summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/framework/java/android/app/job/JobInfo.java2
-rw-r--r--apex/jobscheduler/service/Android.bp1
-rw-r--r--apex/jobscheduler/service/aconfig/Android.bp13
-rw-r--r--apex/jobscheduler/service/aconfig/app_idle.aconfig14
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java8
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java24
-rw-r--r--api/StubLibraries.bp12
-rw-r--r--core/api/current.txt6
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java10
-rw-r--r--core/java/android/app/Activity.java7
-rw-r--r--core/java/android/app/ActivityManagerInternal.java11
-rw-r--r--core/java/android/app/ActivityThread.java6
-rw-r--r--core/java/android/app/AppOpsManager.java3
-rw-r--r--core/java/android/app/Notification.java76
-rw-r--r--core/java/android/app/TEST_MAPPING16
-rw-r--r--core/java/android/app/activity_manager.aconfig11
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java2
-rw-r--r--core/java/android/content/TEST_MAPPING8
-rw-r--r--core/java/android/content/pm/CrossProfileApps.java2
-rw-r--r--core/java/android/content/res/Configuration.java2
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl1
-rw-r--r--core/java/android/hardware/input/InputManager.java13
-rw-r--r--core/java/android/hardware/input/InputManagerGlobal.java12
-rw-r--r--core/java/android/os/VintfObject.java18
-rw-r--r--core/java/android/provider/CallLog.java2
-rw-r--r--core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java109
-rw-r--r--core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java72
-rw-r--r--core/java/android/text/DynamicLayout.java1
-rw-r--r--core/java/android/text/StaticLayout.java1
-rw-r--r--core/java/android/view/Display.java13
-rw-r--r--core/java/android/view/InputDevice.java43
-rw-r--r--core/java/android/view/InsetsController.java6
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java27
-rw-r--r--core/java/android/view/KeyEvent.java65
-rw-r--r--core/java/android/view/MotionEvent.java105
-rw-r--r--core/java/android/view/WindowManager.java12
-rw-r--r--core/java/android/view/WindowMetrics.java10
-rw-r--r--core/java/android/view/accessibility/flags/accessibility_flags.aconfig1
-rw-r--r--core/java/android/window/BackProgressAnimator.java1
-rw-r--r--core/java/android/window/TaskFragmentTransaction.java27
-rw-r--r--core/java/android/window/TaskSnapshot.java5
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig7
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig8
-rw-r--r--core/java/android/window/flags/windowing_sdk.aconfig5
-rw-r--r--core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java14
-rw-r--r--core/java/com/android/internal/widget/CompactMessagingLayout.java263
-rw-r--r--core/jni/Android.bp4
-rw-r--r--core/jni/android_os_VintfObject.cpp90
-rw-r--r--core/jni/android_view_InputDevice.cpp5
-rw-r--r--core/res/res/layout/notification_template_material_messaging_compact_heads_up.xml12
-rw-r--r--core/res/res/values-af/strings.xml27
-rw-r--r--core/res/res/values-am/strings.xml27
-rw-r--r--core/res/res/values-ar/strings.xml31
-rw-r--r--core/res/res/values-as/strings.xml27
-rw-r--r--core/res/res/values-az/strings.xml27
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml35
-rw-r--r--core/res/res/values-be/strings.xml27
-rw-r--r--core/res/res/values-bg/strings.xml29
-rw-r--r--core/res/res/values-bn/strings.xml29
-rw-r--r--core/res/res/values-bs/strings.xml27
-rw-r--r--core/res/res/values-ca/strings.xml33
-rw-r--r--core/res/res/values-cs/strings.xml27
-rw-r--r--core/res/res/values-da/strings.xml27
-rw-r--r--core/res/res/values-de/strings.xml29
-rw-r--r--core/res/res/values-el/strings.xml29
-rw-r--r--core/res/res/values-en-rAU/strings.xml27
-rw-r--r--core/res/res/values-en-rCA/strings.xml7
-rw-r--r--core/res/res/values-en-rGB/strings.xml27
-rw-r--r--core/res/res/values-en-rIN/strings.xml27
-rw-r--r--core/res/res/values-en-rXC/strings.xml7
-rw-r--r--core/res/res/values-es-rUS/strings.xml27
-rw-r--r--core/res/res/values-es/strings.xml29
-rw-r--r--core/res/res/values-et/strings.xml27
-rw-r--r--core/res/res/values-eu/strings.xml27
-rw-r--r--core/res/res/values-fa/strings.xml29
-rw-r--r--core/res/res/values-fi/strings.xml27
-rw-r--r--core/res/res/values-fr-rCA/strings.xml27
-rw-r--r--core/res/res/values-fr/strings.xml27
-rw-r--r--core/res/res/values-gl/strings.xml27
-rw-r--r--core/res/res/values-gu/strings.xml27
-rw-r--r--core/res/res/values-hi/strings.xml31
-rw-r--r--core/res/res/values-hr/strings.xml27
-rw-r--r--core/res/res/values-hu/strings.xml29
-rw-r--r--core/res/res/values-hy/strings.xml29
-rw-r--r--core/res/res/values-in/strings.xml27
-rw-r--r--core/res/res/values-is/strings.xml27
-rw-r--r--core/res/res/values-it/strings.xml27
-rw-r--r--core/res/res/values-iw/strings.xml29
-rw-r--r--core/res/res/values-ja/strings.xml27
-rw-r--r--core/res/res/values-ka/strings.xml29
-rw-r--r--core/res/res/values-kk/strings.xml27
-rw-r--r--core/res/res/values-km/strings.xml27
-rw-r--r--core/res/res/values-kn/strings.xml27
-rw-r--r--core/res/res/values-ko/strings.xml29
-rw-r--r--core/res/res/values-ky/strings.xml27
-rw-r--r--core/res/res/values-lo/strings.xml29
-rw-r--r--core/res/res/values-lt/strings.xml27
-rw-r--r--core/res/res/values-lv/strings.xml27
-rw-r--r--core/res/res/values-mk/strings.xml33
-rw-r--r--core/res/res/values-ml/strings.xml33
-rw-r--r--core/res/res/values-mn/strings.xml29
-rw-r--r--core/res/res/values-mr/strings.xml27
-rw-r--r--core/res/res/values-ms/strings.xml27
-rw-r--r--core/res/res/values-my/strings.xml27
-rw-r--r--core/res/res/values-nb/strings.xml27
-rw-r--r--core/res/res/values-ne/strings.xml55
-rw-r--r--core/res/res/values-nl/strings.xml27
-rw-r--r--core/res/res/values-or/strings.xml29
-rw-r--r--core/res/res/values-pa/strings.xml27
-rw-r--r--core/res/res/values-pl/strings.xml27
-rw-r--r--core/res/res/values-pt-rBR/strings.xml29
-rw-r--r--core/res/res/values-pt-rPT/strings.xml29
-rw-r--r--core/res/res/values-pt/strings.xml29
-rw-r--r--core/res/res/values-ro/strings.xml27
-rw-r--r--core/res/res/values-ru/strings.xml31
-rw-r--r--core/res/res/values-si/strings.xml27
-rw-r--r--core/res/res/values-sk/strings.xml27
-rw-r--r--core/res/res/values-sl/strings.xml29
-rw-r--r--core/res/res/values-sq/strings.xml6
-rw-r--r--core/res/res/values-sr/strings.xml35
-rw-r--r--core/res/res/values-sv/strings.xml45
-rw-r--r--core/res/res/values-sw/strings.xml27
-rw-r--r--core/res/res/values-ta/strings.xml27
-rw-r--r--core/res/res/values-te/strings.xml27
-rw-r--r--core/res/res/values-th/strings.xml27
-rw-r--r--core/res/res/values-tl/strings.xml27
-rw-r--r--core/res/res/values-tr/strings.xml27
-rw-r--r--core/res/res/values-uk/strings.xml27
-rw-r--r--core/res/res/values-ur/strings.xml27
-rw-r--r--core/res/res/values-uz/strings.xml27
-rw-r--r--core/res/res/values-vi/strings.xml27
-rw-r--r--core/res/res/values-zh-rCN/strings.xml27
-rw-r--r--core/res/res/values-zh-rHK/strings.xml31
-rw-r--r--core/res/res/values-zh-rTW/strings.xml27
-rw-r--r--core/res/res/values-zu/strings.xml27
-rw-r--r--core/res/res/values/attrs.xml2
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/config_telephony.xml19
-rw-r--r--core/res/res/values/dimens.xml6
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml7
-rw-r--r--graphics/java/android/graphics/fonts/FontFamily.java2
-rw-r--r--graphics/java/android/graphics/text/LineBreakConfig.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java223
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java79
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java31
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java104
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java24
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java8
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig7
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt34
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt18
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml10
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java38
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java66
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java37
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java93
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt133
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java19
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt72
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java20
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt25
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java58
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java19
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt150
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.kt77
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java22
-rw-r--r--media/java/android/media/IMediaRouter2.aidl3
-rw-r--r--media/java/android/media/IMediaRouterService.aidl3
-rw-r--r--media/java/android/media/LoudnessCodecDispatcher.java15
-rw-r--r--media/java/android/media/MediaRouter2.java34
-rw-r--r--packages/CredentialManager/res/values-fr-rCA/strings.xml8
-rw-r--r--packages/CredentialManager/res/values-hy/strings.xml10
-rw-r--r--packages/CredentialManager/res/values-ka/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-kk/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-ne/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt3
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm4
-rw-r--r--packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_preference_category_no_title.xml23
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt35
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionController.kt62
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt85
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt80
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt167
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt78
-rw-r--r--packages/SettingsLib/aconfig/settingslib.aconfig10
-rw-r--r--packages/SettingsLib/res/values/strings.xml4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java23
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java4
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java39
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java27
-rw-r--r--packages/SystemUI/Android.bp46
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig10
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java8
-rw-r--r--packages/SystemUI/aconfig/accessibility.aconfig16
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig25
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt28
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/FingerprintPropertyRepositoryTest.kt103
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt73
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt39
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt10
-rw-r--r--packages/SystemUI/res/drawable/qs_tile_background_flagged.xml30
-rw-r--r--packages/SystemUI/res/drawable/qs_tile_focused_background.xml18
-rw-r--r--packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml3
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_button_bar.xml11
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml3
-rw-r--r--packages/SystemUI/res/layout/screenshot_shelf.xml61
-rw-r--r--packages/SystemUI/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/res/values/styles.xml6
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java (renamed from packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/data/repository/NightDisplayRepository.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCompactMessagingTemplateViewWrapper.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java247
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt119
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ServiceStateModel.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt67
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepository.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractor.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java)14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt53
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileStateTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt145
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/TextPrecomputerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt68
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt136
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java18
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt10
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/VolumePanelAncKosmos.kt5
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/data/repository/FakeAncSliceRepository.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt58
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt4
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt1
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt9
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt2
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt2
-rw-r--r--packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt22
-rw-r--r--services/accessibility/accessibility.aconfig10
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java307
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java39
-rw-r--r--services/core/java/com/android/server/BootReceiver.java28
-rw-r--r--services/core/java/com/android/server/PinnerService.java12
-rw-r--r--services/core/java/com/android/server/TEST_MAPPING21
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java73
-rw-r--r--services/core/java/com/android/server/am/OomAdjusterModernImpl.java211
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java11
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig11
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java18
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java9
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java19
-rw-r--r--services/core/java/com/android/server/flags/pinner.aconfig7
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java6
-rw-r--r--services/core/java/com/android/server/input/NativeInputManagerService.java5
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodBindingController.java22
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java259
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodMap.java2
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java100
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java3
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java1
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java46
-rw-r--r--services/core/java/com/android/server/media/MediaRouterService.java13
-rw-r--r--services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java98
-rw-r--r--services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java21
-rw-r--r--services/core/java/com/android/server/pm/PackageFreezer.java10
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java2
-rw-r--r--services/core/java/com/android/server/power/Notifier.java62
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java6
-rw-r--r--services/core/java/com/android/server/power/WakeLockLog.java16
-rw-r--r--services/core/java/com/android/server/power/feature/PowerManagerFlags.java13
-rw-r--r--services/core/java/com/android/server/power/feature/power_flags.aconfig8
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java50
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java31
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java7
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java11
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java71
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java21
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java2
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp7
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodMapTest.java24
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java58
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java21
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java28
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java11
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/OWNERS2
-rw-r--r--services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java45
-rw-r--r--services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java3
-rw-r--r--services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java122
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java99
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java18
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java12
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl9
-rw-r--r--tests/BinderLeakTest/Android.bp3
-rw-r--r--tests/Input/src/com/android/test/input/InputDeviceTest.java5
562 files changed, 7113 insertions, 4258 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index c74c48ce6ba8..5f57c3973ab0 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -31,6 +31,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.app.Notification;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
@@ -1366,6 +1367,7 @@ public class JobInfo implements Parcelable {
* @return This object for method chaining
*/
@FlaggedApi(Flags.FLAG_JOB_DEBUG_INFO_APIS)
+ @SuppressLint("BuilderSetStyle")
@NonNull
public Builder removeDebugTag(@NonNull String tag) {
mDebugTags.remove(tag);
diff --git a/apex/jobscheduler/service/Android.bp b/apex/jobscheduler/service/Android.bp
index 06c7d64d1708..559490cec04f 100644
--- a/apex/jobscheduler/service/Android.bp
+++ b/apex/jobscheduler/service/Android.bp
@@ -33,6 +33,7 @@ java_library {
"modules-utils-fastxmlserializer",
"service-jobscheduler-alarm.flags-aconfig-java",
"service-jobscheduler-job.flags-aconfig-java",
+ "service-jobscheduler-appidle.flags-aconfig-java",
],
// Rename classes shared with the framework
diff --git a/apex/jobscheduler/service/aconfig/Android.bp b/apex/jobscheduler/service/aconfig/Android.bp
index 859c67ad8910..7b2525c67916 100644
--- a/apex/jobscheduler/service/aconfig/Android.bp
+++ b/apex/jobscheduler/service/aconfig/Android.bp
@@ -42,3 +42,16 @@ java_aconfig_library {
name: "service-jobscheduler-alarm.flags-aconfig-java",
aconfig_declarations: "alarm_flags",
}
+
+// App Idle
+aconfig_declarations {
+ name: "app_idle_flags",
+ package: "com.android.server.usage",
+ container: "system",
+ srcs: ["app_idle.aconfig"],
+}
+
+java_aconfig_library {
+ name: "service-jobscheduler-appidle.flags-aconfig-java",
+ aconfig_declarations: "app_idle_flags",
+}
diff --git a/apex/jobscheduler/service/aconfig/app_idle.aconfig b/apex/jobscheduler/service/aconfig/app_idle.aconfig
new file mode 100644
index 000000000000..c8976ca8361e
--- /dev/null
+++ b/apex/jobscheduler/service/aconfig/app_idle.aconfig
@@ -0,0 +1,14 @@
+package: "com.android.server.usage"
+container: "system"
+
+flag {
+ name: "avoid_idle_check"
+ namespace: "backstage_power"
+ description: "Postpone app idle check after boot completed"
+ is_fixed_read_only: true
+ bug: "337864590"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index 4d4e3407a3c3..6265d9bb815f 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -788,7 +788,13 @@ public class AppIdleHistory {
}
appUsageHistory.nextEstimatedLaunchTime = getLongValue(parser,
ATTR_NEXT_ESTIMATED_APP_LAUNCH_TIME, 0);
- appUsageHistory.lastInformedBucket = -1;
+ if (Flags.avoidIdleCheck()) {
+ // Set lastInformedBucket to the same value with the currentBucket
+ // it should have already been informed.
+ appUsageHistory.lastInformedBucket = appUsageHistory.currentBucket;
+ } else {
+ appUsageHistory.lastInformedBucket = -1;
+ }
userHistory.put(packageName, appUsageHistory);
if (version >= XML_VERSION_ADD_BUCKET_EXPIRY_TIMES) {
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 410074e6ec85..c3fe0314636e 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -707,7 +707,7 @@ public class AppStandbyController
initializeDefaultsForSystemApps(UserHandle.USER_SYSTEM);
}
- if (mPendingOneTimeCheckIdleStates) {
+ if (!Flags.avoidIdleCheck() && mPendingOneTimeCheckIdleStates) {
postOneTimeCheckIdleStates();
}
@@ -1021,7 +1021,7 @@ public class AppStandbyController
== REASON_SUB_DEFAULT_APP_RESTORED)) {
newBucket = getBucketForLocked(packageName, userId, elapsedRealtime);
if (DEBUG) {
- Slog.d(TAG, "Evaluated AOSP newBucket = "
+ Slog.d(TAG, "Evaluated " + packageName + " newBucket = "
+ standbyBucketToString(newBucket));
}
reason = REASON_MAIN_TIMEOUT;
@@ -1990,7 +1990,9 @@ public class AppStandbyController
}
}
if (android.app.admin.flags.Flags.disallowUserControlBgUsageFix()) {
- postCheckIdleStates(userId);
+ if (!Flags.avoidIdleCheck()) {
+ postCheckIdleStates(userId);
+ }
}
}
@@ -2392,9 +2394,14 @@ public class AppStandbyController
final boolean isHeadLess = !systemLauncherActivities.contains(pkg);
if (updateHeadlessSystemAppCache(pkg, isHeadLess)) {
- mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE,
- UserHandle.USER_SYSTEM, -1, pkg)
- .sendToTarget();
+ if (!Flags.avoidIdleCheck()) {
+ // Checking idle state for the each individual headless system app
+ // during the boot up is not necessary, a full idle check for all
+ // usres will be scheduled after boot completed.
+ mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE,
+ UserHandle.USER_SYSTEM, -1, pkg)
+ .sendToTarget();
+ }
}
}
final long end = SystemClock.uptimeMillis();
@@ -2438,6 +2445,11 @@ public class AppStandbyController
@Override
public void dumpState(String[] args, PrintWriter pw) {
+ pw.println("Flags: ");
+ pw.println(" " + Flags.FLAG_AVOID_IDLE_CHECK
+ + ": " + Flags.avoidIdleCheck());
+ pw.println();
+
synchronized (mCarrierPrivilegedLock) {
pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps
+ "): " + mCarrierPrivilegedApps);
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index 13d6ae5be3e8..6cfd2e0ce833 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -44,8 +44,8 @@ non_updatable_exportable_droidstubs {
removed_api_file: ":non-updatable-removed.txt",
},
last_released: {
- api_file: ":android-non-updatable.api.public.latest",
- removed_api_file: ":android-non-updatable-removed.api.public.latest",
+ api_file: ":android-non-updatable.api.combined.public.latest",
+ removed_api_file: ":android-non-updatable-removed.api.combined.public.latest",
baseline_file: ":android-non-updatable-incompatibilities.api.public.latest",
},
api_lint: {
@@ -124,8 +124,8 @@ non_updatable_exportable_droidstubs {
removed_api_file: ":non-updatable-system-removed.txt",
},
last_released: {
- api_file: ":android-non-updatable.api.system.latest",
- removed_api_file: ":android-non-updatable-removed.api.system.latest",
+ api_file: ":android-non-updatable.api.combined.system.latest",
+ removed_api_file: ":android-non-updatable-removed.api.combined.system.latest",
baseline_file: ":android-non-updatable-incompatibilities.api.system.latest",
},
api_lint: {
@@ -263,8 +263,8 @@ non_updatable_exportable_droidstubs {
removed_api_file: ":non-updatable-module-lib-removed.txt",
},
last_released: {
- api_file: ":android-non-updatable.api.module-lib.latest",
- removed_api_file: ":android-non-updatable-removed.api.module-lib.latest",
+ api_file: ":android-non-updatable.api.combined.module-lib.latest",
+ removed_api_file: ":android-non-updatable-removed.api.combined.module-lib.latest",
baseline_file: ":android-non-updatable-incompatibilities.api.module-lib.latest",
},
api_lint: {
diff --git a/core/api/current.txt b/core/api/current.txt
index 13958d24096b..16de8fe7066c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -3344,9 +3344,9 @@ package android.accessibilityservice {
public abstract class AccessibilityService extends android.app.Service {
ctor public AccessibilityService();
method public void attachAccessibilityOverlayToDisplay(int, @NonNull android.view.SurfaceControl);
- method @FlaggedApi("android.view.accessibility.a11y_overlay_callbacks") public void attachAccessibilityOverlayToDisplay(int, @NonNull android.view.SurfaceControl, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
+ method @FlaggedApi("android.view.accessibility.a11y_overlay_callbacks") public final void attachAccessibilityOverlayToDisplay(int, @NonNull android.view.SurfaceControl, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
method public void attachAccessibilityOverlayToWindow(int, @NonNull android.view.SurfaceControl);
- method @FlaggedApi("android.view.accessibility.a11y_overlay_callbacks") public void attachAccessibilityOverlayToWindow(int, @NonNull android.view.SurfaceControl, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
+ method @FlaggedApi("android.view.accessibility.a11y_overlay_callbacks") public final void attachAccessibilityOverlayToWindow(int, @NonNull android.view.SurfaceControl, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
method public boolean clearCache();
method public boolean clearCachedSubtree(@NonNull android.view.accessibility.AccessibilityNodeInfo);
method public final void disableSelf();
@@ -3354,7 +3354,7 @@ package android.accessibilityservice {
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
method @NonNull public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
method @NonNull public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController(int);
- method @FlaggedApi("android.view.accessibility.braille_display_hid") @NonNull public android.accessibilityservice.BrailleDisplayController getBrailleDisplayController();
+ method @FlaggedApi("android.view.accessibility.braille_display_hid") @NonNull public final android.accessibilityservice.BrailleDisplayController getBrailleDisplayController();
method @NonNull @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method @Nullable public final android.accessibilityservice.InputMethod getInputMethod();
method @NonNull public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index d70fa19a4468..fd9600c1f87f 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -3554,8 +3554,8 @@ public abstract class AccessibilityService extends Service {
* @see #OVERLAY_RESULT_INVALID
* @see #OVERLAY_RESULT_INTERNAL_ERROR
*/
- @FlaggedApi("android.view.accessibility.a11y_overlay_callbacks")
- public void attachAccessibilityOverlayToDisplay(
+ @FlaggedApi(android.view.accessibility.Flags.FLAG_A11Y_OVERLAY_CALLBACKS)
+ public final void attachAccessibilityOverlayToDisplay(
int displayId,
@NonNull SurfaceControl sc,
@NonNull @CallbackExecutor Executor executor,
@@ -3627,8 +3627,8 @@ public abstract class AccessibilityService extends Service {
* @see #OVERLAY_RESULT_INVALID
* @see #OVERLAY_RESULT_INTERNAL_ERROR
*/
- @FlaggedApi("android.view.accessibility.a11y_overlay_callbacks")
- public void attachAccessibilityOverlayToWindow(
+ @FlaggedApi(android.view.accessibility.Flags.FLAG_A11Y_OVERLAY_CALLBACKS)
+ public final void attachAccessibilityOverlayToWindow(
int accessibilityWindowId,
@NonNull SurfaceControl sc,
@NonNull @CallbackExecutor Executor executor,
@@ -3645,7 +3645,7 @@ public abstract class AccessibilityService extends Service {
*/
@FlaggedApi(android.view.accessibility.Flags.FLAG_BRAILLE_DISPLAY_HID)
@NonNull
- public BrailleDisplayController getBrailleDisplayController() {
+ public final BrailleDisplayController getBrailleDisplayController() {
BrailleDisplayController.checkApiFlagIsEnabled();
synchronized (mLock) {
if (mBrailleDisplayController == null) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e1cb630f4d82..79e2bd437c3e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1183,6 +1183,7 @@ public class Activity extends ContextThemeWrapper
* @see #setIntent(Intent, ComponentCaller)
*/
@FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
+ @SuppressLint("OnNameExpected")
public @Nullable ComponentCaller getCaller() {
return mCaller;
}
@@ -1203,6 +1204,7 @@ public class Activity extends ContextThemeWrapper
* @see #getCaller
*/
@FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
+ @SuppressLint("OnNameExpected")
public void setIntent(@Nullable Intent newIntent, @Nullable ComponentCaller newCaller) {
internalSetIntent(newIntent, newCaller);
}
@@ -7161,6 +7163,7 @@ public class Activity extends ContextThemeWrapper
* @see ComponentCaller
*/
@FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
+ @SuppressLint("OnNameExpected")
public @NonNull ComponentCaller getInitialCaller() {
return mInitialCaller;
}
@@ -7188,10 +7191,11 @@ public class Activity extends ContextThemeWrapper
* @see #getCaller
*/
@FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
+ @SuppressLint("OnNameExpected")
public @NonNull ComponentCaller getCurrentCaller() {
if (mCurrentCaller == null) {
throw new IllegalStateException("The caller is null because #getCurrentCaller should be"
- + " called within #onNewIntent method");
+ + " called within #onNewIntent or #onActivityResult methods");
}
return mCurrentCaller;
}
@@ -9634,6 +9638,7 @@ public class Activity extends ContextThemeWrapper
* the default behaviour
*/
@FlaggedApi(android.security.Flags.FLAG_ASM_RESTRICTIONS_ENABLED)
+ @SuppressLint("OnNameExpected")
public void setAllowCrossUidActivitySwitchFromBelow(boolean allowed) {
ActivityClient.getInstance().setAllowCrossUidActivitySwitchFromBelow(mToken, allowed);
}
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index d8df447982a0..8e99e46be6ac 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1282,4 +1282,15 @@ public abstract class ActivityManagerInternal {
*/
public abstract void addStartInfoTimestamp(int key, long timestampNs, int uid, int pid,
int userId);
+
+ /**
+ * It is similar {@link IActivityManager#killApplication(String, int, int, String, int)} but
+ * it immediately stop the package.
+ *
+ * <p>Note: Do not call this method from inside PMS's lock, otherwise it'll run into
+ * watchdog reset.
+ * @hide
+ */
+ public abstract void killApplicationSync(String pkgName, int appId, int userId,
+ String reason, int exitInfoReason);
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d4812dd612c3..76c1ed619510 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -18,6 +18,7 @@ package android.app;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
import static android.app.ConfigurationController.createNewConfigAndUpdateIfNotNull;
+import static android.app.Flags.skipBgMemTrimOnFgApp;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
@@ -7078,6 +7079,11 @@ public final class ActivityThread extends ClientTransactionHandler
if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
try {
+ if (skipBgMemTrimOnFgApp()
+ && mLastProcessState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+ && level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
+ return;
+ }
if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
PropertyInvalidatedCache.onTrimMemory();
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 54f69099e081..6865f9c5013b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -3583,6 +3583,9 @@ public class AppOpsManager {
return mAttributionTag;
}
+ /**
+ * Persistent device Id of the proxy that noted the op
+ */
@FlaggedApi(Flags.FLAG_DEVICE_ID_IN_OP_PROXY_INFO_ENABLED)
public @Nullable String getDeviceId() { return mDeviceId; }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0672064bd5ea..d8f03b165a00 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8892,6 +8892,62 @@ public class Notification implements Parcelable
}
}
+ private void fixTitleAndTextForCompactMessaging(StandardTemplateParams p) {
+ Message m = findLatestIncomingMessage();
+ final CharSequence text = (m == null) ? null : m.mText;
+ CharSequence sender = m == null ? null
+ : m.mSender == null || TextUtils.isEmpty(m.mSender.getName())
+ ? mUser.getName() : m.mSender.getName();
+
+ CharSequence conversationTitle = mIsGroupConversation ? mConversationTitle : null;
+
+ // we want to have colon for possible title for conversation.
+ final BidiFormatter bidi = BidiFormatter.getInstance();
+ if (sender != null) {
+ sender = mBuilder.mContext.getString(
+ com.android.internal.R.string.notification_messaging_title_template,
+ bidi.unicodeWrap(sender), "");
+ } else if (conversationTitle != null) {
+ conversationTitle = mBuilder.mContext.getString(
+ com.android.internal.R.string.notification_messaging_title_template,
+ bidi.unicodeWrap(conversationTitle), "");
+ }
+
+ if (Flags.cleanUpSpansAndNewLines()) {
+ conversationTitle = stripStyling(conversationTitle);
+ sender = stripStyling(sender);
+ }
+
+ final boolean showOnlySenderName = showOnlySenderName();
+
+ final CharSequence title;
+ boolean isConversationTitleAvailable = !showOnlySenderName && conversationTitle != null;
+ if (isConversationTitleAvailable) {
+ title = conversationTitle;
+ } else {
+ title = sender;
+ }
+
+ p.title(title);
+ // when the conversation title is available, use headerTextSecondary for sender and
+ // summaryText for text
+ if (isConversationTitleAvailable) {
+ p.headerTextSecondary(sender);
+ p.summaryText(text);
+ } else {
+ // when it is not, use headerTextSecondary for text and don't use summaryText
+ p.headerTextSecondary(text);
+ p.summaryText(null);
+ }
+ }
+
+ /** developer settings to always show sender name */
+ private boolean showOnlySenderName() {
+ return SystemProperties.getBoolean(
+ "persist.compact_heads_up_notification.show_only_sender_name",
+ false);
+ }
+
/**
* @hide
*/
@@ -9211,24 +9267,34 @@ public class Notification implements Parcelable
}
}
- // This method fills title and text
- fixTitleAndTextExtras(mBuilder.mN.extras);
final StandardTemplateParams p = mBuilder.mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP)
.highlightExpander(isConversationLayout)
.fillTextsFrom(mBuilder)
- .hideTime(true)
- .summaryText("");
- p.headerTextSecondary(p.mText);
+ .hideTime(true);
+
+ fixTitleAndTextForCompactMessaging(p);
TemplateBindResult bindResult = new TemplateBindResult();
RemoteViews contentView = mBuilder.applyStandardTemplate(
mBuilder.getMessagingCompactHeadsUpLayoutResource(), p, bindResult);
+ contentView.setViewVisibility(R.id.header_text_secondary_divider, View.GONE);
+ contentView.setViewVisibility(R.id.header_text_divider, View.GONE);
if (conversationIcon != null) {
contentView.setViewVisibility(R.id.icon, View.GONE);
+ contentView.setViewVisibility(R.id.conversation_face_pile, View.GONE);
contentView.setViewVisibility(R.id.conversation_icon, View.VISIBLE);
contentView.setBoolean(R.id.conversation_icon, "setApplyCircularCrop", true);
contentView.setImageViewIcon(R.id.conversation_icon, conversationIcon);
+ } else if (mIsGroupConversation) {
+ contentView.setViewVisibility(R.id.icon, View.GONE);
+ contentView.setViewVisibility(R.id.conversation_icon, View.GONE);
+ contentView.setInt(R.id.status_bar_latest_event_content,
+ "setNotificationBackgroundColor", mBuilder.getBackgroundColor(p));
+ contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
+ mBuilder.getSmallIconColor(p));
+ contentView.setBundle(R.id.status_bar_latest_event_content, "setGroupFacePile",
+ mBuilder.mN.extras);
}
if (remoteInputAction != null) {
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index dc44764dc046..0deb842aff61 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -378,6 +378,14 @@
}
],
"file_patterns": ["(/|^)ContextImpl.java"]
+ },
+ {
+ "file_patterns": [
+ "(/|^)Activity.*.java",
+ "(/|^)PendingIntent.java",
+ "(/|^)ComtextImpl.java"
+ ],
+ "name": "CtsWindowManagerBackgroundActivityTestCases"
}
],
"postsubmit": [
@@ -392,14 +400,6 @@
{
"file_patterns": ["(/|^)AppOpsManager.java"],
"name": "CtsAppOpsTestCases"
- },
- {
- "file_patterns": [
- "(/|^)Activity.*.java",
- "(/|^)PendingIntent.java",
- "(/|^)ComtextImpl.java"
- ],
- "name": "CtsWindowManagerBackgroundActivityTestCases"
}
]
}
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index bb24fd19315e..fa646a76768c 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -70,3 +70,14 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "backstage_power"
+ name: "skip_bg_mem_trim_on_fg_app"
+ description: "Skip background memory trim event on foreground processes."
+ is_fixed_read_only: true
+ bug: "308927629"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4bc1ce6d64ff..c529f7d95190 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1698,7 +1698,7 @@ public class DevicePolicyManager {
/**
* A boolean extra indicating whether device encryption can be skipped as part of
- * <a href="#managed-provisioning>provisioning</a>.
+ * <a href="#managed-provisioning">provisioning</a>.
*
* <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} or an intent with action
* {@link #ACTION_PROVISION_MANAGED_DEVICE} that starts device owner provisioning.
diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING
index f08395ae5e40..41a4288eae5c 100644
--- a/core/java/android/content/TEST_MAPPING
+++ b/core/java/android/content/TEST_MAPPING
@@ -56,6 +56,10 @@
}
],
"file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"]
+ },
+ {
+ "name": "CtsWindowManagerBackgroundActivityTestCases",
+ "file_patterns": ["(/|^)IntentSender.java"]
}
],
"ravenwood-presubmit": [
@@ -65,9 +69,5 @@
}
],
"postsubmit": [
- {
- "name": "CtsWindowManagerBackgroundActivityTestCases",
- "file_patterns": ["(/|^)IntentSender.java"]
- }
]
}
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 8220313a9197..57ee622de910 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -326,6 +326,7 @@ public class CrossProfileApps {
* @return whether the specified user is a profile.
*/
@FlaggedApi(FLAG_ALLOW_QUERYING_PROFILE_TYPE)
+ @SuppressWarnings("UserHandleName")
public boolean isProfile(@NonNull UserHandle userHandle) {
// Note that this is not a security check, but rather a check for correct use.
// The actual security check is performed by UserManager.
@@ -343,6 +344,7 @@ public class CrossProfileApps {
* @return whether the specified user is a managed profile.
*/
@FlaggedApi(FLAG_ALLOW_QUERYING_PROFILE_TYPE)
+ @SuppressWarnings("UserHandleName")
public boolean isManagedProfile(@NonNull UserHandle userHandle) {
// Note that this is not a security check, but rather a check for correct use.
// The actual security check is performed by UserManager.
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 885f4c5e8ec4..982224b026bc 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -806,7 +806,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*
* <aside class="note"><b>Note:</b> If the app targets
* {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}
- * or after, The width measurement reflects the window size without excluding insets.
+ * or after, the width measurement reflects the window size without excluding insets.
* Otherwise, the measurement excludes window insets even when the app is displayed edge to edge
* using {@link android.view.Window#setDecorFitsSystemWindows(boolean)
* Window#setDecorFitsSystemWindows(boolean)}.</aside>
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 45b316aa5498..40d4fb6df4bc 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -55,7 +55,6 @@ interface IInputManager {
int[] getInputDeviceIds();
// Enable/disable input device.
- boolean isInputDeviceEnabled(int deviceId);
void enableInputDevice(int deviceId);
void disableInputDevice(int deviceId);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 7527aa7197e9..9eabc8d53bb3 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -333,19 +333,6 @@ public final class InputManager {
}
/**
- * Returns true if an input device is enabled. Should return true for most
- * situations. Some system apps may disable an input device, for
- * example to prevent unwanted touch events.
- *
- * @param id The input device Id.
- *
- * @hide
- */
- public boolean isInputDeviceEnabled(int id) {
- return mGlobal.isInputDeviceEnabled(id);
- }
-
- /**
* Enables an InputDevice.
* <p>
* Requires {@link android.Manifest.permission#DISABLE_INPUT_DEVICE}.
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index fcd5a3ed06c0..7b471806cfc1 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -411,18 +411,6 @@ public final class InputManagerGlobal {
}
/**
- * @see InputManager#isInputDeviceEnabled(int)
- */
- public boolean isInputDeviceEnabled(int id) {
- try {
- return mIm.isInputDeviceEnabled(id);
- } catch (RemoteException ex) {
- Log.w(TAG, "Could not check enabled status of input device with id = " + id);
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /**
* @see InputManager#enableInputDevice(int)
*/
public void enableInputDevice(int id) {
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 505655775239..bb89e0791053 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -17,8 +17,11 @@
package android.os;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.app.ActivityThread;
+import java.io.IOException;
import java.util.Map;
/**
@@ -113,5 +116,20 @@ public class VintfObject {
@TestApi
public static native Long getTargetFrameworkCompatibilityMatrixVersion();
+ /**
+ * Executes a shell command using shell user identity, and return the standard output in string.
+ *
+ * @hide
+ */
+ private static @Nullable String runShellCommand(@NonNull String command) throws IOException {
+ var activityThread = ActivityThread.currentActivityThread();
+ var instrumentation = activityThread.getInstrumentation();
+ var automation = instrumentation.getUiAutomation();
+ var pfd = automation.executeShellCommand(command);
+ try (var is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
+ return new String(is.readAllBytes());
+ }
+ }
+
private VintfObject() {}
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 120846ca593b..708c1966be8b 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -2017,7 +2017,7 @@ public class CallLog {
return false;
}
final UserInfo userInfo = userManager.getUserInfo(userId);
- return userInfo != null && !userInfo.isManagedProfile();
+ return userInfo != null && !userInfo.isProfile();
}
/**
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
index 793e58ac5d3b..293015f86cee 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
@@ -18,6 +18,9 @@ package android.service.ondeviceintelligence;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallSuper;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
@@ -40,13 +43,16 @@ import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.Handler;
import android.os.IBinder;
import android.os.ICancellationSignal;
+import android.os.Looper;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.RemoteException;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.infra.AndroidFuture;
@@ -88,6 +94,14 @@ public abstract class OnDeviceIntelligenceService extends Service {
private static final String TAG = OnDeviceIntelligenceService.class.getSimpleName();
private volatile IRemoteProcessingService mRemoteProcessingService;
+ private Handler mHandler;
+
+ @CallSuper
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mHandler = new Handler(Looper.getMainLooper(), null /* callback */, true /* async */);
+ }
/**
* The {@link Intent} that must be declared as handled by the service. To be supported, the
@@ -107,38 +121,49 @@ public abstract class OnDeviceIntelligenceService extends Service {
@Override
public final IBinder onBind(@NonNull Intent intent) {
if (SERVICE_INTERFACE.equals(intent.getAction())) {
- // TODO(326052028) : Move the remote method calls to an app handler from the binder
- // thread.
return new IOnDeviceIntelligenceService.Stub() {
/** {@inheritDoc} */
@Override
public void ready() {
- OnDeviceIntelligenceService.this.onReady();
+ mHandler.executeOrSendMessage(
+ obtainMessage(OnDeviceIntelligenceService::onReady,
+ OnDeviceIntelligenceService.this));
}
@Override
public void getVersion(RemoteCallback remoteCallback) {
Objects.requireNonNull(remoteCallback);
- OnDeviceIntelligenceService.this.onGetVersion(l -> {
- Bundle b = new Bundle();
- b.putLong(OnDeviceIntelligenceManager.API_VERSION_BUNDLE_KEY, l);
- remoteCallback.sendResult(b);
- });
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onGetVersion,
+ OnDeviceIntelligenceService.this, l -> {
+ Bundle b = new Bundle();
+ b.putLong(
+ OnDeviceIntelligenceManager.API_VERSION_BUNDLE_KEY,
+ l);
+ remoteCallback.sendResult(b);
+ }));
}
@Override
public void listFeatures(int callerUid,
IListFeaturesCallback listFeaturesCallback) {
Objects.requireNonNull(listFeaturesCallback);
- OnDeviceIntelligenceService.this.onListFeatures(callerUid,
- wrapListFeaturesCallback(listFeaturesCallback));
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onListFeatures,
+ OnDeviceIntelligenceService.this, callerUid,
+ wrapListFeaturesCallback(listFeaturesCallback)));
}
@Override
public void getFeature(int callerUid, int id, IFeatureCallback featureCallback) {
Objects.requireNonNull(featureCallback);
- OnDeviceIntelligenceService.this.onGetFeature(callerUid,
- id, wrapFeatureCallback(featureCallback));
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onGetFeature,
+ OnDeviceIntelligenceService.this, callerUid,
+ id, wrapFeatureCallback(featureCallback)));
}
@@ -147,9 +172,11 @@ public abstract class OnDeviceIntelligenceService extends Service {
IFeatureDetailsCallback featureDetailsCallback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(featureDetailsCallback);
-
- OnDeviceIntelligenceService.this.onGetFeatureDetails(callerUid,
- feature, wrapFeatureDetailsCallback(featureDetailsCallback));
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onGetFeatureDetails,
+ OnDeviceIntelligenceService.this, callerUid,
+ feature, wrapFeatureDetailsCallback(featureDetailsCallback)));
}
@Override
@@ -163,10 +190,13 @@ public abstract class OnDeviceIntelligenceService extends Service {
transport = CancellationSignal.createTransport();
cancellationSignalFuture.complete(transport);
}
- OnDeviceIntelligenceService.this.onDownloadFeature(callerUid,
- feature,
- CancellationSignal.fromTransport(transport),
- wrapDownloadCallback(downloadCallback));
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onDownloadFeature,
+ OnDeviceIntelligenceService.this, callerUid,
+ feature,
+ CancellationSignal.fromTransport(transport),
+ wrapDownloadCallback(downloadCallback)));
}
@Override
@@ -174,9 +204,11 @@ public abstract class OnDeviceIntelligenceService extends Service {
AndroidFuture<ParcelFileDescriptor> future) {
Objects.requireNonNull(fileName);
Objects.requireNonNull(future);
-
- OnDeviceIntelligenceService.this.onGetReadOnlyFileDescriptor(fileName,
- future);
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onGetReadOnlyFileDescriptor,
+ OnDeviceIntelligenceService.this, fileName,
+ future));
}
@Override
@@ -184,13 +216,15 @@ public abstract class OnDeviceIntelligenceService extends Service {
Feature feature, RemoteCallback remoteCallback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(remoteCallback);
-
- OnDeviceIntelligenceService.this.onGetReadOnlyFeatureFileDescriptorMap(
- feature, parcelFileDescriptorMap -> {
- Bundle bundle = new Bundle();
- parcelFileDescriptorMap.forEach(bundle::putParcelable);
- remoteCallback.sendResult(bundle);
- });
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onGetReadOnlyFeatureFileDescriptorMap,
+ OnDeviceIntelligenceService.this, feature,
+ parcelFileDescriptorMap -> {
+ Bundle bundle = new Bundle();
+ parcelFileDescriptorMap.forEach(bundle::putParcelable);
+ remoteCallback.sendResult(bundle);
+ }));
}
@Override
@@ -201,12 +235,18 @@ public abstract class OnDeviceIntelligenceService extends Service {
@Override
public void notifyInferenceServiceConnected() {
- OnDeviceIntelligenceService.this.onInferenceServiceConnected();
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onInferenceServiceConnected,
+ OnDeviceIntelligenceService.this));
}
@Override
public void notifyInferenceServiceDisconnected() {
- OnDeviceIntelligenceService.this.onInferenceServiceDisconnected();
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceIntelligenceService::onInferenceServiceDisconnected,
+ OnDeviceIntelligenceService.this));
}
};
}
@@ -222,7 +262,8 @@ public abstract class OnDeviceIntelligenceService extends Service {
* @hide
*/
@TestApi
- public void onReady() {}
+ public void onReady() {
+ }
/**
@@ -410,12 +451,16 @@ public abstract class OnDeviceIntelligenceService extends Service {
Slog.v(TAG,
"onGetReadOnlyFileDescriptor: " + fileName + " under internal app storage.");
File f = new File(getBaseContext().getFilesDir(), fileName);
+ if (!f.exists()) {
+ f = new File(fileName);
+ }
ParcelFileDescriptor pfd = null;
try {
pfd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
Slog.d(TAG, "Successfully opened a file with ParcelFileDescriptor.");
} catch (FileNotFoundException e) {
Slog.e(TAG, "Cannot open file. No ParcelFileDescriptor returned.");
+ future.completeExceptionally(e);
} finally {
future.complete(pfd);
if (pfd != null) {
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
index 8237b20260ea..d00485cb1ca5 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
@@ -19,7 +19,10 @@ package android.service.ondeviceintelligence;
import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.AUGMENT_REQUEST_CONTENT_BUNDLE_KEY;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
import android.annotation.CallbackExecutor;
+import android.annotation.CallSuper;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -48,6 +51,7 @@ import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.ICancellationSignal;
+import android.os.Looper;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
@@ -120,7 +124,20 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
*/
public static final String MODEL_UNLOADED_BUNDLE_KEY = "model_unloaded";
+ /**
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_UPDATE_BUNDLE_KEY = "device_config_update";
+
private IRemoteStorageService mRemoteStorageService;
+ private Handler mHandler;
+
+ @CallSuper
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mHandler = new Handler(Looper.getMainLooper(), null /* callback */, true /* async */);
+ }
/**
* @hide
@@ -147,11 +164,15 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
transport = CancellationSignal.createTransport();
cancellationSignalFuture.complete(transport);
}
- OnDeviceSandboxedInferenceService.this.onTokenInfoRequest(callerUid,
- feature,
- request,
- CancellationSignal.fromTransport(transport),
- wrapTokenInfoCallback(tokenInfoCallback));
+
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceSandboxedInferenceService::onTokenInfoRequest,
+ OnDeviceSandboxedInferenceService.this,
+ callerUid, feature,
+ request,
+ CancellationSignal.fromTransport(transport),
+ wrapTokenInfoCallback(tokenInfoCallback)));
}
@Override
@@ -173,13 +194,18 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
processingSignalTransport = ProcessingSignal.createTransport();
processingSignalFuture.complete(processingSignalTransport);
}
- OnDeviceSandboxedInferenceService.this.onProcessRequestStreaming(callerUid,
- feature,
- request,
- requestType,
- CancellationSignal.fromTransport(transport),
- ProcessingSignal.fromTransport(processingSignalTransport),
- wrapStreamingResponseCallback(callback));
+
+
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceSandboxedInferenceService::onProcessRequestStreaming,
+ OnDeviceSandboxedInferenceService.this, callerUid,
+ feature,
+ request,
+ requestType,
+ CancellationSignal.fromTransport(transport),
+ ProcessingSignal.fromTransport(processingSignalTransport),
+ wrapStreamingResponseCallback(callback)));
}
@Override
@@ -200,11 +226,14 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
processingSignalTransport = ProcessingSignal.createTransport();
processingSignalFuture.complete(processingSignalTransport);
}
- OnDeviceSandboxedInferenceService.this.onProcessRequest(callerUid, feature,
- request, requestType,
- CancellationSignal.fromTransport(transport),
- ProcessingSignal.fromTransport(processingSignalTransport),
- wrapResponseCallback(callback));
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceSandboxedInferenceService::onProcessRequest,
+ OnDeviceSandboxedInferenceService.this, callerUid, feature,
+ request, requestType,
+ CancellationSignal.fromTransport(transport),
+ ProcessingSignal.fromTransport(processingSignalTransport),
+ wrapResponseCallback(callback)));
}
@Override
@@ -212,10 +241,11 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
IProcessingUpdateStatusCallback callback) {
Objects.requireNonNull(processingState);
Objects.requireNonNull(callback);
-
- OnDeviceSandboxedInferenceService.this.onUpdateProcessingState(processingState,
- wrapOutcomeReceiver(callback)
- );
+ mHandler.executeOrSendMessage(
+ obtainMessage(
+ OnDeviceSandboxedInferenceService::onUpdateProcessingState,
+ OnDeviceSandboxedInferenceService.this, processingState,
+ wrapOutcomeReceiver(callback)));
}
};
}
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index cce4f7bf7b1f..a78a417300ab 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -310,6 +310,7 @@ public class DynamicLayout extends Layout {
* @see Layout#getUseBoundsForWidth()
* @see Layout.Builder#setUseBoundsForWidth(boolean)
*/
+ @SuppressLint("MissingGetterMatchingBuilder") // The base class `Layout` has a getter.
@NonNull
@FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH)
public Builder setUseBoundsForWidth(boolean useBoundsForWidth) {
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 3dd3a9ea8baf..95460a3575eb 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -447,6 +447,7 @@ public class StaticLayout extends Layout {
* @see Layout#getUseBoundsForWidth()
* @see Layout.Builder#setUseBoundsForWidth(boolean)
*/
+ @SuppressLint("MissingGetterMatchingBuilder") // The base class `Layout` has a getter.
@NonNull
@FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH)
public Builder setUseBoundsForWidth(boolean useBoundsForWidth) {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 4475418e1e57..6464239eb2fc 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -916,6 +916,12 @@ public final class Display {
* {@code getWindowManager()} or {@code getSystemService(Context.WINDOW_SERVICE)}), the
* size of the current app window is returned. As a result, in multi-window mode, the
* returned size can be smaller than the size of the device screen.
+ * The returned window size can vary depending on API level:
+ * <ul>
+ * <li>API level 35 and above, the window size will be returned.
+ * <li>API level 34 and below, the window size minus system decoration areas and
+ * display cutout is returned.
+ * </ul>
* <li>If size is requested from a non-activity context (for example, the application
* context, where the WindowManager is accessed by
* {@code getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}), the
@@ -924,9 +930,10 @@ public final class Display {
* <li>API level 29 and below &mdash; The size of the entire display (based on
* current rotation) minus system decoration areas is returned.
* <li>API level 30 and above &mdash; The size of the top running activity in the
- * current process is returned. If the current process has no running
- * activities, the size of the device default display, including system
- * decoration areas, is returned.
+ * current process is returned, system decoration areas exclusion follows the
+ * behavior defined above, based on the caller's API level. If the current
+ * process has no running activities, the size of the device default display,
+ * including system decoration areas, is returned.
* </ul>
* </ul>
*
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index d22d2a52c8cc..609ad5bb013c 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -78,6 +78,7 @@ public final class InputDevice implements Parcelable {
private final InputDeviceIdentifier mIdentifier;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private final boolean mIsExternal;
+ @Source
private final int mSources;
private final int mKeyboardType;
private final KeyCharacterMap mKeyCharacterMap;
@@ -92,6 +93,7 @@ public final class InputDevice implements Parcelable {
private final boolean mHasBattery;
private final HostUsiVersion mHostUsiVersion;
private final int mAssociatedDisplayId;
+ private final boolean mEnabled;
private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
private final ViewBehavior mViewBehavior = new ViewBehavior(this);
@@ -359,6 +361,28 @@ public final class InputDevice implements Parcelable {
*/
public static final int SOURCE_ANY = 0xffffff00;
+ /** @hide */
+ @IntDef(flag = true, prefix = { "SOURCE_" }, value = {
+ SOURCE_UNKNOWN,
+ SOURCE_KEYBOARD,
+ SOURCE_DPAD,
+ SOURCE_GAMEPAD,
+ SOURCE_TOUCHSCREEN,
+ SOURCE_MOUSE,
+ SOURCE_STYLUS,
+ SOURCE_BLUETOOTH_STYLUS,
+ SOURCE_TRACKBALL,
+ SOURCE_MOUSE_RELATIVE,
+ SOURCE_TOUCHPAD,
+ SOURCE_TOUCH_NAVIGATION,
+ SOURCE_ROTARY_ENCODER,
+ SOURCE_JOYSTICK,
+ SOURCE_HDMI,
+ SOURCE_SENSOR,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Source {}
+
/**
* Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}.
*
@@ -479,7 +503,7 @@ public final class InputDevice implements Parcelable {
int keyboardType, KeyCharacterMap keyCharacterMap, @Nullable String keyboardLanguageTag,
@Nullable String keyboardLayoutType, boolean hasVibrator, boolean hasMicrophone,
boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery, int usiVersionMajor,
- int usiVersionMinor, int associatedDisplayId) {
+ int usiVersionMinor, int associatedDisplayId, boolean enabled) {
mId = id;
mGeneration = generation;
mControllerNumber = controllerNumber;
@@ -510,6 +534,7 @@ public final class InputDevice implements Parcelable {
mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
mHostUsiVersion = new HostUsiVersion(usiVersionMajor, usiVersionMinor);
mAssociatedDisplayId = associatedDisplayId;
+ mEnabled = enabled;
}
private InputDevice(Parcel in) {
@@ -534,6 +559,7 @@ public final class InputDevice implements Parcelable {
mHasBattery = in.readInt() != 0;
mHostUsiVersion = HostUsiVersion.CREATOR.createFromParcel(in);
mAssociatedDisplayId = in.readInt();
+ mEnabled = in.readInt() != 0;
mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);
int numRanges = in.readInt();
@@ -578,6 +604,8 @@ public final class InputDevice implements Parcelable {
private int mUsiVersionMajor = -1;
private int mUsiVersionMinor = -1;
private int mAssociatedDisplayId = Display.INVALID_DISPLAY;
+ // The default is true, the same as the native default state.
+ private boolean mEnabled = true;
private List<MotionRange> mMotionRanges = new ArrayList<>();
private boolean mShouldSmoothScroll;
@@ -708,6 +736,12 @@ public final class InputDevice implements Parcelable {
return this;
}
+ /** @see InputDevice#isEnabled() */
+ public Builder setEnabled(boolean enabled) {
+ mEnabled = enabled;
+ return this;
+ }
+
/** @see InputDevice#getMotionRanges() */
public Builder addMotionRange(int axis, int source,
float min, float max, float flat, float fuzz, float resolution) {
@@ -749,7 +783,8 @@ public final class InputDevice implements Parcelable {
mHasBattery,
mUsiVersionMajor,
mUsiVersionMinor,
- mAssociatedDisplayId);
+ mAssociatedDisplayId,
+ mEnabled);
final int numRanges = mMotionRanges.size();
for (int i = 0; i < numRanges; i++) {
@@ -1298,7 +1333,7 @@ public final class InputDevice implements Parcelable {
* @return Whether the input device is enabled.
*/
public boolean isEnabled() {
- return InputManagerGlobal.getInstance().isInputDeviceEnabled(mId);
+ return mEnabled;
}
/**
@@ -1588,6 +1623,7 @@ public final class InputDevice implements Parcelable {
out.writeInt(mHasBattery ? 1 : 0);
mHostUsiVersion.writeToParcel(out, flags);
out.writeInt(mAssociatedDisplayId);
+ out.writeInt(mEnabled ? 1 : 0);
int numRanges = mMotionRanges.size();
numRanges = numRanges > MAX_RANGES ? MAX_RANGES : numRanges;
@@ -1619,6 +1655,7 @@ public final class InputDevice implements Parcelable {
description.append(" Generation: ").append(mGeneration).append("\n");
description.append(" Location: ").append(mIsExternal ? "external" : "built-in").append(
"\n");
+ description.append(" Enabled: ").append(isEnabled()).append("\n");
description.append(" Keyboard Type: ");
switch (mKeyboardType) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index d7f2b01f46ea..fd10a1f5f710 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -303,7 +303,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
/** Not running an animation. */
- @VisibleForTesting
+ @VisibleForTesting(visibility = PACKAGE)
public static final int ANIMATION_TYPE_NONE = -1;
/** Running animation will show insets */
@@ -317,7 +317,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
public static final int ANIMATION_TYPE_USER = 2;
/** Running animation will resize insets */
- @VisibleForTesting
+ @VisibleForTesting(visibility = PACKAGE)
public static final int ANIMATION_TYPE_RESIZE = 3;
@Retention(RetentionPolicy.SOURCE)
@@ -1714,7 +1714,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
mImeSourceConsumer.onWindowFocusLost();
}
- @VisibleForTesting
+ @VisibleForTesting(visibility = PACKAGE)
public @AnimationType int getAnimationType(@InsetsType int type) {
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner;
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index fdb2a6ee1791..6c670f5d6934 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -17,6 +17,7 @@
package android.view;
import static android.view.InsetsController.ANIMATION_TYPE_NONE;
+import static android.view.InsetsController.ANIMATION_TYPE_RESIZE;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsSourceConsumerProto.ANIMATION_STATE;
@@ -31,6 +32,7 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
@@ -179,10 +181,11 @@ public class InsetsSourceConsumer {
mController.notifyVisibilityChanged();
}
- // If we have a new leash, make sure visibility is up-to-date, even though we
- // didn't want to run an animation above.
- if (mController.getAnimationType(mType) == ANIMATION_TYPE_NONE) {
- applyRequestedVisibilityToControl();
+ // If there is no animation controlling the leash, make sure the visibility and the
+ // position is up-to-date.
+ final int animType = mController.getAnimationType(mType);
+ if (animType == ANIMATION_TYPE_NONE || animType == ANIMATION_TYPE_RESIZE) {
+ applyRequestedVisibilityAndPositionToControl();
}
// Remove the surface that owned by last control when it lost.
@@ -371,21 +374,27 @@ public class InsetsSourceConsumer {
if (DEBUG) Log.d(TAG, "updateSource: " + newSource);
}
- private void applyRequestedVisibilityToControl() {
- if (mSourceControl == null || mSourceControl.getLeash() == null) {
+ private void applyRequestedVisibilityAndPositionToControl() {
+ if (mSourceControl == null) {
+ return;
+ }
+ final SurfaceControl leash = mSourceControl.getLeash();
+ if (leash == null) {
return;
}
final boolean requestedVisible = (mController.getRequestedVisibleTypes() & mType) != 0;
+ final Point surfacePosition = mSourceControl.getSurfacePosition();
try (Transaction t = mTransactionSupplier.get()) {
if (DEBUG) Log.d(TAG, "applyRequestedVisibilityToControl: " + requestedVisible);
if (requestedVisible) {
- t.show(mSourceControl.getLeash());
+ t.show(leash);
} else {
- t.hide(mSourceControl.getLeash());
+ t.hide(leash);
}
// Ensure the alpha value is aligned with the actual requested visibility.
- t.setAlpha(mSourceControl.getLeash(), requestedVisible ? 1 : 0);
+ t.setAlpha(leash, requestedVisible ? 1 : 0);
+ t.setPosition(leash, surfacePosition.x, surfacePosition.y);
t.apply();
}
onPerceptible(requestedVisible);
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 154f1fedbcfa..01015ea250e0 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -20,6 +20,7 @@ import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT
import static android.view.Display.INVALID_DISPLAY;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -35,6 +36,8 @@ import android.view.KeyCharacterMap.KeyData;
import com.android.hardware.input.Flags;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.TimeUnit;
/**
@@ -944,7 +947,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
@FlaggedApi(Flags.FLAG_EMOJI_AND_SCREENSHOT_KEYCODES_AVAILABLE)
public static final int KEYCODE_SCREENSHOT = 318;
- /**
+ /**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
*/
@@ -1034,6 +1037,15 @@ public class KeyEvent extends InputEvent implements Parcelable {
@Deprecated
public static final int ACTION_MULTIPLE = 2;
+ /** @hide */
+ @IntDef(prefix = {"ACTION_"}, value = {
+ ACTION_DOWN,
+ ACTION_UP,
+ ACTION_MULTIPLE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Action {}
+
/**
* SHIFT key locked in CAPS mode.
* Reserved for use by {@link MetaKeyKeyListener} for a published constant in its API.
@@ -1222,6 +1234,33 @@ public class KeyEvent extends InputEvent implements Parcelable {
*/
public static final int META_SCROLL_LOCK_ON = 0x400000;
+ /** @hide */
+ @IntDef(flag = true, prefix = {"META_"}, value = {
+ META_CAP_LOCKED,
+ META_ALT_LOCKED,
+ META_SYM_LOCKED,
+ META_SELECTING,
+ META_ALT_ON,
+ META_ALT_LEFT_ON,
+ META_ALT_RIGHT_ON,
+ META_SHIFT_ON,
+ META_SHIFT_LEFT_ON,
+ META_SHIFT_RIGHT_ON,
+ META_SYM_ON,
+ META_FUNCTION_ON,
+ META_CTRL_ON,
+ META_CTRL_LEFT_ON,
+ META_CTRL_RIGHT_ON,
+ META_META_ON,
+ META_META_LEFT_ON,
+ META_META_RIGHT_ON,
+ META_CAPS_LOCK_ON,
+ META_NUM_LOCK_ON,
+ META_SCROLL_LOCK_ON,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface MetaState {}
+
/**
* This mask is a combination of {@link #META_SHIFT_ON}, {@link #META_SHIFT_LEFT_ON}
* and {@link #META_SHIFT_RIGHT_ON}.
@@ -1366,6 +1405,27 @@ public class KeyEvent extends InputEvent implements Parcelable {
*/
public static final int FLAG_TAINTED = IInputConstants.INPUT_EVENT_FLAG_TAINTED;
+ /** @hide */
+ @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+ FLAG_WOKE_HERE,
+ FLAG_SOFT_KEYBOARD,
+ FLAG_KEEP_TOUCH_MODE,
+ FLAG_FROM_SYSTEM,
+ FLAG_EDITOR_ACTION,
+ FLAG_CANCELED,
+ FLAG_VIRTUAL_HARD_KEY,
+ FLAG_LONG_PRESS,
+ FLAG_CANCELED_LONG_PRESS,
+ FLAG_TRACKING,
+ FLAG_FALLBACK,
+ FLAG_IS_ACCESSIBILITY_EVENT,
+ FLAG_PREDISPATCH,
+ FLAG_START_TRACKING,
+ FLAG_TAINTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Flag {}
+
/**
* Returns the maximum keycode.
*/
@@ -1401,8 +1461,10 @@ public class KeyEvent extends InputEvent implements Parcelable {
// NOTE: mHmac is private and not used in this class, but it's used on native side / parcel.
private @Nullable byte[] mHmac;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @MetaState
private int mMetaState;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @Action
private int mAction;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private int mKeyCode;
@@ -1411,6 +1473,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private int mRepeatCount;
@UnsupportedAppUsage
+ @Flag
private int mFlags;
/**
* The time when the key initially was pressed, in nanoseconds. Only millisecond precision is
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 38f9a91ae44f..6db40bf6e0b8 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -50,6 +50,7 @@ import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -445,6 +446,25 @@ public final class MotionEvent extends InputEvent implements Parcelable {
@Deprecated
public static final int ACTION_POINTER_ID_SHIFT = 8;
+ /** @hide */
+ @IntDef(prefix = { "ACTION_" }, value = {
+ ACTION_DOWN,
+ ACTION_UP,
+ ACTION_MOVE,
+ ACTION_CANCEL,
+ ACTION_OUTSIDE,
+ ACTION_POINTER_DOWN,
+ ACTION_POINTER_UP,
+ ACTION_HOVER_MOVE,
+ ACTION_SCROLL,
+ ACTION_HOVER_ENTER,
+ ACTION_HOVER_EXIT,
+ ACTION_BUTTON_PRESS,
+ ACTION_BUTTON_RELEASE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ActionMasked {}
+
/**
* This flag indicates that the window that received this motion event is partly
* or wholly obscured by another visible window above it and the event directly passed through
@@ -548,6 +568,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
public static final int FLAG_TARGET_ACCESSIBILITY_FOCUS =
MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS;
+ /** @hide */
+ @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+ FLAG_WINDOW_IS_OBSCURED,
+ FLAG_WINDOW_IS_PARTIALLY_OBSCURED,
+ FLAG_HOVER_EXIT_PENDING,
+ FLAG_IS_GENERATED_GESTURE,
+ FLAG_CANCELED,
+ FLAG_NO_FOCUS_CHANGE,
+ FLAG_IS_ACCESSIBILITY_EVENT,
+ FLAG_TAINTED,
+ FLAG_TARGET_ACCESSIBILITY_FOCUS,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Flag {}
+
/**
* Flag indicating the motion event intersected the top edge of the screen.
*/
@@ -1422,6 +1457,63 @@ public final class MotionEvent extends InputEvent implements Parcelable {
names.append(AXIS_GESTURE_SWIPE_FINGER_COUNT, "AXIS_GESTURE_SWIPE_FINGER_COUNT");
}
+ /** @hide */
+ @IntDef(prefix = { "AXIS_" }, value = {
+ AXIS_X,
+ AXIS_Y,
+ AXIS_PRESSURE,
+ AXIS_SIZE,
+ AXIS_TOUCH_MAJOR,
+ AXIS_TOUCH_MINOR,
+ AXIS_TOOL_MAJOR,
+ AXIS_TOOL_MINOR,
+ AXIS_ORIENTATION,
+ AXIS_VSCROLL,
+ AXIS_HSCROLL,
+ AXIS_Z,
+ AXIS_RX,
+ AXIS_RY,
+ AXIS_RZ,
+ AXIS_HAT_X,
+ AXIS_HAT_Y,
+ AXIS_LTRIGGER,
+ AXIS_RTRIGGER,
+ AXIS_THROTTLE,
+ AXIS_RUDDER,
+ AXIS_WHEEL,
+ AXIS_GAS,
+ AXIS_BRAKE,
+ AXIS_DISTANCE,
+ AXIS_TILT,
+ AXIS_SCROLL,
+ AXIS_RELATIVE_X,
+ AXIS_RELATIVE_Y,
+ AXIS_GENERIC_1,
+ AXIS_GENERIC_2,
+ AXIS_GENERIC_3,
+ AXIS_GENERIC_4,
+ AXIS_GENERIC_5,
+ AXIS_GENERIC_6,
+ AXIS_GENERIC_7,
+ AXIS_GENERIC_8,
+ AXIS_GENERIC_9,
+ AXIS_GENERIC_10,
+ AXIS_GENERIC_11,
+ AXIS_GENERIC_12,
+ AXIS_GENERIC_13,
+ AXIS_GENERIC_14,
+ AXIS_GENERIC_15,
+ AXIS_GENERIC_16,
+ AXIS_GESTURE_X_OFFSET,
+ AXIS_GESTURE_Y_OFFSET,
+ AXIS_GESTURE_SCROLL_X_DISTANCE,
+ AXIS_GESTURE_SCROLL_Y_DISTANCE,
+ AXIS_GESTURE_PINCH_SCALE_FACTOR,
+ AXIS_GESTURE_SWIPE_FINGER_COUNT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Axis {}
+
/**
* Button constant: Primary button (left mouse button).
*
@@ -1522,6 +1614,19 @@ public final class MotionEvent extends InputEvent implements Parcelable {
"0x80000000",
};
+ /** @hide */
+ @IntDef(flag = true, prefix = { "BUTTON_" }, value = {
+ BUTTON_PRIMARY,
+ BUTTON_SECONDARY,
+ BUTTON_TERTIARY,
+ BUTTON_BACK,
+ BUTTON_FORWARD,
+ BUTTON_STYLUS_PRIMARY,
+ BUTTON_STYLUS_SECONDARY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Button {}
+
/**
* Classification constant: None.
*
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f22e8f583e1a..0f54940ba0e5 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -781,7 +781,7 @@ public interface WindowManager extends ViewManager {
* <p>
* The metrics describe the size of the area the window would occupy with
* {@link LayoutParams#MATCH_PARENT MATCH_PARENT} width and height, and the {@link WindowInsets}
- * such a window would have.
+ * such a window would have. The {@link WindowInsets} are not deducted from the bounds.
* <p>
* The value of this is based on the <b>current</b> windowing state of the system.
*
@@ -811,7 +811,7 @@ public interface WindowManager extends ViewManager {
* <p>
* The metrics describe the size of the largest potential area the window might occupy with
* {@link LayoutParams#MATCH_PARENT MATCH_PARENT} width and height, and the {@link WindowInsets}
- * such a window would have.
+ * such a window would have. The {@link WindowInsets} are not deducted from the bounds.
* <p>
* Note that this might still be smaller than the size of the physical display if certain areas
* of the display are not available to windows created in this {@link Context}.
@@ -4264,11 +4264,9 @@ public interface WindowManager extends ViewManager {
* no letterbox is applied."/>
*
* <p>
- * A cutout in the corner is considered to be on the short edge: <br/>
- * <img src="{@docRoot}reference/android/images/display_cutout/short_edge/fullscreen_corner_no_letterbox.png"
- * height="720"
- * alt="Screenshot of a fullscreen activity on a display with a cutout in the corner in
- * portrait, no letterbox is applied."/>
+ * A cutout in the corner can be considered to be on different edge in different device
+ * rotations. This behavior may vary from device to device. Use this flag is possible to
+ * letterbox your app if the display cutout is at corner.
*
* <p>
* On the other hand, should the cutout be on the long edge of the display, a letterbox will
diff --git a/core/java/android/view/WindowMetrics.java b/core/java/android/view/WindowMetrics.java
index 26298bc645ad..8bcc9de118e2 100644
--- a/core/java/android/view/WindowMetrics.java
+++ b/core/java/android/view/WindowMetrics.java
@@ -101,9 +101,13 @@ public final class WindowMetrics {
* Returns the bounds of the area associated with this window or {@code UiContext}.
* <p>
* <b>Note that the size of the reported bounds can have different size than
- * {@link Display#getSize(Point)}.</b> This method reports the window size including all system
- * bar areas, while {@link Display#getSize(Point)} reports the area excluding navigation bars
- * and display cutout areas. The value reported by {@link Display#getSize(Point)} can be
+ * {@link Display#getSize(Point)} based on your target API level and calling context.</b>
+ * This method reports the window size including all system
+ * bar areas, while {@link Display#getSize(Point)} can report the area excluding navigation bars
+ * and display cutout areas depending on the calling context and target SDK level. Please refer
+ * to {@link Display#getSize(Point)} for details.
+ * <p>
+ * The value reported by {@link Display#getSize(Point)} excluding system decoration areas can be
* obtained by using:
* <pre class="prettyprint">
* final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index da2bf9d7ab38..4de3a7b5ae4b 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -124,6 +124,7 @@ flag {
namespace: "accessibility"
name: "add_type_window_control"
is_exported: true
+ is_fixed_read_only: true
description: "adds new TYPE_WINDOW_CONTROL to AccessibilityWindowInfo for detecting Window Decorations"
bug: "320445550"
}
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index 163e43a009e7..6fe0784a2fa5 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -114,7 +114,6 @@ public class BackProgressAnimator {
* dispatches as the progress animation updates.
*/
public void onBackStarted(BackMotionEvent event, ProgressCallback callback) {
- reset();
mLastBackEvent = event;
mCallback = callback;
mBackAnimationInProgress = true;
diff --git a/core/java/android/window/TaskFragmentTransaction.java b/core/java/android/window/TaskFragmentTransaction.java
index 32e3f5ad10ca..1e5b0971aad6 100644
--- a/core/java/android/window/TaskFragmentTransaction.java
+++ b/core/java/android/window/TaskFragmentTransaction.java
@@ -189,6 +189,10 @@ public final class TaskFragmentTransaction implements Parcelable {
@Nullable
private IBinder mActivityToken;
+ /** @see #setOtherActivityToken(IBinder) */
+ @Nullable
+ private IBinder mOtherActivityToken;
+
@Nullable
private TaskFragmentParentInfo mTaskFragmentParentInfo;
@@ -210,6 +214,7 @@ public final class TaskFragmentTransaction implements Parcelable {
mActivityToken = in.readStrongBinder();
mTaskFragmentParentInfo = in.readTypedObject(TaskFragmentParentInfo.CREATOR);
mSurfaceControl = in.readTypedObject(SurfaceControl.CREATOR);
+ mOtherActivityToken = in.readStrongBinder();
}
@Override
@@ -224,6 +229,7 @@ public final class TaskFragmentTransaction implements Parcelable {
dest.writeStrongBinder(mActivityToken);
dest.writeTypedObject(mTaskFragmentParentInfo, flags);
dest.writeTypedObject(mSurfaceControl, flags);
+ dest.writeStrongBinder(mOtherActivityToken);
}
/** The change is related to the TaskFragment created with this unique token. */
@@ -292,6 +298,21 @@ public final class TaskFragmentTransaction implements Parcelable {
}
/**
+ * Token of another activity.
+ * <p>For {@link #TYPE_ACTIVITY_REPARENTED_TO_TASK}, it is the next activity (behind the
+ * reparented one) that fills the Task and occludes other activities. It will be the
+ * actual activity token if the activity belongs to the same process as the organizer.
+ * Otherwise, it is {@code null}.
+ *
+ * @hide
+ */
+ @NonNull
+ public Change setOtherActivityToken(@NonNull IBinder activityToken) {
+ mOtherActivityToken = requireNonNull(activityToken);
+ return this;
+ }
+
+ /**
* Sets info of the parent Task of the embedded TaskFragment.
* @see TaskFragmentParentInfo
*
@@ -350,6 +371,12 @@ public final class TaskFragmentTransaction implements Parcelable {
return mActivityToken;
}
+ /** @hide */
+ @Nullable
+ public IBinder getOtherActivityToken() {
+ return mOtherActivityToken;
+ }
+
/**
* Obtains the {@link TaskFragmentParentInfo} for this transaction.
*/
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java
index a2e3d40e5c6b..f0144cbf0f4a 100644
--- a/core/java/android/window/TaskSnapshot.java
+++ b/core/java/android/window/TaskSnapshot.java
@@ -33,6 +33,8 @@ import android.os.SystemClock;
import android.view.Surface;
import android.view.WindowInsetsController;
+import com.android.window.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -334,7 +336,8 @@ public class TaskSnapshot implements Parcelable {
*/
public synchronized void removeReference(@ReferenceFlags int usage) {
mInternalReferences &= ~usage;
- if (mInternalReferences == 0 && mSnapshot != null && !mSnapshot.isClosed()) {
+ if (Flags.releaseSnapshotAggressively() && mInternalReferences == 0 && mSnapshot != null
+ && !mSnapshot.isClosed()) {
mSnapshot.close();
}
}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 760c9166959c..f94766ebb57e 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -78,3 +78,10 @@ flag {
description: "Allows for additional windows tied to WindowDecoration to be layered between status bar and notification shade."
bug: "316186265"
}
+
+flag {
+ name: "enable_app_header_with_task_density"
+ namespace: "lse_desktop_experience"
+ description: "Matches the App Header density to that of the app window, instead of SysUI's"
+ bug: "332414819"
+}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index ee3e34f2b9e2..f08f5b8fddbe 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -163,4 +163,12 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "release_snapshot_aggressively"
+ namespace: "windowing_frontend"
+ description: "Actively release task snapshot memory"
+ bug: "238206323"
+ is_fixed_read_only: true
} \ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 4d1b87a3d97a..b4678f6d812d 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -124,7 +124,10 @@ flag {
flag {
namespace: "windowing_sdk"
- name: "pip_restore_to_overlay"
+ name: "fix_pip_restore_to_overlay"
description: "Restore exit-pip activity back to ActivityEmbedding overlay"
bug: "297887697"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 97ce96ec30f6..1dcd893eb143 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -1908,12 +1908,16 @@ public class ParsingPackageUtils {
} else if (parser.getName().equals("package")) {
final TypedArray sa = res.obtainAttributes(parser,
R.styleable.AndroidManifestQueriesPackage);
- final String packageName = sa.getNonConfigurationString(
- R.styleable.AndroidManifestQueriesPackage_name, 0);
- if (TextUtils.isEmpty(packageName)) {
- return input.error("Package name is missing from package tag.");
+ try {
+ final String packageName = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestQueriesPackage_name, 0);
+ if (TextUtils.isEmpty(packageName)) {
+ return input.error("Package name is missing from package tag.");
+ }
+ pkg.addQueriesPackage(packageName.intern());
+ } finally {
+ sa.recycle();
}
- pkg.addQueriesPackage(packageName.intern());
} else if (parser.getName().equals("provider")) {
final TypedArray sa = res.obtainAttributes(parser,
R.styleable.AndroidManifestQueriesProvider);
diff --git a/core/java/com/android/internal/widget/CompactMessagingLayout.java b/core/java/com/android/internal/widget/CompactMessagingLayout.java
new file mode 100644
index 000000000000..1e2c01ae4be9
--- /dev/null
+++ b/core/java/com/android/internal/widget/CompactMessagingLayout.java
@@ -0,0 +1,263 @@
+/*
+ * 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.widget;
+
+import android.app.Notification;
+import android.app.Notification.MessagingStyle;
+import android.app.Person;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.RemotableViewMethod;
+import android.view.View;
+import android.view.ViewStub;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.RemoteViews;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A custom-built layout for the compact Heads Up of Notification.MessagingStyle .
+ */
+@RemoteViews.RemoteView
+public class CompactMessagingLayout extends FrameLayout {
+
+ private final PeopleHelper mPeopleHelper = new PeopleHelper();
+
+ private ViewStub mConversationFacePileViewStub;
+
+ private int mNotificationBackgroundColor;
+ private int mFacePileSize;
+ private int mFacePileAvatarSize;
+ private int mFacePileProtectionWidth;
+ private int mLayoutColor;
+
+ public CompactMessagingLayout(@NonNull Context context) {
+ super(context);
+ }
+
+ public CompactMessagingLayout(@NonNull Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public CompactMessagingLayout(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public CompactMessagingLayout(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mPeopleHelper.init(getContext());
+ mConversationFacePileViewStub = requireViewById(R.id.conversation_face_pile);
+ mFacePileSize = getResources()
+ .getDimensionPixelSize(R.dimen.conversation_compact_face_pile_size);
+ mFacePileAvatarSize = getResources()
+ .getDimensionPixelSize(R.dimen.conversation_compact_face_pile_avatar_size);
+ mFacePileProtectionWidth = getResources().getDimensionPixelSize(
+ R.dimen.conversation_compact_face_pile_protection_width);
+ }
+
+ /**
+ * Set conversation data
+ *
+ * @param extras Bundle contains conversation data
+ */
+ @RemotableViewMethod(asyncImpl = "setGroupFacePileAsync")
+ public void setGroupFacePile(Bundle extras) {
+ // NO-OP
+ }
+
+ /**
+ * async version of {@link ConversationLayout#setLayoutColor}
+ */
+ @RemotableViewMethod
+ public Runnable setLayoutColorAsync(int color) {
+ mLayoutColor = color;
+ return NotificationRunnables.NOOP;
+ }
+
+ @RemotableViewMethod(asyncImpl = "setLayoutColorAsync")
+ public void setLayoutColor(int color) {
+ mLayoutColor = color;
+ }
+
+ /**
+ * @param color the color of the notification background
+ */
+ @RemotableViewMethod
+ public void setNotificationBackgroundColor(int color) {
+ mNotificationBackgroundColor = color;
+ }
+
+ /**
+ * async version of {@link CompactMessagingLayout#setGroupFacePile}
+ * setGroupFacePile!
+ */
+ public Runnable setGroupFacePileAsync(Bundle extras) {
+ final Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
+ final List<Notification.MessagingStyle.Message> newMessages =
+ Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
+ final Parcelable[] histMessages =
+ extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES);
+ final List<Notification.MessagingStyle.Message> newHistoricMessages =
+ Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
+ final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
+
+ final List<List<MessagingStyle.Message>> groups = groupMessages(newMessages,
+ newHistoricMessages);
+ final PeopleHelper.NameToPrefixMap nameToPrefixMap =
+ mPeopleHelper.mapUniqueNamesToPrefixWithGroupList(groups);
+ final int layoutColor = mLayoutColor;
+ // Find last two person's icon to show them in the face pile.
+ Icon secondLastIcon = null;
+ Icon lastIcon = null;
+ CharSequence lastKey = null;
+ final CharSequence userKey = getPersonKey(user);
+ for (int i = groups.size() - 1; i >= 0; i--) {
+ final MessagingStyle.Message message = groups.get(i).get(0);
+ final Person sender =
+ message.getSenderPerson() != null ? message.getSenderPerson() : user;
+ final CharSequence senderKey = getPersonKey(sender);
+ final boolean notUser = senderKey != userKey;
+ final boolean notIncluded = senderKey != lastKey;
+
+ if ((notUser && notIncluded) || (i == 0 && lastKey == null)) {
+ final Icon icon = getSenderIcon(sender, nameToPrefixMap, layoutColor);
+ if (lastIcon == null) {
+ lastIcon = icon;
+ lastKey = senderKey;
+ } else {
+ secondLastIcon = icon;
+ break;
+ }
+ }
+ }
+
+ if (lastIcon == null) {
+ lastIcon = getSenderIcon(null, null, layoutColor);
+ }
+
+ if (secondLastIcon == null) {
+ secondLastIcon = getSenderIcon(null, null, layoutColor);
+ }
+ final Drawable secondLastIconDrawable = secondLastIcon.loadDrawable(getContext());
+ final Drawable lastIconDrawable = lastIcon.loadDrawable(getContext());
+ return () -> {
+ final View conversationFacePile = mConversationFacePileViewStub.inflate();
+ conversationFacePile.setVisibility(VISIBLE);
+
+ final ImageView facePileBottomBg = conversationFacePile.requireViewById(
+ com.android.internal.R.id.conversation_face_pile_bottom_background);
+ final ImageView facePileTop = conversationFacePile.requireViewById(
+ com.android.internal.R.id.conversation_face_pile_top);
+ final ImageView facePileBottom = conversationFacePile.requireViewById(
+ com.android.internal.R.id.conversation_face_pile_bottom);
+
+ facePileTop.setImageDrawable(secondLastIconDrawable);
+ facePileBottom.setImageDrawable(lastIconDrawable);
+ facePileBottomBg.setImageTintList(ColorStateList.valueOf(mNotificationBackgroundColor));
+ setSize(conversationFacePile, mFacePileSize);
+ setSize(facePileBottom, mFacePileAvatarSize);
+ setSize(facePileTop, mFacePileAvatarSize);
+ setSize(facePileBottomBg, mFacePileAvatarSize + 2 * mFacePileProtectionWidth);
+ };
+ }
+
+ @NonNull
+ private Icon getSenderIcon(@Nullable Person sender,
+ @Nullable PeopleHelper.NameToPrefixMap uniqueNames,
+ int layoutColor) {
+ if (sender == null) {
+ return mPeopleHelper.createAvatarSymbol(/* name = */ "", /* symbol = */ "",
+ layoutColor);
+ }
+
+ if (sender.getIcon() != null) {
+ return sender.getIcon();
+ }
+
+ final CharSequence senderName = sender.getName();
+ if (!TextUtils.isEmpty(senderName)) {
+ final String symbol = uniqueNames != null ? uniqueNames.getPrefix(senderName) : "";
+ return mPeopleHelper.createAvatarSymbol(senderName, symbol, layoutColor);
+ }
+
+ return mPeopleHelper.createAvatarSymbol(/* name = */ "", /* symbol = */ "", layoutColor);
+ }
+
+
+ /**
+ * Groups the given messages by their sender.
+ */
+ private static List<List<MessagingStyle.Message>> groupMessages(
+ List<MessagingStyle.Message> messages,
+ List<MessagingStyle.Message> historicMessages
+ ) {
+ if (messages.isEmpty() && historicMessages.isEmpty()) return List.of();
+
+ ArrayList<MessagingStyle.Message> currentGroup = null;
+ CharSequence currentSenderKey = null;
+ final ArrayList<List<MessagingStyle.Message>> groups = new ArrayList<>();
+ final int histSize = historicMessages.size();
+
+ for (int i = 0; i < histSize + messages.size(); i++) {
+ final MessagingStyle.Message message = i < histSize ? historicMessages.get(i)
+ : messages.get(i - histSize);
+ if (message == null) continue;
+
+ final CharSequence senderKey = getPersonKey(message.getSenderPerson());
+ final boolean isNewGroup = currentGroup == null || senderKey != currentSenderKey;
+ if (isNewGroup) {
+ currentGroup = new ArrayList<>();
+ groups.add(currentGroup);
+ currentSenderKey = senderKey;
+ }
+ currentGroup.add(message);
+ }
+ return groups;
+ }
+
+ private static CharSequence getPersonKey(@Nullable Person person) {
+ return person == null ? null : person.getKey() == null ? person.getName() : person.getKey();
+ }
+
+ private static void setSize(View view, int size) {
+ final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams();
+ lp.width = size;
+ lp.height = size;
+ view.setLayoutParams(lp);
+ }
+}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 80a75999c3d0..d9c40c3ea783 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -483,4 +483,8 @@ cc_library_shared {
"libnativehelper",
"libvintf",
],
+
+ required: [
+ "vintf",
+ ],
}
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 8dc9d0aa578e..7a4854bbd260 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -32,6 +32,8 @@ static jmethodID gHashMapInit;
static jmethodID gHashMapPut;
static jclass gLongClazz;
static jmethodID gLongValueOf;
+static jclass gVintfObjectClazz;
+static jmethodID gRunCommand;
namespace android {
@@ -47,6 +49,56 @@ using vintf::VintfObject;
using vintf::Vndk;
using vintf::CheckFlags::ENABLE_ALL_CHECKS;
+// Instead of VintfObject::GetXxx(), we construct
+// HalManifest/CompatibilityMatrix objects by calling `vintf` through
+// UiAutomation.executeShellCommand() so that the commands are executed
+// using shell identity. Otherwise, we would need to allow "apps" to access
+// files like apex-info-list.xml which we don't want to open to apps.
+// This is okay because VintfObject is @TestApi and only used in CTS tests.
+
+static std::string runCmd(JNIEnv* env, const char* cmd) {
+ jstring jstr = (jstring)env->CallStaticObjectMethod(gVintfObjectClazz, gRunCommand,
+ env->NewStringUTF(cmd));
+ std::string output;
+ if (jstr) {
+ auto cstr = env->GetStringUTFChars(jstr, nullptr);
+ output = std::string(cstr);
+ env->ReleaseStringUTFChars(jstr, cstr);
+ } else {
+ LOG(WARNING) << "Failed to run " << cmd;
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ return output;
+}
+
+template <typename T>
+static std::shared_ptr<const T> fromXml(const std::string& content) {
+ std::shared_ptr<T> object = std::make_unique<T>();
+ std::string error;
+ if (fromXml(object.get(), content, &error)) {
+ return object;
+ }
+ LOG(WARNING) << "Unabled to parse: " << error;
+ return nullptr;
+}
+
+static std::shared_ptr<const HalManifest> getDeviceHalManifest(JNIEnv* env) {
+ return fromXml<HalManifest>(runCmd(env, "vintf dm"));
+}
+
+static std::shared_ptr<const HalManifest> getFrameworkHalManifest(JNIEnv* env) {
+ return fromXml<HalManifest>(runCmd(env, "vintf fm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getDeviceCompatibilityMatrix(JNIEnv* env) {
+ return fromXml<CompatibilityMatrix>(runCmd(env, "vintf dcm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getFrameworkCompatibilityMatrix(JNIEnv* env) {
+ return fromXml<CompatibilityMatrix>(runCmd(env, "vintf fcm"));
+}
+
template<typename V>
static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) {
size_t i;
@@ -83,12 +135,10 @@ static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass)
{
std::vector<std::string> cStrings;
- tryAddSchema(VintfObject::GetDeviceHalManifest(), "device manifest", &cStrings);
- tryAddSchema(VintfObject::GetFrameworkHalManifest(), "framework manifest", &cStrings);
- tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), "device compatibility matrix",
- &cStrings);
- tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), "framework compatibility matrix",
- &cStrings);
+ tryAddSchema(getDeviceHalManifest(env), "device manifest", &cStrings);
+ tryAddSchema(getFrameworkHalManifest(env), "framework manifest", &cStrings);
+ tryAddSchema(getDeviceCompatibilityMatrix(env), "device compatibility matrix", &cStrings);
+ tryAddSchema(getFrameworkCompatibilityMatrix(env), "framework compatibility matrix", &cStrings);
return toJavaStringArray(env, cStrings);
}
@@ -108,15 +158,13 @@ static jint android_os_VintfObject_verifyBuildAtBoot(JNIEnv*, jclass) {
static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
std::set<std::string> halNames;
- tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(),
- "device manifest", &halNames);
- tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(),
- "framework manifest", &halNames);
+ tryAddHalNamesAndVersions(getDeviceHalManifest(env), "device manifest", &halNames);
+ tryAddHalNamesAndVersions(getFrameworkHalManifest(env), "framework manifest", &halNames);
return toJavaStringArray(env, halNames);
}
static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
- std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+ std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
return nullptr;
@@ -126,8 +174,7 @@ static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
}
static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
- std::shared_ptr<const CompatibilityMatrix> matrix =
- VintfObject::GetFrameworkCompatibilityMatrix();
+ std::shared_ptr<const CompatibilityMatrix> matrix = getFrameworkCompatibilityMatrix(env);
if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
return nullptr;
@@ -148,7 +195,7 @@ static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jc
}
static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
- std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
+ std::shared_ptr<const HalManifest> manifest = getFrameworkHalManifest(env);
if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
return nullptr;
@@ -163,7 +210,7 @@ static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
}
static jobject android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion(JNIEnv* env, jclass) {
- std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+ std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
if (manifest == nullptr || manifest->level() == Level::UNSPECIFIED) {
return nullptr;
}
@@ -188,19 +235,20 @@ static const JNINativeMethod gVintfObjectMethods[] = {
const char* const kVintfObjectPathName = "android/os/VintfObject";
-int register_android_os_VintfObject(JNIEnv* env)
-{
-
+int register_android_os_VintfObject(JNIEnv* env) {
gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap"));
gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V");
- gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz,
- "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
gLongClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Long"));
gLongValueOf = GetStaticMethodIDOrDie(env, gLongClazz, "valueOf", "(J)Ljava/lang/Long;");
+ gVintfObjectClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, kVintfObjectPathName));
+ gRunCommand = GetStaticMethodIDOrDie(env, gVintfObjectClazz, "runShellCommand",
+ "(Ljava/lang/String;)Ljava/lang/String;");
return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
- NELEM(gVintfObjectMethods));
+ NELEM(gVintfObjectMethods));
}
extern int register_android_os_VintfRuntimeInfo(JNIEnv* env);
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index aae0da9006a2..f5992d906323 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -90,7 +90,8 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi
deviceInfo.hasButtonUnderPad(), deviceInfo.hasSensor(),
deviceInfo.hasBattery(), usiVersion.majorVersion,
usiVersion.minorVersion,
- deviceInfo.getAssociatedDisplayId()));
+ deviceInfo.getAssociatedDisplayId(),
+ deviceInfo.isEnabled()));
// Note: We do not populate the Bluetooth address into the InputDevice object to avoid leaking
// it to apps that do not have the Bluetooth permission.
@@ -126,7 +127,7 @@ int register_android_view_InputDevice(JNIEnv* env)
gInputDeviceClassInfo.ctor = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
"(IIILjava/lang/String;IIILjava/lang/"
"String;ZIILandroid/view/KeyCharacterMap;Ljava/"
- "lang/String;Ljava/lang/String;ZZZZZIII)V");
+ "lang/String;Ljava/lang/String;ZZZZZIIIZ)V");
gInputDeviceClassInfo.addMotionRange =
GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "addMotionRange", "(IIFFFFF)V");
diff --git a/core/res/res/layout/notification_template_material_messaging_compact_heads_up.xml b/core/res/res/layout/notification_template_material_messaging_compact_heads_up.xml
index 3b288d7038e1..82920bad95cd 100644
--- a/core/res/res/layout/notification_template_material_messaging_compact_heads_up.xml
+++ b/core/res/res/layout/notification_template_material_messaging_compact_heads_up.xml
@@ -13,7 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<FrameLayout
+<com.android.internal.widget.CompactMessagingLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
@@ -45,6 +45,14 @@
android:scaleType="centerCrop"
android:importantForAccessibility="no"
/>
+ <ViewStub
+ android:layout="@layout/conversation_face_pile_layout"
+ android:layout_gravity="center_vertical|start"
+ android:layout_width="@dimen/conversation_compact_face_pile_size"
+ android:layout_height="@dimen/conversation_compact_face_pile_size"
+ android:layout_marginStart="@dimen/notification_icon_circle_start"
+ android:id="@+id/conversation_face_pile"
+ />
<FrameLayout
android:id="@+id/alternate_expand_target"
android:layout_width="@dimen/notification_content_margin_start"
@@ -101,4 +109,4 @@
/>
</FrameLayout>
</LinearLayout>
-</FrameLayout>
+</com.android.internal.widget.CompactMessagingLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 2a3c691dcd04..7fe8641cd889 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Stembystand"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Snelsluit"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nuwe kennisgewing"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fisieke sleutelbord"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sekuriteit"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 08a290c454f3..1d1ded6ce468 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"የድምጽ እርዳታ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"መቆለፊያ"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"አዲስ ማሳወቂያ"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"አካላዊ ቁልፍ ሰሌዳ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ደህንነት"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"በመልክ መክፈትን እንደገና ያዋቅሩ"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"የእርስዎ የመልክ ሞዴል በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በመልክ ለመክፈት እንደገና ያዋቅሩት።"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ያዋቅሩ"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"አሁን አይደለም"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 20d491fd22d8..6ee9d5dab3a3 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -287,6 +287,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"المساعد الصوتي"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"إلغاء التأمين"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"إشعار جديد"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"لوحة المفاتيح الخارجية"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"الأمان"</string>
@@ -2398,9 +2400,9 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"تم ضبط تنسيق لوحة المفاتيح على <xliff:g id="LAYOUT_1">%1$s</xliff:g> و<xliff:g id="LAYOUT_2">%2$s</xliff:g> و<xliff:g id="LAYOUT_3">%3$s</xliff:g>… انقر لتغييره."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"تم إعداد لوحات المفاتيح الخارجية"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"انقر لعرض لوحات المفاتيح."</string>
- <string name="profile_label_private" msgid="6463418670715290696">"ملف شخصي خاص"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"المساحة الخاصة"</string>
<string name="profile_label_clone" msgid="769106052210954285">"نسخة طبق الأصل"</string>
- <string name="profile_label_work" msgid="3495359133038584618">"ملف العمل"</string>
+ <string name="profile_label_work" msgid="3495359133038584618">"مساحة العمل"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"ملف العمل 2"</string>
<string name="profile_label_work_3" msgid="4834572253956798917">"ملف العمل 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ملف شخصي تجريبي"</string>
@@ -2417,22 +2419,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"إعادة إعداد ميزة \"فتح الجهاز ببصمة الإصبع\""</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"إعادة إعداد ميزة \"فتح الجهاز بالتعرّف على الوجه\""</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"هناك مشكلة في نموذج الوجه الخاص بك وتم حذفه. يُرجى إعداده مرة أخرى لفتح قفل هاتفك باستخدام وجهك."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"إعداد"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"لاحقًا"</string>
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 30ced90bd5e4..9064df1d5ae5 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"কণ্ঠধ্বনিৰে সহায়"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"লকডাউন"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"৯৯৯+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"নতুন জাননী"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"কায়িক কীব’ৰ্ড"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"সুৰক্ষা"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ফে’চ আনলক পুনৰ ছেট আপ কৰক"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপোনাৰ মুখাৱয়বৰ মডেলটোৱে ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। মুখাৱয়বৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ছেট আপ কৰক"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এতিয়া নহয়"</string>
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 49073f11f897..23a96689c073 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Səs Yardımçısı"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Kilidləyin"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Yeni bildiriş"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fiziki klaviatura"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Güvənlik"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarlayın"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"İndi yox"</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ca66ef4a018f..db9a93f7a63a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zaključavanje"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Novo obaveštenje"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tastatura"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Bezbednost"</string>
@@ -835,11 +837,11 @@
<string name="policylab_watchLogin" msgid="7599669460083719504">"Nadzor pokušaja otključavanja ekrana"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke sa Android TV uređaja ako se unese previše netačnih lozinki."</string>
- <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke sa sistema za info-zabavu ako je netačna lozinka uneta previše puta."</string>
+ <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava sistem za informacije i zabavu ili briše sve podatke sa sistema za informacije i zabavu ako je netačna lozinka uneta previše puta."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava telefon ili briše sve podatke sa telefona ako je netačna lozinka uneta previše puta."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava tablet ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke ovog profila ako se unese previše netačnih lozinki."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava sistem za informacije i zabavu ili briše sve podatke ovog profila ako se unese previše netačnih lozinki."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava telefon ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"Promena zaključavanja ekrana"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Menja otključavanje ekrana."</string>
@@ -848,13 +850,13 @@
<string name="policylab_wipeData" msgid="1359485247727537311">"Brisanje svih podataka"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Brisanje podataka na tabletu bez upozorenja resetovanjem na fabrička podešavanja."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Briše podatke Android TV uređaja bez upozorenja pomoću resetovanja na fabrička podešavanja."</string>
- <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Briše podatke na sistemu za info-zabavu bez upozorenja resetovanjem na fabrička podešavanja."</string>
+ <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Briše podatke na sistemu za informacije i zabavu bez upozorenja resetovanjem na fabrička podešavanja."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Brisanje podataka na telefonu bez upozorenja resetovanjem na fabrička podešavanja."</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Brisanje podataka profila"</string>
<string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Obriši podatke korisnika"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Briše podatke ovog korisnika na ovom tabletu bez upozorenja."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Briše podatke ovog korisnika na ovom Android TV uređaju bez upozorenja."</string>
- <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Briše podatke ovog profila na ovom sistemu za info-zabavu bez upozorenja."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Briše podatke ovog profila na ovom sistemu za informacije i zabavu bez upozorenja."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Briše podatke ovog korisnika na ovom telefonu bez upozorenja."</string>
<string name="policylab_setGlobalProxy" msgid="215332221188670221">"Podesite globalni proksi server uređaja"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Podešava globalni proksi uređaja koji će se koristiti dok su smernice omogućene. Samo vlasnik uređaja može da podesi globalni proksi."</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo podesite otključavanje otiskom prsta"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Podesi"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4cd150a6ebf6..ec19c2da015e 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Галас. дапамога"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Блакіроўка"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Новае апавяшчэнне"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Фізічная клавіятура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Бяспека"</string>
@@ -2415,22 +2417,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Наладзіць разблакіроўку адбіткам пальца паўторна"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Паўторна наладзьце распазнаванне твару"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Мадэль твару не працавала належным чынам і была выдалена. Каб мець магчымасць разблакіраваць тэлефон з дапамогай распазнавання твару, наладзьце яго яшчэ раз."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Наладзіць"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index eb2e9207367f..1b73710c4548 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Гласова помощ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Заключване"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Ново известие"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физическа клавиатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Сигурност"</string>
@@ -1726,7 +1728,7 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Без включване"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ВКЛ."</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ИЗКЛ."</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Искате ли да разрешите на <xliff:g id="SERVICE">%1$s</xliff:g> да има пълен контрол над устройството ви?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Искате ли да разрешите на „<xliff:g id="SERVICE">%1$s</xliff:g>“ да има пълен контрол над устройството ви?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Пълният контрол е подходящ за приложенията, които помагат на потребителите със специални нужди, но не и за повечето приложения."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Преглед и управление на екрана"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Услугата може да чете цялото съдържание на екрана и да показва такова върху други приложения."</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Повторно настройване на „Отключване с лице“"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Моделът на лицето ви бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с лице."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настройване"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 6618127ada43..0e32bbe64c86 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ভয়েস সহায়তা"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"লকডাউন"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"৯৯৯+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"নতুন বিজ্ঞপ্তি"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ফিজিক্যাল কীবোর্ড"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"নিরাপত্তা"</string>
@@ -644,7 +646,7 @@
<string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"চালিয়ে যেতে আপনার বায়োমেট্রিক্স বা স্ক্রিন লক ব্যবহার করুন"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্রিক হার্ডওয়্যার পাওয়া যাবে না"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"যাচাইকরণ বাতিল হয়েছে"</string>
- <string name="biometric_not_recognized" msgid="5106687642694635888">"স্বীকৃত নয়"</string>
+ <string name="biometric_not_recognized" msgid="5106687642694635888">"শনাক্ত করা যায়নি"</string>
<string name="biometric_face_not_recognized" msgid="5535599455744525200">"ফেস চেনা যায়নি"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"যাচাইকরণ বাতিল হয়েছে"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"পিন, প্যাটার্ন অথবা পাসওয়ার্ড সেট করা নেই"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করুন"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"\'ফেস আনলক\' আবার সেট-আপ করুন"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপনার ফেস মডেল ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফেস ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"সেট-আপ করুন"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এখন নয়"</string>
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 4f058bf74b41..ddc515325992 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zaključaj"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Novo obavještenje"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tastatura"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sigurnost"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo postavite otključavanje otiskom prsta"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavite"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 77fd6b833bb8..1fd814d3561a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -85,7 +85,7 @@
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No es pot accedir a la xarxa mòbil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova de canviar de xarxa preferent. Toca per canviar-la."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Les trucades d\'emergència no estan disponibles"</string>
- <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Per poder fer trucades d\'emergència, cal tenir connexió a una xarxa mòbil"</string>
+ <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Per poder fer trucades d\'emergència, cal tenir connexió de xarxa mòbil"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Desviació de trucades"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de devolució de trucada d\'emergència"</string>
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assist. per veu"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueig de seguretat"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"+999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificació nova"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclat físic"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguretat"</string>
@@ -1905,8 +1907,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Actualitzat per l\'administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions a la xarxa."</string>
- <string name="battery_saver_description" msgid="8518809702138617167">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions a la xarxa."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions de xarxa."</string>
+ <string name="battery_saver_description" msgid="8518809702138617167">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions de xarxa."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Per reduir l\'ús de dades, la funció Estalvi de dades evita que determinades aplicacions enviïn o rebin dades en segon pla. L\'aplicació que estiguis fent servir podrà accedir a les dades, però menys sovint. Això vol dir, per exemple, que les imatges no es mostraran fins que no les toquis."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vols activar l\'Estalvi de dades?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activa"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ara no"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 5615f79d1013..ec7bb29a2ebe 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Hlas. asistence"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zamknout"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nové oznámení"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyzická klávesnice"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Zabezpečení"</string>
@@ -2415,22 +2417,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string>
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavit"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teď ne"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index fd04e42c8e1f..ef4126283fa9 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Taleassistent"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Låsning"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Ny notifikation"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysisk tastatur"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sikkerhed"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nu"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 630ec7512784..1df8954ef78d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Sprachassistent"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Sperren"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Neue Benachrichtigung"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Physische Tastatur"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sicherheit"</string>
@@ -1997,7 +1999,7 @@
<string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Notruf"</string>
<string name="set_up_screen_lock_title" msgid="8346083801616474030">"Displaysperre einrichten"</string>
<string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Displaysperre einrichten"</string>
- <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Richte zur Nutzung des privaten Bereichs auf dem Gerät die Displaysperre ein"</string>
+ <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Richte zur Nutzung des vertraulichen Profils auf dem Gerät die Displaysperre ein"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"App ist nicht verfügbar"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist derzeit nicht verfügbar."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nicht verfügbar"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Einrichten"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nicht jetzt"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 54901313dad2..3c7d16714849 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Φων.υποβοηθ."</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Κλείδωμα"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Νέα ειδοποίηση"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Κανονικό πληκτρολόγιο"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Ασφάλεια"</string>
@@ -2402,7 +2404,7 @@
<string name="profile_label_test" msgid="9168641926186071947">"Δοκιμή"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Κοινόχρηστο"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Προφίλ εργασίας"</string>
- <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Απόρρητος χώρος"</string>
+ <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ιδιωτικός χώρος"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Κλώνος"</string>
<string name="accessibility_label_communal_profile" msgid="1437173163111334791">"Κοινόχρηστο"</string>
<string name="redacted_notification_message" msgid="1520587845842228816">"Έγινε απόκρυψη της ειδοποίησης ευαίσθητου περιεχομένου"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με το πρόσωπο"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Το μοντέλο προσώπου δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το πρόσωπό σας."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ρύθμιση"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Όχι τώρα"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index a32fcca8fc1f..5f7dd656d0ca 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lockdown"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"New notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Security"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 9f06f71c147f..d1894b5e7106 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -283,6 +283,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lockdown"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"Reply"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"New notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Security"</string>
@@ -2414,8 +2415,10 @@
<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="6261149111900787302">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted to improve performance"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7688302770424064884">"<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 to improve performance"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
+ <skip />
<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="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bfcc4be89814..12fd027cdf2d 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lockdown"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"New notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Security"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 80007323188c..129310eec160 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lockdown"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"New notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Physical keyboard"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Security"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 0fe2cccd8d58..e08f93466a0e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -283,6 +283,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎Voice Assist‎‏‎‎‏‎"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎Lockdown‎‏‎‎‏‎"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎999+‎‏‎‎‏‎"</string>
+ <string name="notification_compact_heads_up_reply" msgid="2425293958371284340">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎Reply‎‏‎‎‏‎"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎New notification‎‏‎‎‏‎"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‎Physical keyboard‎‏‎‎‏‎"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎Security‎‏‎‎‏‎"</string>
@@ -2414,8 +2415,10 @@
<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="6261149111900787302">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ wasn\'t working well and was deleted to improve performance‎‏‎‎‏‎"</string>
- <string name="fingerprint_dangling_notification_msg_2" msgid="7688302770424064884">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎<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 to improve performance‎‏‎‎‏‎"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
+ <skip />
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
+ <skip />
<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="face_dangling_notification_title" msgid="947852541060975473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎Set up Face Unlock again‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8717640a6910..30a0457201b4 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nueva"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguridad"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir 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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vuelve a configurar el Desbloqueo con huellas dactilares"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 6549da21376f..5079fdf415f9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo de seguridad"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt; 999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nueva"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguridad"</string>
@@ -1402,7 +1404,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Se ha detectado un accesorio de audio analógico"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Depuración por USB activa"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar la depuración USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar la depuración por USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Seleccionar para inhabilitar la depuración por USB"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuración inalámbrica conectada"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar la depuración inalámbrica"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 92f89e3ccb99..16b0ea25b158 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Häälabi"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lukusta"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Uus märguanne"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Füüsiline klaviatuur"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Turvalisus"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Seadista"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Mitte praegu"</string>
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 2d4130e23fc0..4fb4726dce87 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ahots-laguntza"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blokeatu"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Jakinarazpen berria"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teklatu fisikoa"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurtasuna"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguratu"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Orain ez"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 07b267471157..7272bcfcf8f3 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"دستیار صوتی"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"قفل همه"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"۹۹۹+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"اعلان جدید"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"صفحه‌کلید فیزیکی"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"امنیت"</string>
@@ -666,7 +668,7 @@
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"اثر انگشت تشخیص داده نشد"</string>
<string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"اثر انگشت تشخیص داده نشد"</string>
- <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"چهره شناسایی نشد. درعوض از اثر انگشت استفاده کنید."</string>
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"چهره شناسایی نشد، از اثر انگشت استفاده کنید."</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالت‌سنجی شد"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چهره اصالت‌سنجی شد"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالت‌سنجی شد، لطفاً تأیید را فشار دهید"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راه‌اندازی مجدد «قفل‌گشایی با اثر انگشت»"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"راه‌اندازی مجدد «قفل‌گشایی با چهره»"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"مدل چهره شما خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با چهره، دوباره آن را راه‌اندازی کنید."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"راه‌اندازی"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"حالا نه"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index e802443e5acb..7062a8955acb 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ääniapuri"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lukitse"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Uusi ilmoitus"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyysinen näppäimistö"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Turvallisuus"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index bf70c3cd4e97..bc61dead4cdb 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assist. vocale"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Verrouillage"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nouvelle notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Clavier physique"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sécurité"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurer"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Plus tard"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 57272245224f..69d42194a95e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assistance vocale"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Verrouiller"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nouvelle notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Clavier physique"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sécurité"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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 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="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 votre visage."</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>
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 663ef9ace52d..dfa4fe3d75b2 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloquear"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nova"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguranza"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora non"</string>
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index dc4253750380..8a84d25ee961 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"વૉઇસ સહાય"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"લૉકડાઉન"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"નવું નોટિફિકેશન"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ભૌતિક કીબોર્ડ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"સુરક્ષા"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"તમારા ચહેરાનું મૉડલ બરાબર કામ કરતું ન હતું અને તેને ડિલીટ કરવામાં આવ્યું હતું. તમારા ફોનને ચહેરા વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"સેટઅપ કરો"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"હમણાં નહીં"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 25f6ca1cc6f6..e43491294ce2 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"आवाज़ से डिवाइस का इस्तेमाल"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"लॉकडाउन"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"नई सूचना"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"सामान्य कीबोर्ड"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"सुरक्षा"</string>
@@ -666,7 +668,7 @@
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"फ़िंगरप्रिंट की पहचान नहीं हो पाई"</string>
<string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"फ़िंगरप्रिंट की पहचान नहीं हो पाई"</string>
- <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"चेहरा नहीं पहचाना गया. फ़िंगरप्रिंट इस्तेमाल करें."</string>
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"चेहरा की पहचान नहीं हो पाई. फ़िंगरप्रिंट का इस्तेमाल करें."</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"फ़िंगरप्रिंट की पुष्टि हो गई"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"चेहरे की पहचान की गई"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरे की पहचान की गई, कृपया पुष्टि बटन दबाएं"</string>
@@ -2394,7 +2396,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"कीबोर्ड का लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… पर सेट कर दिया गया है. इसे बदलने के लिए टैप करें."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"फ़िज़िकल कीबोर्ड कॉन्फ़िगर किए गए"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"कीबोर्ड देखने के लिए टैप करें"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"निजी"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"प्राइवेट"</string>
<string name="profile_label_clone" msgid="769106052210954285">"क्लोन"</string>
<string name="profile_label_work" msgid="3495359133038584618">"ऑफ़िस"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"ऑफ़िस 2"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"अच्छे से काम न करने की वजह से, चेहरे का मॉडल मिटा दिया गया. फ़ेस अनलॉक की सुविधा की मदद से फ़ोन अनलॉक करने के लिए, इस सुविधा को दोबारा सेट अप करें."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट अप करें"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अभी नहीं"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 117d4e5632c6..0bd8be3b4472 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Glasovna pomoć"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zaključaj"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova obavijest"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizička tipkovnica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sigurnost"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovno postavite otključavanje otiskom prsta"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavi"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sad"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index de8fa848edd6..aeebbdc22aac 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Hangsegéd"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zárolás"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Új értesítés"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizikai billentyűzet"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Biztonság"</string>
@@ -1997,7 +1999,7 @@
<string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Vészhelyzet"</string>
<string name="set_up_screen_lock_title" msgid="8346083801616474030">"Állítson be képernyőzárat"</string>
<string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Képernyőzár beállítása"</string>
- <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"A magánterület használatához állítson be képernyőzárat"</string>
+ <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"A privát terület használatához állítson be képernyőzárat"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string>
<string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> nem áll rendelkezése"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index d37993442bcf..a0e0bd218a18 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ձայնային օգնութ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Արգելափակում"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Նոր ծանուցում"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Ֆիզիկական ստեղնաշար"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Անվտանգություն"</string>
@@ -2394,7 +2396,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> դասավորությունները։ Հպեք փոխելու համար։"</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Ֆիզիկական ստեղնաշարերը կարգավորված են"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Հպեք՝ ստեղնաշարերը դիտելու համար"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Անձնական"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Մասնավոր"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Կլոն"</string>
<string name="profile_label_work" msgid="3495359133038584618">"Աշխատանքային"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Աշխատանքային 2"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Նորից կարգավորեք դեմքով ապակողպումը"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ձեր դեմքի նմուշը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը դեմքով ապակողպելու համար։"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Կարգավորել"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ոչ հիմա"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index e6634d23fd62..fb6180b0d126 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Bantuan Suara"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Kunci total"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Notifikasi baru"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Keyboard fisik"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Keamanan"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Penyiapan"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Lain kali"</string>
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index f77a18a3911b..3f96dae37c8d 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Raddaðstoð"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Læsing"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Ný tilkynning"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Vélbúnaðarlyklaborð"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Öryggi"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Í bið…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setja upp fingrafarskenni aftur"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 95ccad54d63f..f22b6531c66e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blocco"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nuova notifica"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tastiera fisica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sicurezza"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Non ora"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index fee437af96cf..3a924e1916c0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"האסיסטנט"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"נעילה"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"התראה חדשה"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"מקלדת פיזית"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"אבטחה"</string>
@@ -2395,7 +2397,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… אפשר להקיש כדי לשנות את ההגדרה הזו."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"הוגדרו מקלדות פיזיות"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"יש להקיש כדי להציג את המקלדות"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"פרטי"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"פרופיל פרטי"</string>
<string name="profile_label_clone" msgid="769106052210954285">"שכפול"</string>
<string name="profile_label_work" msgid="3495359133038584618">"פרופיל עבודה"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"פרופיל עבודה 2"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"הגדרה חוזרת של \'ביטול הנעילה בטביעת אצבע\'"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"הגדרה חוזרת של \'פתיחה ע\"י זיהוי הפנים\'"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"התבנית לזיהוי הפנים לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות זיהוי הפנים."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"הגדרה"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"לא עכשיו"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 726db1c4ea89..e31d79574841 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"音声アシスト"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ロックダウン"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"新しい通知"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"物理キーボード"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"セキュリティ"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"指紋認証をもう一度設定してください"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"顔認証をもう一度設定してください"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"顔モデルが正常に機能せず、削除されました。顔認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"後で"</string>
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index bdf6c489326b..a28471995d96 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ხმოვანი ასისტ."</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"დაბლოკვა"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"ახალი შეტყობინება"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ფიზიკური კლავიატურა"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"უსაფრთხოება"</string>
@@ -2394,7 +2396,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"დაყენდა კლავიატურის განლაგება: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… შეეხეთ შესაცვლელად."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ფიზიკური კლავიატურები კონფიგურირებულია"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"შეეხეთ კლავიატურების სანახავად"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"პირადი"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"კერძო"</string>
<string name="profile_label_clone" msgid="769106052210954285">"კლონი"</string>
<string name="profile_label_work" msgid="3495359133038584618">"სამსახური"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"სამსახური 2"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ანაბეჭდით განბლოკვის ხელახლა დაყენება"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"დააყენეთ სახით განბლოკვა ხელახლა"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"თქვენი სახის მოდელი კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი სახის საშუალებით განბლოკოთ."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"დაყენება"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ახლა არა"</string>
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 55cf92bb3280..e407c09b5a4e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Дауыс көмекшісі"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Құлыптау"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Жаңа хабарландыру"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физикалық пернетақта"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Қауіпсіздік"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Бет тану функциясын қайта реттеу"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Бет үлгісі дұрыс істемегендіктен жойылды. Телефонды бетпен ашу үшін оны қайта реттеңіз."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Реттеу"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Қазір емес"</string>
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 6a826db47006..4fe436890a22 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ជំនួយសម្លេង"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ការចាក់​សោ"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"ការជូនដំណឹងថ្មី"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ក្ដារចុច​រូបវន្ត"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"សុវត្ថិភាព"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"រៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"រៀបចំ​ការដោះ​សោ​ដោយស្កេន​មុខម្ដងទៀត"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"គំរូមុខរបស់អ្នកមិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើមុខ។"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"រៀបចំ"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"កុំទាន់"</string>
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 40d513893dda..3223c4089d68 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ಲಾಕ್‌ಡೌನ್‌"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"ಹೊಸ ನೋಟಿಫಿಕೇಶನ್‍"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ಭದ್ರತೆ"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫೇಸ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ಸೆಟಪ್ ಮಾಡಿ"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ಈಗ ಬೇಡ"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index dd476281eec9..7a8d324f0950 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"음성 지원"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"잠금"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"새 알림"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"물리적 키보드"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"보안"</string>
@@ -1388,7 +1390,7 @@
<string name="no_permissions" msgid="5729199278862516390">"권한 필요 없음"</string>
<string name="perm_costs_money" msgid="749054595022779685">"비용이 부과될 수 있습니다."</string>
<string name="dlg_ok" msgid="5103447663504839312">"확인"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"이 기기를 USB로 충전 중."</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"이 기기를 USB로 충전 중"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"USB를 통해 연결된 기기 충전"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB 파일 전송 사용 설정됨"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB를 통해 PTP 사용 설정됨"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"지문 잠금 해제 다시 설정"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"얼굴 인식 잠금 해제 다시 설정"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"얼굴 모델이 제대로 작동하지 않아 삭제되었습니다. 얼굴로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"설정"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"나중에"</string>
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index bb29c36a0410..8a233a3108a4 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Үн жардамчысы"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Бекем кулпулоо"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Жаңы эскертме"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Аппараттык баскычтоп"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Коопсуздук"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Жүзүңүздүн үлгүсү ойдогудай иштебегендиктен, жок кылынды. Телефондо Жүзүнөн таанып ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тууралоо"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Азыр эмес"</string>
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 5fa0fc135612..3e06b3da8ddc 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ຊ່ວຍ​ເຫຼືອ​ທາງ​ສຽງ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ລັອກໄວ້"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"ການແຈ້ງເຕືອນໃໝ່"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ແປ້ນພິມພາຍນອກ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ຄວາມປອດໄພ"</string>
@@ -2394,7 +2396,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ຕັ້ງໂຄງຮ່າງແປ້ນພິມເປັນ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… ແຕະເພື່ອປ່ຽນແປງ."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ຕັ້ງຄ່າແປ້ນພິມແທ້ແລ້ວ"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ແຕະເພື່ອເບິ່ງແປ້ນພິມ"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"ສ່ວນຕົວ"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"ສ່ວນບຸກຄົນ"</string>
<string name="profile_label_clone" msgid="769106052210954285">"ໂຄລນ"</string>
<string name="profile_label_work" msgid="3495359133038584618">"ວຽກ"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"ວຽກ 2"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືຄືນໃໝ່"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າຄືນໃໝ່"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ຮູບແບບໃບໜ້າຂອງທ່ານເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍໃບໜ້າ."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ຕັ້ງຄ່າ"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ບໍ່ຟ້າວເທື່ອ"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e06c2efe31b8..50572f80e723 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Užrakinimas"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Naujas pranešimas"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizinė klaviatūra"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sauga"</string>
@@ -2415,22 +2417,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Laukiama..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Atrakinimo piršto atspaudu nustatymas dar kartą"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nustatyti"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne dabar"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d2a6cd9af5a6..8be327da1aeb 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Balss palīgs"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloķēšana"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"Pārsniedz"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Jauns paziņojums"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fiziskā tastatūra"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Drošība"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Iestatīt"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne tagad"</string>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 796f9efe1bbc..680ff0a4b1b1 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -153,7 +153,7 @@
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> по <xliff:g id="TIME_DELAY">{2}</xliff:g> секунди"</string>
<string name="cfTemplateRegistered" msgid="5619930473441550596">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не е препратено"</string>
<string name="cfTemplateRegisteredTime" msgid="5222794399642525045">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не е проследен"</string>
- <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Безбедност на мобилна мрежа"</string>
+ <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>, мрежа во близина го сними уникатниот ID (IMSI или IMEI) на вашиот телефон со користење на вашата SIM-картичка на <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Гласовна помош"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Заклучување"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Ново известување"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физичка тастатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безбедност"</string>
@@ -2394,9 +2396,9 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Допрете за да промените."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичките тастатури се конфигурирани"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Допрете за да ги видите тастатурите"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Приватен профил"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Приватно"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Клониран профил"</string>
- <string name="profile_label_work" msgid="3495359133038584618">"Работен профил"</string>
+ <string name="profile_label_work" msgid="3495359133038584618">"Работно"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Работен профил 2"</string>
<string name="profile_label_work_3" msgid="4834572253956798917">"Работен профил 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Профил за тестирање"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Поставете „Отклучување со лик“ повторно"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Вашиот модел на лик не функционираше добро, па се избриша. Поставете го повторно за да го отклучите телефонот со лик."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Поставете"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index a0b4c8d80e96..eca7f28651e8 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"വോയ്‌സ് സഹായം"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ലോക്ക്‌ഡൗൺ"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"പുതിയ അറിയിപ്പ്"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ഫിസിക്കൽ കീബോഡ്"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"സുരക്ഷ"</string>
@@ -1904,8 +1906,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"നിങ്ങളുടെ അഡ്‌മിൻ അപ്‌ഡേറ്റ് ചെയ്യുന്നത്"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"നിങ്ങളുടെ അഡ്‌മിൻ ഇല്ലാതാക്കുന്നത്"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ശരി"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"\'ബാറ്ററി ലാഭിക്കൽ\' ഡാർക്ക് തീം ഓണാക്കുന്നു, ഒപ്പം പശ്ചാത്തല ആക്‌റ്റിവിറ്റിയും ചില വിഷ്വൽ ഇഫക്റ്റുകളും ചില ഫീച്ചറുകളും ചില നെറ്റ്‌വർക്ക് കണക്ഷനുകളും പരിമിതപ്പെടുത്തുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു."</string>
- <string name="battery_saver_description" msgid="8518809702138617167">"ബാറ്ററി ലാഭിക്കൽ ഡാർക്ക് തീം ഓണാക്കുന്നു, പശ്ചാത്തല ആക്‌റ്റിവിറ്റിയും ചില വിഷ്വൽ ഇഫക്റ്റുകളും ചില ഫീച്ചറുകളും ചില നെറ്റ്‌വർക്ക് കണക്ഷനുകളും അത് പരിമിതപ്പെടുത്തുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"\'ബാറ്ററി സേവർ\' ഡാർക്ക് തീം ഓണാക്കുന്നു, ഒപ്പം പശ്ചാത്തല ആക്‌റ്റിവിറ്റിയും ചില വിഷ്വൽ ഇഫക്റ്റുകളും ചില ഫീച്ചറുകളും ചില നെറ്റ്‌വർക്ക് കണക്ഷനുകളും പരിമിതപ്പെടുത്തുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു."</string>
+ <string name="battery_saver_description" msgid="8518809702138617167">"ബാറ്ററി സേവർ ഡാർക്ക് തീം ഓണാക്കുന്നു, പശ്ചാത്തല ആക്‌റ്റിവിറ്റിയും ചില വിഷ്വൽ ഇഫക്റ്റുകളും ചില ഫീച്ചറുകളും ചില നെറ്റ്‌വർക്ക് കണക്ഷനുകളും അത് പരിമിതപ്പെടുത്തുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു."</string>
<string name="data_saver_description" msgid="4995164271550590517">"ഡാറ്റാ ഉപയോഗം കുറയ്ക്കാൻ സഹായിക്കുന്നതിനായി പശ്ചാത്തലത്തിൽ ഡാറ്റ അയയ്ക്കുകയോ സ്വീകരിക്കുകയോ ചെയ്യുന്നതിൽ നിന്ന് ചില ആപ്പുകളെ ഡാറ്റാ സേവർ തടയുന്നു. നിങ്ങൾ നിലവിൽ ഉപയോഗിക്കുന്ന ഒരു ആപ്പിന് ഡാറ്റ ആക്‌സസ് ചെയ്യാനാകും, എന്നാൽ വല്ലപ്പോഴും മാത്രമെ സംഭവിക്കുന്നുള്ളു. ഇതിനർത്ഥം, ഉദാഹരണമായി നിങ്ങൾ ടാപ്പ് ചെയ്യുന്നത് വരെ ചിത്രങ്ങൾ പ്രദ‍‍‍ർശിപ്പിക്കുകയില്ല എന്നാണ്."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"ഡാറ്റാ സേവർ ഓണാക്കണോ?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"ഓണാക്കുക"</string>
@@ -2384,7 +2386,7 @@
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ഉപകരണത്തിന് ചൂട് കൂടുതലാണ്"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"നിങ്ങളുടെ ഫോൺ വളരെയധികം ചൂടാകുന്നതിനാൽ ഡ്യുവൽ സ്‌ക്രീൻ ലഭ്യമല്ല"</string>
<string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"ഡ്യുവൽ സ്‌ക്രീൻ ലഭ്യമല്ല"</string>
- <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"ബാറ്ററി ലാഭിക്കൽ ഓണായതിനാൽ ഡ്യുവൽ സ്‌ക്രീൻ ലഭ്യമല്ല. നിങ്ങൾക്ക് ഇത് ക്രമീകരണത്തിൽ ഓഫാക്കാം."</string>
+ <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"ബാറ്ററി സേവർ ഓണായതിനാൽ ഡ്യുവൽ സ്‌ക്രീൻ ലഭ്യമല്ല. നിങ്ങൾക്ക് ഇത് ക്രമീകരണത്തിൽ ഓഫാക്കാം."</string>
<string name="device_state_notification_settings_button" msgid="691937505741872749">"ക്രമീകരണത്തിലേക്ക് പോകുക"</string>
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ഓഫാക്കുക"</string>
<string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> കോൺഫിഗർ ചെയ്‌തു"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"നിങ്ങളുടെ മുഖ മോഡൽ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ മുഖം ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"സജ്ജീകരിക്കുക"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ഇപ്പോൾ വേണ്ട"</string>
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 5ba16fe87ffd..8d430eedc396 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Дуут туслах"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Түгжих"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Шинэ мэдэгдэл"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Биет гар"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Аюулгүй байдал"</string>
@@ -2394,7 +2396,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Гарын бүдүүвчийг <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> болгож тохируулсан… Өөрчлөхийн тулд товшино уу."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Биет гарыг тохируулсан"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Гарыг харахын тулд товшино уу"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Хувийн"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Хаалттай"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Клон"</string>
<string name="profile_label_work" msgid="3495359133038584618">"Ажил"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Ажил 2"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Царайгаар түгжээ тайлахыг дахин тохируулна уу"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Таны нүүрний загвар сайн ажиллахгүй байсан бөгөөд үүнийг устгасан. Утасныхаа түгжээг царайгаар тайлахын тулд нүүрний загварыг дахин тохируулна уу."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тохируулах"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Одоо биш"</string>
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 6c19cc592880..d5f2bae87f0d 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"व्हॉइस सहाय्य"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"लॉकडाउन"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"नवीन सूचना"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"वास्तविक कीबोर्ड"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"सुरक्षा"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिंट अनलॉक पुन्हा सेट करा"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलॉक पुन्हा सेट करा"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तुमचे फेस मॉडेल योग्यरीत्या काम करत नसल्यामुळे ते हटवले गेले आहे. तुमचा चेहरा वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट करा"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"आताच नको"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 82c1a5974c62..8018cb36741f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Bantuan Suara"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Kunci semua"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Pemberitahuan baharu"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Papan kekunci fizikal"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Keselamatan"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string>
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Sediakan Buka Kunci Cap Jari sekali lagi"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sediakan"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Bukan sekarang"</string>
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 43b7ffafd093..488bdb082f08 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"အသံ အကူအညီ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"လော့ခ်ဒေါင်း"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"၉၉၉+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"အကြောင်းကြားချက်အသစ်"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"စက်၏ ကီးဘုတ်"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"လုံခြုံရေး"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"သင့်မျက်နှာနမူနာ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို မျက်နှာဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"စနစ်ထည့်သွင်းရန်"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ယခုမလုပ်ပါ"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ad4ffc202466..3939f48b9265 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Talehjelp"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Låsing"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nytt varsel"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysisk tastatur"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Sikkerhet"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nå"</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 1cde247403c3..c16a02cb1278 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"आवाज सहायता"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"लकडाउन गर्नु…"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"९९९+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"नयाँ सूचना"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"फिजिकल किबोर्ड"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"सुरक्षा"</string>
@@ -873,30 +875,30 @@
<item msgid="4537253139152229577">"घरको फ्याक्स"</item>
<item msgid="6751245029698664340">"पेजर"</item>
<item msgid="1692790665884224905">"अन्य"</item>
- <item msgid="6216981255272016212">"आफू अनुकूल"</item>
+ <item msgid="6216981255272016212">" कस्टम"</item>
</string-array>
<string-array name="emailAddressTypes">
<item msgid="7786349763648997741">"गृह"</item>
<item msgid="435564470865989199">"काम"</item>
<item msgid="4199433197875490373">"अन्य"</item>
- <item msgid="3233938986670468328">"आफू अनुकूल"</item>
+ <item msgid="3233938986670468328">" कस्टम"</item>
</string-array>
<string-array name="postalAddressTypes">
<item msgid="3861463339764243038">"गृह"</item>
<item msgid="5472578890164979109">"काम"</item>
<item msgid="5718921296646594739">"अन्य"</item>
- <item msgid="5523122236731783179">"आफू अनुकूल"</item>
+ <item msgid="5523122236731783179">" कस्टम"</item>
</string-array>
<string-array name="imAddressTypes">
<item msgid="588088543406993772">"गृह"</item>
<item msgid="5503060422020476757">"काम"</item>
<item msgid="2530391194653760297">"अन्य"</item>
- <item msgid="7640927178025203330">"आफू अनुकूल"</item>
+ <item msgid="7640927178025203330">" कस्टम"</item>
</string-array>
<string-array name="organizationTypes">
<item msgid="6144047813304847762">"काम गर्नुहोस्"</item>
<item msgid="7402720230065674193">"अन्य"</item>
- <item msgid="808230403067569648">"आफू अनुकूल"</item>
+ <item msgid="808230403067569648">" कस्टम"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="7535761744432206400">"AIM"</item>
@@ -908,7 +910,7 @@
<item msgid="4717545739447438044">"ICQ"</item>
<item msgid="8293711853624033835">"Jabber"</item>
</string-array>
- <string name="phoneTypeCustom" msgid="5120365721260686814">"आफू अनुकूल"</string>
+ <string name="phoneTypeCustom" msgid="5120365721260686814">" कस्टम"</string>
<string name="phoneTypeHome" msgid="3880132427643623588">"गृह"</string>
<string name="phoneTypeMobile" msgid="1178852541462086735">"मोबाइल"</string>
<string name="phoneTypeWork" msgid="6604967163358864607">"काम"</string>
@@ -929,24 +931,24 @@
<string name="phoneTypeWorkPager" msgid="3748332310638505234">"कार्य पेजर"</string>
<string name="phoneTypeAssistant" msgid="757550783842231039">"सहायक"</string>
<string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
- <string name="eventTypeCustom" msgid="3257367158986466481">"आफू अनुकूल"</string>
+ <string name="eventTypeCustom" msgid="3257367158986466481">" कस्टम"</string>
<string name="eventTypeBirthday" msgid="7770026752793912283">"जन्मदिन"</string>
<string name="eventTypeAnniversary" msgid="4684702412407916888">"वार्षिक समारोह"</string>
<string name="eventTypeOther" msgid="530671238533887997">"अन्य"</string>
- <string name="emailTypeCustom" msgid="1809435350482181786">"आफू अनुकूल"</string>
+ <string name="emailTypeCustom" msgid="1809435350482181786">" कस्टम"</string>
<string name="emailTypeHome" msgid="1597116303154775999">"गृह"</string>
<string name="emailTypeWork" msgid="2020095414401882111">"काम"</string>
<string name="emailTypeOther" msgid="5131130857030897465">"अन्य"</string>
<string name="emailTypeMobile" msgid="787155077375364230">"मोबाइल"</string>
- <string name="postalTypeCustom" msgid="5645590470242939129">"आफू अनुकूल"</string>
+ <string name="postalTypeCustom" msgid="5645590470242939129">" कस्टम"</string>
<string name="postalTypeHome" msgid="7562272480949727912">"गृह"</string>
<string name="postalTypeWork" msgid="8553425424652012826">"काम"</string>
<string name="postalTypeOther" msgid="7094245413678857420">"अन्य"</string>
- <string name="imTypeCustom" msgid="5653384545085765570">"आफू अनुकूल"</string>
+ <string name="imTypeCustom" msgid="5653384545085765570">" कस्टम"</string>
<string name="imTypeHome" msgid="6996507981044278216">"गृह"</string>
<string name="imTypeWork" msgid="2099668940169903123">"काम"</string>
<string name="imTypeOther" msgid="8068447383276219810">"अन्य"</string>
- <string name="imProtocolCustom" msgid="4437878287653764692">"आफू अनुकूल"</string>
+ <string name="imProtocolCustom" msgid="4437878287653764692">" कस्टम"</string>
<string name="imProtocolAim" msgid="4050198236506604378">"AIM"</string>
<string name="imProtocolMsn" msgid="2257148557766499232">"Windows Live"</string>
<string name="imProtocolYahoo" msgid="5373338758093392231">"Yahoo"</string>
@@ -958,8 +960,8 @@
<string name="imProtocolNetMeeting" msgid="4985002408136148256">"NetMeeting"</string>
<string name="orgTypeWork" msgid="8684458700669564172">"काम"</string>
<string name="orgTypeOther" msgid="5450675258408005553">"अन्य"</string>
- <string name="orgTypeCustom" msgid="1126322047677329218">"आफू अनुकूल"</string>
- <string name="relationTypeCustom" msgid="282938315217441351">"आफू अनुकूल"</string>
+ <string name="orgTypeCustom" msgid="1126322047677329218">" कस्टम"</string>
+ <string name="relationTypeCustom" msgid="282938315217441351">" कस्टम"</string>
<string name="relationTypeAssistant" msgid="4057605157116589315">"सहायक"</string>
<string name="relationTypeBrother" msgid="7141662427379247820">"भाइ"</string>
<string name="relationTypeChild" msgid="9076258911292693601">"सन्तान"</string>
@@ -974,7 +976,7 @@
<string name="relationTypeRelative" msgid="3396498519818009134">"आफन्त"</string>
<string name="relationTypeSister" msgid="3721676005094140671">"बहिनी"</string>
<string name="relationTypeSpouse" msgid="6916682664436031703">"पति-पत्नी"</string>
- <string name="sipAddressTypeCustom" msgid="6283889809842649336">"आफू अनुकूल"</string>
+ <string name="sipAddressTypeCustom" msgid="6283889809842649336">" कस्टम"</string>
<string name="sipAddressTypeHome" msgid="5918441930656878367">"गृह"</string>
<string name="sipAddressTypeWork" msgid="7873967986701216770">"काम गर्नुहोस्"</string>
<string name="sipAddressTypeOther" msgid="6317012577345187275">"अन्य"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलक फेरि सेटअप गर्नुहोस्"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तपाईंको फेस मोडेलले राम्ररी काम गरिरहेको थिएन र त्यसलाई मेटाइयो। अनुहार प्रयोग गरी आफ्नो फोन अनलक गर्न फेस मोडेल फेरि सेट अप गर्नुहोस्।"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेटअप गर्नुहोस्"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अहिले होइन"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7bae96e6ab88..f8b0f9e12c36 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Spraakassistent"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Lockdown"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999 +"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nieuwe melding"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysiek toetsenbord"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Beveiliging"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ontgrendelen met vingerafdruk weer instellen"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Instellen"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Niet nu"</string>
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index c00998acbe16..9abed2b264f4 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ଭଏସ୍‌ ସହାୟକ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ଲକ୍ କରନ୍ତୁ"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"ନୂଆ ବିଜ୍ଞପ୍ତି"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ଫିଜିକଲ୍ କୀ’ବୋର୍ଡ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ସୁରକ୍ଷା"</string>
@@ -2144,7 +2146,7 @@
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ନିୟମିତ ମୋଡ୍‍ ସୂଚନା ବିଜ୍ଞପ୍ତି"</string>
<string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ବେଟେରୀ ସେଭର ଚାଲୁ କରାଯାଇଛି"</string>
<string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ବ୍ୟାଟେରୀ ଲାଇଫ ବଢ଼ାଇବା ପାଇଁ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କମ୍ କରିବା"</string>
- <string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଚାଲୁ‌ ଅଛି"</string>
+ <string name="dynamic_mode_notification_title_v2" msgid="5072385242078021152">"ବେଟେରୀ ସେଭର ଚାଲୁ ଅଛି"</string>
<string name="dynamic_mode_notification_summary_v2" msgid="2142444344663147938">"ବେଟେରୀ ଲାଇଫକୁ ବଢ଼ାଇବା ପାଇଁ ବେଟେରୀ ସେଭରକୁ ଚାଲୁ କରାଯାଇଛି"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ବେଟେରୀ ସେଭର"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"ବ୍ୟାଟେରୀ ସେଭର୍ ବନ୍ଦ ଅଛି"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ଫେସ୍ ଅନଲକ୍ ପୁଣି ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ଆପଣଙ୍କ ଫେସ ମଡେଲ ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଫେସ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ସେଟ ଅପ କରନ୍ତୁ"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 77020acff650..64b326c9f227 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ਲਾਕਡਾਊਨ"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"ਨਵੀਂ ਸੂਚਨਾ"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ਸੁਰੱਖਿਆ"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ਤੁਹਾਡਾ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਚਿਹਰੇ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ਸੈੱਟਅੱਪ ਕਰੋ"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ਹੁਣੇ ਨਹੀਂ"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0971ae40d500..9cc99166d98f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asystent głosowy"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blokada"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nowe powiadomienie"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Klawiatura fizyczna"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Bezpieczeństwo"</string>
@@ -2415,22 +2417,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Oczekiwanie…"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Skonfiguruj ponownie odblokowywanie odciskiem palca"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Skonfiguruj"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie teraz"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index b04cd4c6ed98..e3b49a0b399b 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ajuda de voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueio total"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova notificação"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurança"</string>
@@ -2395,7 +2397,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para mudar."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para conferir os teclados"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Particular"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Privado"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Clone"</string>
<string name="profile_label_work" msgid="3495359133038584618">"Trabalho"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Trabalho 2"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 90f9eda9c32e..d8c1f72fecb5 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Assist. de voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloquear"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova notificação"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurança"</string>
@@ -327,7 +329,7 @@
<string name="permgroupdesc_storage" msgid="5378659041354582769">"aceder aos ficheiros no seu dispositivo"</string>
<string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e áudio"</string>
<string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"aceder a música e áudio no seu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"fotos e vídeos"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
<string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"aceder a fotos e vídeos no seu dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar áudio"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a 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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configure o Desbloqueio por impressão digital novamente"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index b04cd4c6ed98..e3b49a0b399b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ajuda de voz"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueio total"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nova notificação"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Teclado físico"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Segurança"</string>
@@ -2395,7 +2397,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para mudar."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para conferir os teclados"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Particular"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Privado"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Clone"</string>
<string name="profile_label_work" msgid="3495359133038584618">"Trabalho"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Trabalho 2"</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c43df4fa6e41..7de995219497 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistent vocal"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blocare strictă"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"˃999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificare nouă"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tastatură fizică"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Securitate"</string>
@@ -2414,22 +2416,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string>
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurează"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nu acum"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 32a2338b284d..d999bf5b2050 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Аудиоподсказки"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Блокировка входа"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt;999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Новое уведомление"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физическая клавиатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безопасность"</string>
@@ -668,7 +670,7 @@
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечаток не распознан."</string>
<string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Отпечаток не распознан."</string>
- <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"Лицо не распознано. Используйте отпечаток."</string>
+ <string name="fingerprint_dialog_use_fingerprint_instead" msgid="5590293588784953188">"Лицо не распознано. Сканируйте отпечаток пальца."</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечаток пальца проверен"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицо распознано"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицо распознано, нажмите кнопку \"Подтвердить\""</string>
@@ -2396,7 +2398,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Настроены раскладки клавиатуры для яз.: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> и др. Нажмите, чтобы изменить."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физические клавиатуры настроены"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Нажмите, чтобы посмотреть подключенные клавиатуры."</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Личный"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Частный"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Клон"</string>
<string name="profile_label_work" msgid="3495359133038584618">"Рабочий"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Рабочий 2"</string>
@@ -2415,22 +2417,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Настройте фейсконтроль заново"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель лица оказалась неудачной и была удалена. Чтобы пользоваться фейсконтролем, настройте его заново."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настроить"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сейчас"</string>
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 9539cef0f26c..a8eda4f65c7e 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"හඬ සහායක"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"අගුලු දැමීම"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"නව දැනුම්දීම"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"භෞතික යතුරු පුවරුව"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ආරක්ෂාව"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"මුහුණෙන් අගුලු හැරීම නැවත සකසන්න"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ඔබේ මුහුණු මාදිලිය හොඳින් ක්‍රියා නොකරයි, එය මකන ලදි. මුහුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"සකසන්න"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"දැන් නොවේ"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index c72a426d0436..46897cbbf7cb 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Hlasový asistent"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Uzamknúť"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Nové upozornenie"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyzická klávesnica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Zabezpečenie"</string>
@@ -2415,22 +2417,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastaviť"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teraz nie"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e1be803cce1b..2f10d584fed9 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Glas. pomočnik"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Zakleni"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999 +"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Novo obvestilo"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fizična tipkovnica"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Varnost"</string>
@@ -1733,7 +1735,7 @@
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ogledovanje in upravljanje zaslona"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Bere lahko vso vsebino na zaslonu ter prikaže vsebino prek drugih aplikacij."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Ogledovanje in izvajanje dejanj"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali tipalom strojne opreme ter komunicira z aplikacijami v vašem imenu."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali tipalom ter komunicira z aplikacijami v vašem imenu."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dovoli"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zavrni"</string>
<string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Odmesti"</string>
@@ -2415,22 +2417,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"V teku …"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vnovična nastavitev odklepanja s prstnim odtisom"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavi"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne zdaj"</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 4d79ce707787..70980b61e972 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ndihma zanore"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Blloko"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Njoftim i ri"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tastiera fizike"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Siguria"</string>
@@ -2415,9 +2417,9 @@
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
<!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
<skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
<!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
<skip />
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 95ccead79ce2..86387c95f727 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -284,6 +284,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Гласовна помоћ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Закључавање"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Ново обавештење"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физичка тастатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безбедност"</string>
@@ -835,11 +837,11 @@
<string name="policylab_watchLogin" msgid="7599669460083719504">"Надзор покушаја откључавања екрана"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Прати број нетачно унетих лозинки приликом откључавања екрана и закључава таблет или брише податке са таблета ако је нетачна лозинка унета превише пута."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке са Android TV уређаја ако се унесе превише нетачних лозинки."</string>
- <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Прати број нетачно унетих лозинки при откључавању екрана и закључава систем за инфо-забаву или брише све податке са система за инфо-забаву ако је нетачна лозинка унета превише пута."</string>
+ <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Прати број нетачно унетих лозинки при откључавању екрана и закључава систем за информације и забаву или брише све податке са система за информације и забаву ако је нетачна лозинка унета превише пута."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Прати број нетачно унетих лозинки при откључавању екрана и закључава телефон или брише све податке са телефона ако је нетачна лозинка унета превише пута."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава таблет или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава систем за инфо-забаву или брише све податке овог профила ако се унесе превише нетачних лозинки."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава систем за информације и забаву или брише све податке овог профила ако се унесе превише нетачних лозинки."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава телефон или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"Промена закључавања екрана"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Мења откључавање екрана."</string>
@@ -848,13 +850,13 @@
<string name="policylab_wipeData" msgid="1359485247727537311">"Брисање свих података"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Брисање података на таблету без упозорења ресетовањем на фабричка подешавања."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Брише податке Android TV уређаја без упозорења помоћу ресетовања на фабричка подешавања."</string>
- <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Брише податке на систему за инфо-забаву без упозорења ресетовањем на фабричка подешавања."</string>
+ <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Брише податке на систему за информације и забаву без упозорења ресетовањем на фабричка подешавања."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Брисање података на телефону без упозорења ресетовањем на фабричка подешавања."</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Брисање података профила"</string>
<string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Обриши податке корисника"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Брише податке овог корисника на овом таблету без упозорења."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Брише податке овог корисника на овом Android TV уређају без упозорења."</string>
- <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Брише податке овог профила на овом систему за инфо-забаву без упозорења."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Брише податке овог профила на овом систему за информације и забаву без упозорења."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Брише податке овог корисника на овом телефону без упозорења."</string>
<string name="policylab_setGlobalProxy" msgid="215332221188670221">"Подесите глобални прокси сервер уређаја"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Подешава глобални прокси уређаја који ће се користити док су смернице омогућене. Само власник уређаја може да подеси глобални прокси."</string>
@@ -2414,22 +2416,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поново подесите откључавање отиском прста"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Поново подесите откључавање лицем"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ваш модел лица није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали лицем."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Подеси"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сада"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0cbdda1a4c27..6c15ad8ff76f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Låsning"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Ny avisering"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysiskt tangentbord"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Säkerhet"</string>
@@ -623,12 +625,12 @@
<string name="permdesc_postNotification" msgid="5974977162462877075">"Tillåter att appen visar aviseringar"</string>
<string name="permlab_turnScreenOn" msgid="219344053664171492">"Slå på skärmen"</string>
<string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tillåter att appen slår på skärmen."</string>
- <string name="permlab_useBiometric" msgid="6314741124749633786">"använd biometrisk maskinvara"</string>
- <string name="permdesc_useBiometric" msgid="7502858732677143410">"Tillåter att appen använder biometrisk maskinvara vid autentisering"</string>
- <string name="permlab_manageFingerprint" msgid="7432667156322821178">"hantera maskinvara för fingeravtryck"</string>
+ <string name="permlab_useBiometric" msgid="6314741124749633786">"använd biometrisk hårdvara"</string>
+ <string name="permdesc_useBiometric" msgid="7502858732677143410">"Tillåter att appen använder biometrisk hårdvara vid autentisering"</string>
+ <string name="permlab_manageFingerprint" msgid="7432667156322821178">"hantera hårdvara för fingeravtryck"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Tillåter att appen anropar metoder för att lägga till och radera fingeravtrycksmallar."</string>
- <string name="permlab_useFingerprint" msgid="1001421069766751922">"använda maskinvara för fingeravtryck"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"Tillåter att appen använder maskinvara för fingeravtryck vid autentisering"</string>
+ <string name="permlab_useFingerprint" msgid="1001421069766751922">"använda hårdvara för fingeravtryck"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"Tillåter att appen använder hårdvara för fingeravtryck vid autentisering"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"göra ändringar i din musiksamling"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"Tillåter att appen gör ändringar i din musiksamling."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"göra ändringar i din videosamling"</string>
@@ -642,7 +644,7 @@
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiera din identitet"</string>
<string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Fortsätt med hjälp av din biometriska data"</string>
<string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Fortsätt med hjälp av din biometriska data eller skärmlåset"</string>
- <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvara är inte tillgänglig"</string>
+ <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk hårdvara är inte tillgänglig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen avbröts"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Identifierades inte"</string>
<string name="biometric_face_not_recognized" msgid="5535599455744525200">"Ansiktet känns inte igen"</string>
@@ -670,7 +672,7 @@
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrycket har autentiserats"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet har autentiserats"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet har autentiserats. Tryck på Bekräfta"</string>
- <string name="fingerprint_error_hw_not_available" msgid="7755729484334001137">"Det finns ingen maskinvara för fingeravtryck"</string>
+ <string name="fingerprint_error_hw_not_available" msgid="7755729484334001137">"Det finns ingen hårdvara för fingeravtryck"</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"Det gick inte att konfigurera fingeravtryck"</string>
<string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tiden för fingeravtrycksinställning gick ut. Försök igen."</string>
<string name="fingerprint_error_canceled" msgid="5541771463159727513">"Fingeravtrycksåtgärden avbröts"</string>
@@ -732,7 +734,7 @@
<string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Något täcker ansiktet. Hela ansiktet måste synas."</string>
<string-array name="face_acquired_vendor">
</string-array>
- <string name="face_error_hw_not_available" msgid="5085202213036026288">"Ansiktsverifiering går ej. Otillgänglig maskinvara."</string>
+ <string name="face_error_hw_not_available" msgid="5085202213036026288">"Ansiktsverifiering går ej. Otillgänglig hårdvara."</string>
<string name="face_error_timeout" msgid="2598544068593889762">"Försök att använda ansiktslåset igen"</string>
<string name="face_error_no_space" msgid="5649264057026021723">"Kan inte lagra ny ansiktsdata. Radera först gammal data."</string>
<string name="face_error_canceled" msgid="2164434737103802131">"Ansiktsåtgärden har avbrutits."</string>
@@ -1731,7 +1733,7 @@
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Visa och styra skärmen"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Den kan läsa allt innehåll på skärmen och visa innehåll över andra appar."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Visa och vidta åtgärder"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Den kan registrera din användning av en app eller maskinvarusensor och interagera med appar åt dig."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Den kan registrera din användning av en app eller hårdvarusensor och interagera med appar åt dig."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Tillåt"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Neka"</string>
<string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Avinstallera"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Väntar …"</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurera fingeravtryckslås igen"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 10f55af3dc47..1437a3830d44 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Usaidizi wa Sauti"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Funga"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Arifa mpya"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Kibodi halisi"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Usalama"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Weka mipangilio"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Si sasa"</string>
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 466e29a7e9b1..231b14c6a94d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"குரல் உதவி"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"பூட்டு"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"புதிய அறிவிப்பு"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"கைமுறை கீபோர்டு"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"பாதுகாப்பு"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"\'முகம் காட்டித் திறத்தல்\' அம்சத்தை மீண்டும் அமையுங்கள்"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"உங்கள் முகத் தோற்றப் பதிவு சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது. உங்கள் முகத்தைப் பயன்படுத்தி மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"அமை"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"இப்போது வேண்டாம்"</string>
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index db75aac8b027..cf4e19408909 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"వాయిస్ అసిస్టెంట్"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"లాక్ చేయండి"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"కొత్త నోటిఫికేషన్"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"భౌతిక కీబోర్డ్"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"సెక్యూరిటీ"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ఫేస్ అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"మీ ఫేస్ మోడల్ సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. ఫేస్‌తో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"సెటప్ చేయండి"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ఇప్పుడు కాదు"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 284a5f273f22..59809c92ed96 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ตัวช่วยเสียง"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ปิดล็อก"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"การแจ้งเตือนใหม่"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"แป้นพิมพ์จริง"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ความปลอดภัย"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"รูปแบบใบหน้าของคุณทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยใบหน้า"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ตั้งค่า"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ไว้ทีหลัง"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4dd488681f5b..7ba81ad9b55e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"I-lockdown"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Bagong notification"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Pisikal na keyboard"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Seguridad"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nakabinbin..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"I-set up ulit ang Pag-unlock Gamit ang Fingerprint"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 2b616defdaa6..64498b524b24 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Sesli Yardım"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Tam kilitleme"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Yeni bildirim"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fiziksel klavye"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Güvenlik"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarla"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Şimdi değil"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 850e21b15ef9..fcea7bb43e01 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -285,6 +285,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Голос. підказки"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Блокування"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Нове сповіщення"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Фізична клавіатура"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Безпека"</string>
@@ -2415,22 +2417,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"Налаштуйте фейс-контроль повторно"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель обличчя працювала неналежним чином, і її видалено. Налаштуйте її ще раз, щоб розблоковувати телефон за допомогою фейс-контролю."</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Налаштувати"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index d3fde3c4f455..fc23d99d03d8 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Voice Assist"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"مقفل"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"‎999+‎"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"نئی اطلاع"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"فزیکل کی بورڈ"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"سیکیورٹی"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"فیس اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"آپ کے چہرے کا ماڈل اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو چہرے سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"سیٹ اپ کریں"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ابھی نہیں"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index c143244db230..0ef4ddc4cc0b 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Ovozli yordam"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Qulflash"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Yangi bildirishnoma"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Tashqi klaviatura"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Xavfsizlik"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Kutilmoqda..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmoq izi bilan ochish funksiyasini qayta sozlang"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sozlash"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hozir emas"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a0775d400d5d..6ff6528878e3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Trợ lý thoại"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Khóa"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Thông báo mới"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Bàn phím vật lý"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Bảo mật"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string>
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <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>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="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>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 00dd3db2b35a..10243220d600 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"语音助理"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"锁定"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"新通知"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"实体键盘"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"安全性"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新设置指纹解锁功能"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"重新设置“人脸解锁”功能"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"您的脸部模型无法正常使用,系统已将其删除。如要通过人脸解锁功能来解锁手机,请重新设置。"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"设置"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"以后再说"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 142940a86ebb..b1157f7df6d5 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"語音助手"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"鎖定"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"新通知"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"實體鍵盤"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"安全性"</string>
@@ -651,11 +653,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"請用力按住感應器"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"請按住感應器"</string>
<string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"無法辨識指紋,請再試一次。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"請清潔感應器,然後再試一次"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"請用力按住感應器"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"請按住感應器"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移動太慢,請重試。"</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"重新設定「面孔解鎖」功能"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"由於面部模型無法正常運作,因此系統已將其刪除。請重新設定,才能使用面孔解鎖手機。"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index b7ee23c23f21..da43a12f8fe1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"語音小幫手"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"鎖定"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"超過 999"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"新通知"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"實體鍵盤"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"安全性"</string>
@@ -2413,22 +2415,15 @@
<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>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="face_dangling_notification_title" msgid="947852541060975473">"重新設定人臉解鎖"</string>
+ <string name="face_dangling_notification_msg" msgid="8806849376915541655">"臉部模型無法正常運作,因此系統已將其刪除。請重新設定,才能用臉解鎖手機。"</string>
+ <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a967fb6f1ad1..7749b1b6f04c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -283,6 +283,8 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"Isisekeli sezwi"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"Khiya"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
+ <!-- no translation found for notification_compact_heads_up_reply (2425293958371284340) -->
+ <skip />
<string name="notification_hidden_text" msgid="2835519769868187223">"Isaziso esisha"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Ikhibhodi ephathekayo"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Ukuphepha"</string>
@@ -2413,22 +2415,15 @@
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
- <!-- no translation found for fingerprint_dangling_notification_title (7362075195588639989) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_1 (6261149111900787302) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_2 (7688302770424064884) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_1 (2927018569542316055) -->
- <skip />
- <!-- no translation found for fingerprint_dangling_notification_msg_all_deleted_2 (6897989352716156176) -->
- <skip />
- <!-- no translation found for face_dangling_notification_title (947852541060975473) -->
- <skip />
- <!-- no translation found for face_dangling_notification_msg (8806849376915541655) -->
- <skip />
- <!-- no translation found for biometric_dangling_notification_action_set_up (8246885009807817961) -->
+ <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
+ <!-- no translation found for fingerprint_dangling_notification_msg_1 (8517140433796229725) -->
<skip />
- <!-- no translation found for biometric_dangling_notification_action_not_now (8095249216864443491) -->
+ <!-- no translation found for fingerprint_dangling_notification_msg_2 (7578829498452127613) -->
<skip />
+ <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="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="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setha"</string>
+ <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hhayi manje"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5fa13bab7b0c..405324bf76af 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2589,6 +2589,8 @@
<li>The framework will set {@link android.R.attr#statusBarColor},
{@link android.R.attr#navigationBarColor}, and
{@link android.R.attr#navigationBarDividerColor} to transparent.
+ <li>The frameworks will send Configuration no longer considering system insets.
+ The Configuration will be stable regardless of the system insets change.
</ul>
<p>If this is true, the edge-to-edge enforcement won't be applied. However, this
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5bd20332f381..0676f721c469 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4723,6 +4723,8 @@
<!-- The broadcast intent name for notifying when the on-device model has been unloaded -->
<string name="config_onDeviceIntelligenceModelUnloadedBroadcastKey" translatable="false"></string>
+ <!-- The DeviceConfig namespace for the default system on-device sandboxed inference service. -->
+ <string name="config_defaultOnDeviceIntelligenceDeviceConfigNamespace" translatable="false"></string>
<!-- Component name that accepts ACTION_SEND intents for requesting ambient context consent for
wearable sensing. -->
@@ -6951,9 +6953,6 @@
an app is not changed during subsequent reboots. -->
<bool name="config_stopSystemPackagesByDefault">true</bool>
- <!-- Whether to show weather on the lock screen by default. -->
- <bool name="config_lockscreenWeatherEnabledByDefault">false</bool>
-
<!-- Whether we should persist the brightness value in nits for the default display even if
the underlying display device changes. -->
<bool name="config_persistBrightnessNitsForDefaultDisplay">false</bool>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index cc02a7e377c5..e420ffe68e4c 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -365,4 +365,23 @@
<item>xcap</item>
</string-array>
<java-symbol type="array" name="config_force_cellular_transport_capabilities" />
+
+ <!-- The time duration in millis after which DemoSimulator will move to CONNECTED state from
+ NOT_CONNECTED state if the device is aligned to satellite.
+ -->
+ <integer name="config_demo_pointing_aligned_duration_millis">15000</integer>
+ <java-symbol type="integer" name="config_demo_pointing_aligned_duration_millis" />
+
+ <!-- The time duration in millis after which DemoSimulator will move to NOT_CONNECTED state from
+ CONNECTED state if the device is not aligned to satellite.
+ -->
+ <integer name="config_demo_pointing_not_aligned_duration_millis">30000</integer>
+ <java-symbol type="integer" name="config_demo_pointing_not_aligned_duration_millis" />
+
+ <!-- Boolean indicating whether Telephony should wait for device alignment with satellite
+ before sending or receiving datagrams in demo mode.
+ -->
+ <bool name="config_wait_for_device_alignment_in_demo_datagram">false</bool>
+ <java-symbol type="bool" name="config_wait_for_device_alignment_in_demo_datagram" />
+
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 52ce9936787f..b885e03bc098 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -846,6 +846,12 @@
<dimen name="conversation_face_pile_protection_width">2dp</dimen>
<!-- The width of the protection of the face pile layout when expanded-->
<dimen name="conversation_face_pile_protection_width_expanded">@dimen/conversation_face_pile_protection_width</dimen>
+ <!-- size of the compact face pile -->
+ <dimen name="conversation_compact_face_pile_size">24dp</dimen>
+ <!-- size of the face pile avatar -->
+ <dimen name="conversation_compact_face_pile_avatar_size">17dp</dimen>
+ <!-- size of the face pile protection -->
+ <dimen name="conversation_compact_face_pile_protection_width">1dp</dimen>
<!-- The padding of the expanded message container-->
<dimen name="expanded_group_conversation_message_padding">32dp</dimen>
<!-- The stroke width of the ring used to visually mark a conversation as important -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 28678c1c5fb0..2da5e9a90dbb 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6491,9 +6491,9 @@ ul.</string>
<!-- Fingerprint dangling notification title -->
<string name="fingerprint_dangling_notification_title">Set up Fingerprint Unlock again</string>
<!-- Fingerprint dangling notification content for only 1 fingerprint deleted -->
- <string name="fingerprint_dangling_notification_msg_1"><xliff:g id="fingerprint">%s</xliff:g> wasn\'t working well and was deleted to improve performance</string>
+ <string name="fingerprint_dangling_notification_msg_1"><xliff:g id="fingerprint">%s</xliff:g> wasn\'t working well and was deleted</string>
<!-- Fingerprint dangling notification content for more than 1 fingerprints deleted -->
- <string name="fingerprint_dangling_notification_msg_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> weren\'t working well and were deleted to improve performance</string>
+ <string name="fingerprint_dangling_notification_msg_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> weren\'t working well and were deleted</string>
<!-- Fingerprint dangling notification content for only 1 fingerprint deleted and no fingerprint left-->
<string name="fingerprint_dangling_notification_msg_all_deleted_1"><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>
<!-- Fingerprint dangling notification content for more than 1 fingerprints deleted and no fingerprint left -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index acd3b372b3ae..5a3eaeb8327b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3947,6 +3947,7 @@
<java-symbol type="string" name="config_defaultOnDeviceSandboxedInferenceService" />
<java-symbol type="string" name="config_onDeviceIntelligenceModelLoadedBroadcastKey" />
<java-symbol type="string" name="config_onDeviceIntelligenceModelUnloadedBroadcastKey" />
+ <java-symbol type="string" name="config_defaultOnDeviceIntelligenceDeviceConfigNamespace" />
<java-symbol type="string" name="config_retailDemoPackage" />
<java-symbol type="string" name="config_retailDemoPackageSignature" />
@@ -4542,6 +4543,9 @@
<java-symbol type="dimen" name="conversation_avatar_size_group_expanded" />
<java-symbol type="dimen" name="conversation_face_pile_avatar_size" />
<java-symbol type="dimen" name="conversation_face_pile_avatar_size_group_expanded" />
+ <java-symbol type="dimen" name="conversation_compact_face_pile_size" />
+ <java-symbol type="dimen" name="conversation_compact_face_pile_avatar_size" />
+ <java-symbol type="dimen" name="conversation_compact_face_pile_protection_width" />
<java-symbol type="dimen" name="conversation_face_pile_protection_width" />
<java-symbol type="dimen" name="conversation_face_pile_protection_width_expanded" />
<java-symbol type="dimen" name="conversation_badge_protrusion_group_expanded" />
@@ -5224,9 +5228,6 @@
<java-symbol type="bool" name="config_hotspotNetworksEnabledForService"/>
<java-symbol type="bool" name="config_knownNetworksEnabledForService"/>
- <!-- Whether to show weather on the lockscreen by default. -->
- <java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" />
-
<!-- For keyboard notification -->
<java-symbol type="string" name="keyboard_layout_notification_selected_title"/>
<java-symbol type="string" name="keyboard_layout_notification_one_selected_message"/>
diff --git a/graphics/java/android/graphics/fonts/FontFamily.java b/graphics/java/android/graphics/fonts/FontFamily.java
index bd1327657fb0..5a7b0bbca399 100644
--- a/graphics/java/android/graphics/fonts/FontFamily.java
+++ b/graphics/java/android/graphics/fonts/FontFamily.java
@@ -25,6 +25,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.text.FontConfig;
import android.util.SparseIntArray;
@@ -151,6 +152,7 @@ public final class FontFamily {
* @return A variable font family. null if a variable font cannot be built from the given
* fonts.
*/
+ @SuppressLint("BuilderSetStyle")
@FlaggedApi(FLAG_NEW_FONTS_FALLBACK_XML)
public @Nullable FontFamily buildVariableFamily() {
int variableFamilyType = analyzeAndResolveVariableType(mFonts);
diff --git a/graphics/java/android/graphics/text/LineBreakConfig.java b/graphics/java/android/graphics/text/LineBreakConfig.java
index 7d55928aa656..5a1086cef407 100644
--- a/graphics/java/android/graphics/text/LineBreakConfig.java
+++ b/graphics/java/android/graphics/text/LineBreakConfig.java
@@ -23,6 +23,7 @@ import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.app.ActivityThread;
import android.os.Build;
import android.os.LocaleList;
@@ -314,6 +315,7 @@ public final class LineBreakConfig implements Parcelable {
* @param config an override line break config
* @return This {@code Builder}.
*/
+ @SuppressLint("BuilderSetStyle")
@FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
public @NonNull Builder merge(@NonNull LineBreakConfig config) {
if (config.mLineBreakStyle != LINE_BREAK_STYLE_UNSPECIFIED) {
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 1fbaeeac8608..29936cc2cac3 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -33,7 +33,9 @@ import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSI
import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
-import android.annotation.DimenRes;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityThread;
@@ -53,9 +55,11 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
+import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
+import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.window.InputTransferToken;
@@ -97,6 +101,16 @@ class DividerPresenter implements View.OnTouchListener {
@VisibleForTesting
static final int DEFAULT_DIVIDER_WIDTH_DP = 24;
+ @VisibleForTesting
+ static final PathInterpolator FLING_ANIMATION_INTERPOLATOR =
+ new PathInterpolator(0.4f, 0f, 0.2f, 1f);
+ @VisibleForTesting
+ static final int FLING_ANIMATION_DURATION = 250;
+ @VisibleForTesting
+ static final int MIN_DISMISS_VELOCITY_DP_PER_SECOND = 600;
+ @VisibleForTesting
+ static final int MIN_FLING_VELOCITY_DP_PER_SECOND = 400;
+
private final int mTaskId;
@NonNull
@@ -109,6 +123,14 @@ class DividerPresenter implements View.OnTouchListener {
private final Executor mCallbackExecutor;
/**
+ * The VelocityTracker of the divider, used to track the dragging velocity. This field is
+ * {@code null} until dragging starts.
+ */
+ @GuardedBy("mLock")
+ @Nullable
+ VelocityTracker mVelocityTracker;
+
+ /**
* The {@link Properties} of the divider. This field is {@code null} when no divider should be
* drawn, e.g. when the split doesn't have {@link DividerAttributes} or when the decor surface
* is not available.
@@ -370,13 +392,11 @@ class DividerPresenter implements View.OnTouchListener {
applicationContext.getResources().getDisplayMetrics());
}
- private static int getDimensionDp(@DimenRes int resId) {
- final Context context = ActivityThread.currentActivityThread().getApplication();
- final int px = context.getResources().getDimensionPixelSize(resId);
- return (int) TypedValue.convertPixelsToDimension(
- COMPLEX_UNIT_DIP,
- px,
- context.getResources().getDisplayMetrics());
+ private static float getDisplayDensity() {
+ // TODO(b/329193115) support divider on secondary display
+ final Context applicationContext =
+ ActivityThread.currentActivityThread().getApplication();
+ return applicationContext.getResources().getDisplayMetrics().density;
}
/**
@@ -487,24 +507,27 @@ class DividerPresenter implements View.OnTouchListener {
@Override
public boolean onTouch(@NonNull View view, @NonNull MotionEvent event) {
synchronized (mLock) {
- final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
- mDividerPosition = calculateDividerPosition(
- event, taskBounds, mRenderer.mDividerWidthPx, mProperties.mDividerAttributes,
- mProperties.mIsVerticalSplit, calculateMinPosition(), calculateMaxPosition());
- mRenderer.setDividerPosition(mDividerPosition);
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- onStartDragging();
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- onFinishDragging();
- break;
- case MotionEvent.ACTION_MOVE:
- onDrag();
- break;
- default:
- break;
+ if (mProperties != null && mRenderer != null) {
+ final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
+ mDividerPosition = calculateDividerPosition(
+ event, taskBounds, mRenderer.mDividerWidthPx,
+ mProperties.mDividerAttributes, mProperties.mIsVerticalSplit,
+ calculateMinPosition(), calculateMaxPosition());
+ mRenderer.setDividerPosition(mDividerPosition);
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ onStartDragging(event);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ onFinishDragging(event);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ onDrag(event);
+ break;
+ default:
+ break;
+ }
}
}
@@ -514,7 +537,10 @@ class DividerPresenter implements View.OnTouchListener {
}
@GuardedBy("mLock")
- private void onStartDragging() {
+ private void onStartDragging(@NonNull MotionEvent event) {
+ mVelocityTracker = VelocityTracker.obtain();
+ mVelocityTracker.addMovement(event);
+
mRenderer.mIsDragging = true;
mRenderer.mDragHandle.setPressed(mRenderer.mIsDragging);
mRenderer.updateSurface();
@@ -536,16 +562,81 @@ class DividerPresenter implements View.OnTouchListener {
}
@GuardedBy("mLock")
- private void onDrag() {
+ private void onDrag(@NonNull MotionEvent event) {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.addMovement(event);
+ }
mRenderer.updateSurface();
}
@GuardedBy("mLock")
- private void onFinishDragging() {
- mDividerPosition = adjustDividerPositionForSnapPoints(mDividerPosition);
- mRenderer.setDividerPosition(mDividerPosition);
+ private void onFinishDragging(@NonNull MotionEvent event) {
+ float velocity = 0.0f;
+ if (mVelocityTracker != null) {
+ mVelocityTracker.addMovement(event);
+ mVelocityTracker.computeCurrentVelocity(1000 /* units */);
+ velocity = mProperties.mIsVerticalSplit
+ ? mVelocityTracker.getXVelocity()
+ : mVelocityTracker.getYVelocity();
+ mVelocityTracker.recycle();
+ }
+
+ final int prevDividerPosition = mDividerPosition;
+ mDividerPosition = dividerPositionForSnapPoints(mDividerPosition, velocity);
+ if (mDividerPosition != prevDividerPosition) {
+ ValueAnimator animator = getFlingAnimator(prevDividerPosition, mDividerPosition);
+ animator.start();
+ } else {
+ onDraggingEnd();
+ }
+ }
+
+ @GuardedBy("mLock")
+ @NonNull
+ @VisibleForTesting
+ ValueAnimator getFlingAnimator(int prevDividerPosition, int snappedDividerPosition) {
+ final ValueAnimator animator =
+ getValueAnimator(prevDividerPosition, snappedDividerPosition);
+ animator.addUpdateListener(animation -> {
+ synchronized (mLock) {
+ updateDividerPosition((int) animation.getAnimatedValue());
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ synchronized (mLock) {
+ onDraggingEnd();
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ synchronized (mLock) {
+ onDraggingEnd();
+ }
+ }
+ });
+ return animator;
+ }
+
+ @VisibleForTesting
+ static ValueAnimator getValueAnimator(int prevDividerPosition, int snappedDividerPosition) {
+ ValueAnimator animator = ValueAnimator
+ .ofInt(prevDividerPosition, snappedDividerPosition)
+ .setDuration(FLING_ANIMATION_DURATION);
+ animator.setInterpolator(FLING_ANIMATION_INTERPOLATOR);
+ return animator;
+ }
+
+ @GuardedBy("mLock")
+ private void updateDividerPosition(int position) {
+ mRenderer.setDividerPosition(position);
mRenderer.updateSurface();
+ }
+ @GuardedBy("mLock")
+ private void onDraggingEnd() {
// Veil visibility change should be applied together with the surface boost transaction in
// the wct.
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
@@ -570,36 +661,76 @@ class DividerPresenter implements View.OnTouchListener {
/**
* Returns the divider position adjusted for the min max ratio and fullscreen expansion.
- *
- * If the dragging position is above the {@link DividerAttributes#getPrimaryMaxRatio()} or below
- * {@link DividerAttributes#getPrimaryMinRatio()} and
- * {@link DividerAttributes#isDraggingToFullscreenAllowed} is {@code true}, the system will
- * choose a snap algorithm to adjust the ending position to either fully expand one container or
- * move the divider back to the specified min/max ratio.
- *
- * TODO(b/327067596) implement snap algorithm
- *
* The adjusted divider position is in the range of [minPosition, maxPosition] for a split, 0
* for expanded right (bottom) container, or task width (height) minus the divider width for
* expanded left (top) container.
*/
@GuardedBy("mLock")
- private int adjustDividerPositionForSnapPoints(int dividerPosition) {
+ private int dividerPositionForSnapPoints(int dividerPosition, float velocity) {
final Rect taskBounds = mProperties.mConfiguration.windowConfiguration.getBounds();
final int minPosition = calculateMinPosition();
final int maxPosition = calculateMaxPosition();
final int fullyExpandedPosition = mProperties.mIsVerticalSplit
? taskBounds.right - mRenderer.mDividerWidthPx
: taskBounds.bottom - mRenderer.mDividerWidthPx;
+
if (isDraggingToFullscreenAllowed(mProperties.mDividerAttributes)) {
- if (dividerPosition < minPosition) {
- return 0;
+ final float displayDensity = getDisplayDensity();
+ return dividerPositionWithDraggingToFullscreenAllowed(
+ dividerPosition,
+ minPosition,
+ maxPosition,
+ fullyExpandedPosition,
+ velocity,
+ displayDensity);
+ }
+ return Math.clamp(dividerPosition, minPosition, maxPosition);
+ }
+
+ /**
+ * Returns the divider position given a set of position options. A snap algorithm is used to
+ * adjust the ending position to either fully expand one container or move the divider back to
+ * the specified min/max ratio depending on the dragging velocity.
+ */
+ @VisibleForTesting
+ static int dividerPositionWithDraggingToFullscreenAllowed(int dividerPosition, int minPosition,
+ int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity) {
+ final float minDismissVelocityPxPerSecond =
+ MIN_DISMISS_VELOCITY_DP_PER_SECOND * displayDensity;
+ final float minFlingVelocityPxPerSecond =
+ MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity;
+ if (dividerPosition < minPosition && velocity < -minDismissVelocityPxPerSecond) {
+ return 0;
+ }
+ if (dividerPosition > maxPosition && velocity > minDismissVelocityPxPerSecond) {
+ return fullyExpandedPosition;
+ }
+ if (Math.abs(velocity) < minFlingVelocityPxPerSecond) {
+ if (dividerPosition >= minPosition && dividerPosition <= maxPosition) {
+ return dividerPosition;
}
- if (dividerPosition > maxPosition) {
- return fullyExpandedPosition;
+ int[] possiblePositions = {0, minPosition, maxPosition, fullyExpandedPosition};
+ return snap(dividerPosition, possiblePositions);
+ }
+ if (velocity < 0) {
+ return 0;
+ } else {
+ return fullyExpandedPosition;
+ }
+ }
+
+ /** Calculates the snapped divider position based on the possible positions and distance. */
+ private static int snap(int dividerPosition, int[] possiblePositions) {
+ int snappedPosition = dividerPosition;
+ float minDistance = Float.MAX_VALUE;
+ for (int position : possiblePositions) {
+ float distance = Math.abs(dividerPosition - position);
+ if (distance < minDistance) {
+ snappedPosition = position;
+ minDistance = distance;
}
}
- return Math.clamp(dividerPosition, minPosition, maxPosition);
+ return snappedPosition;
}
private static void setDecorSurfaceBoosted(
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 13c2d1f73461..b764b6ee065f 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -50,6 +50,7 @@ import static androidx.window.extensions.embedding.SplitPresenter.getActivityInt
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
import static androidx.window.extensions.embedding.SplitPresenter.sanitizeBounds;
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSplit;
+import static androidx.window.extensions.embedding.TaskFragmentContainer.OverlayContainerRestoreParams;
import android.annotation.CallbackExecutor;
import android.app.Activity;
@@ -133,6 +134,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private final List<EmbeddingRule> mSplitRules = new ArrayList<>();
/**
+ * Stores the token of the associated Activity that maps to the
+ * {@link OverlayContainerRestoreParams} of the most recent created overlay container.
+ */
+ @GuardedBy("mLock")
+ final ArrayMap<IBinder, OverlayContainerRestoreParams> mOverlayRestoreParams = new ArrayMap<>();
+
+ /**
* A developer-defined {@link SplitAttributes} calculator to compute the current
* {@link SplitAttributes} with the current device and window states.
* It is registered via {@link #setSplitAttributesCalculator(Function)}
@@ -686,11 +694,20 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
exception);
break;
case TYPE_ACTIVITY_REPARENTED_TO_TASK:
+ final IBinder candidateAssociatedActToken, lastOverlayToken;
+ if (Flags.fixPipRestoreToOverlay()) {
+ candidateAssociatedActToken = change.getOtherActivityToken();
+ lastOverlayToken = change.getTaskFragmentToken();
+ } else {
+ candidateAssociatedActToken = lastOverlayToken = null;
+ }
onActivityReparentedToTask(
wct,
taskId,
change.getActivityIntent(),
- change.getActivityToken());
+ change.getActivityToken(),
+ candidateAssociatedActToken,
+ lastOverlayToken);
break;
default:
throw new IllegalArgumentException(
@@ -917,11 +934,28 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* different process, the server will generate a temporary token that
* the organizer can use to reparent the activity through
* {@link WindowContainerTransaction} if needed.
+ * @param candidateAssociatedActToken The token of the candidate associated-activity.
+ * @param lastOverlayToken The last parent overlay container token.
*/
@VisibleForTesting
@GuardedBy("mLock")
void onActivityReparentedToTask(@NonNull WindowContainerTransaction wct,
- int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken) {
+ int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken,
+ @Nullable IBinder candidateAssociatedActToken, @Nullable IBinder lastOverlayToken) {
+ // Reparent the activity to an overlay container if needed.
+ final OverlayContainerRestoreParams params = getOverlayContainerRestoreParams(
+ candidateAssociatedActToken, lastOverlayToken);
+ if (params != null) {
+ final Activity associatedActivity = getActivity(candidateAssociatedActToken);
+ final TaskFragmentContainer targetContainer = createOrUpdateOverlayTaskFragmentIfNeeded(
+ wct, params.mOptions, params.mIntent, associatedActivity);
+ if (targetContainer != null) {
+ wct.reparentActivityToTaskFragment(targetContainer.getTaskFragmentToken(),
+ activityToken);
+ return;
+ }
+ }
+
// If the activity belongs to the current app process, we treat it as a new activity
// launch.
final Activity activity = getActivity(activityToken);
@@ -966,6 +1000,43 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
/**
+ * Returns the {@link OverlayContainerRestoreParams} that stored last time the {@code
+ * associatedActivityToken} associated with and only if data matches the {@code overlayToken}.
+ * Otherwise, return {@code null}.
+ */
+ @VisibleForTesting
+ @GuardedBy("mLock")
+ @Nullable
+ OverlayContainerRestoreParams getOverlayContainerRestoreParams(
+ @Nullable IBinder associatedActivityToken, @Nullable IBinder overlayToken) {
+ if (!Flags.fixPipRestoreToOverlay()) {
+ return null;
+ }
+
+ if (associatedActivityToken == null || overlayToken == null) {
+ return null;
+ }
+
+ final TaskFragmentContainer.OverlayContainerRestoreParams params =
+ mOverlayRestoreParams.get(associatedActivityToken);
+ if (params == null) {
+ return null;
+ }
+
+ if (params.mOverlayToken != overlayToken) {
+ // Not the same overlay container, no need to restore.
+ return null;
+ }
+
+ final Activity associatedActivity = getActivity(associatedActivityToken);
+ if (associatedActivity == null || associatedActivity.isFinishing()) {
+ return null;
+ }
+
+ return params;
+ }
+
+ /**
* Called when the {@link WindowContainerTransaction} created with
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side.
*
@@ -1433,6 +1504,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
mTaskContainers.valueAt(i).onFinishingActivityPaused(wct, activityToken);
}
+
+ mOverlayRestoreParams.remove(activity.getActivityToken());
updateCallbackIfNecessary();
}
@@ -1450,6 +1523,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
mTaskContainers.valueAt(i).onActivityDestroyed(wct, activityToken);
}
+
+ mOverlayRestoreParams.remove(activity.getActivityToken());
// We didn't trigger the callback if there were any pending appeared activities, so check
// again after the pending is removed.
updateCallbackIfNecessary();
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 482554351b97..d0b6a01bb51e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -36,6 +36,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import java.util.ArrayList;
import java.util.Collections;
@@ -274,6 +275,15 @@ class TaskFragmentContainer {
addPendingAppearedActivity(pendingAppearedActivity);
}
mPendingAppearedIntent = pendingAppearedIntent;
+
+ // Save the information necessary for restoring the overlay when needed.
+ if (Flags.fixPipRestoreToOverlay() && overlayTag != null && pendingAppearedIntent != null
+ && associatedActivity != null && !associatedActivity.isFinishing()) {
+ final IBinder associatedActivityToken = associatedActivity.getActivityToken();
+ final OverlayContainerRestoreParams params = new OverlayContainerRestoreParams(mToken,
+ launchOptions, pendingAppearedIntent);
+ mController.mOverlayRestoreParams.put(associatedActivityToken, params);
+ }
}
/**
@@ -1105,4 +1115,25 @@ class TaskFragmentContainer {
}
return sb.append("]").toString();
}
+
+ static class OverlayContainerRestoreParams {
+ /** The token of the overlay container */
+ @NonNull
+ final IBinder mOverlayToken;
+
+ /** The launch options to create this container. */
+ @NonNull
+ final Bundle mOptions;
+
+ /** The Intent that used to be started in the overlay container. */
+ @NonNull
+ final Intent mIntent;
+
+ OverlayContainerRestoreParams(@NonNull IBinder overlayToken, @NonNull Bundle options,
+ @NonNull Intent intent) {
+ mOverlayToken = overlayToken;
+ mOptions = options;
+ mIntent = intent;
+ }
+ }
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
index b0a45e285896..746607c8094c 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
@@ -19,6 +19,10 @@ package androidx.window.extensions.embedding;
import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE;
import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
+import static androidx.window.extensions.embedding.DividerPresenter.FLING_ANIMATION_DURATION;
+import static androidx.window.extensions.embedding.DividerPresenter.FLING_ANIMATION_INTERPOLATOR;
+import static androidx.window.extensions.embedding.DividerPresenter.MIN_DISMISS_VELOCITY_DP_PER_SECOND;
+import static androidx.window.extensions.embedding.DividerPresenter.MIN_FLING_VELOCITY_DP_PER_SECOND;
import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
import static androidx.window.extensions.embedding.DividerPresenter.getInitialDividerPosition;
import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
@@ -35,6 +39,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Color;
@@ -637,6 +642,105 @@ public class DividerPresenterTest {
DividerPresenter.getContainerBackgroundColor(container, defaultColor));
}
+ @Test
+ public void testGetValueAnimator() {
+ ValueAnimator animator =
+ DividerPresenter.getValueAnimator(
+ 375 /* prevDividerPosition */,
+ 500 /* snappedDividerPosition */);
+
+ assertEquals(animator.getDuration(), FLING_ANIMATION_DURATION);
+ assertEquals(animator.getInterpolator(), FLING_ANIMATION_INTERPOLATOR);
+ }
+
+ @Test
+ public void testDividerPositionWithDraggingToFullscreenAllowed() {
+ final float displayDensity = 600F;
+ final float dismissVelocity = MIN_DISMISS_VELOCITY_DP_PER_SECOND * displayDensity + 10f;
+ final float nonFlingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity - 10f;
+ final float flingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity + 10f;
+
+ // Divider position is less than minPosition and the velocity is enough to be dismissed
+ assertEquals(
+ 0, // Closed position
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 10 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ -dismissVelocity,
+ displayDensity));
+
+ // Divider position is greater than maxPosition and the velocity is enough to be dismissed
+ assertEquals(
+ 1200, // Fully expanded position
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 1000 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ dismissVelocity,
+ displayDensity));
+
+ // Divider position is returned when the velocity is not fast enough for fling and is in
+ // between minPosition and maxPosition
+ assertEquals(
+ 500, // dividerPosition is not snapped
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 500 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity));
+
+ // Divider position is snapped when the velocity is not fast enough for fling and larger
+ // than maxPosition
+ assertEquals(
+ 900, // Closest position is maxPosition
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 950 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity));
+
+ // Divider position is snapped when the velocity is not fast enough for fling and smaller
+ // than minPosition
+ assertEquals(
+ 30, // Closest position is minPosition
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 20 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity));
+
+ // Divider position is greater than minPosition and the velocity is enough for fling
+ assertEquals(
+ 0, // Closed position
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 50 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ -flingVelocity,
+ displayDensity));
+
+ // Divider position is less than maxPosition and the velocity is enough for fling
+ assertEquals(
+ 1200, // Fully expanded position
+ DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ 800 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ flingVelocity,
+ displayDensity));
+ }
+
private TaskFragmentContainer createMockTaskFragmentContainer(
@NonNull IBinder token, @NonNull Rect bounds) {
final TaskFragmentContainer container = mock(TaskFragmentContainer.class);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 9ebcb759115d..f3222572a3e2 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -836,6 +836,30 @@ public class OverlayPresentationTest {
any());
}
+ @Test
+ public void testOnActivityReparentedToTask_overlayRestoration() {
+ mSetFlagRule.enableFlags(Flags.FLAG_FIX_PIP_RESTORE_TO_OVERLAY);
+
+ // Prepares and mock the data necessary for the test.
+ final IBinder activityToken = mActivity.getActivityToken();
+ final Intent intent = new Intent();
+ final IBinder fillTaskActivityToken = new Binder();
+ final IBinder lastOverlayToken = new Binder();
+ final TaskFragmentContainer overlayContainer = mSplitController.newContainer(intent,
+ mActivity, TASK_ID);
+ final TaskFragmentContainer.OverlayContainerRestoreParams params = mock(
+ TaskFragmentContainer.OverlayContainerRestoreParams.class);
+ doReturn(params).when(mSplitController).getOverlayContainerRestoreParams(any(), any());
+ doReturn(overlayContainer).when(mSplitController).createOrUpdateOverlayTaskFragmentIfNeeded(
+ any(), any(), any(), any());
+
+ // Verify the activity should be reparented to the overlay container.
+ mSplitController.onActivityReparentedToTask(mTransaction, TASK_ID, intent, activityToken,
+ fillTaskActivityToken, lastOverlayToken);
+ verify(mTransaction).reparentActivityToTaskFragment(
+ eq(overlayContainer.getTaskFragmentToken()), eq(activityToken));
+ }
+
/**
* A simplified version of {@link SplitController#createOrUpdateOverlayTaskFragmentIfNeeded}
*/
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 7d86ec2272af..35353dbe36be 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
@@ -397,7 +397,8 @@ public class SplitControllerTest {
@Test
public void testOnActivityReparentedToTask_sameProcess() {
mSplitController.onActivityReparentedToTask(mTransaction, TASK_ID, new Intent(),
- mActivity.getActivityToken());
+ mActivity.getActivityToken(), null /* fillTaskActivityToken */,
+ null /* lastOverlayToken */);
// Treated as on activity created, but allow to split as primary.
verify(mSplitController).resolveActivityToContainer(mTransaction,
@@ -413,7 +414,8 @@ public class SplitControllerTest {
final IBinder activityToken = new Binder();
final Intent intent = new Intent();
- mSplitController.onActivityReparentedToTask(mTransaction, TASK_ID, intent, activityToken);
+ mSplitController.onActivityReparentedToTask(mTransaction, TASK_ID, intent, activityToken,
+ null /* fillTaskActivityToken */, null /* lastOverlayToken */);
// Treated as starting new intent
verify(mSplitController, never()).resolveActivityToContainer(any(), any(), anyBoolean());
@@ -1210,7 +1212,7 @@ public class SplitControllerTest {
mSplitController.onTransactionReady(transaction);
verify(mSplitController).onActivityReparentedToTask(any(), eq(TASK_ID), eq(intent),
- eq(activityToken));
+ eq(activityToken), any(), any());
verify(mSplitPresenter).onTransactionHandled(eq(transaction.getTransactionToken()), any(),
anyInt(), anyBoolean());
}
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 8977d5cad780..66d48799204c 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -78,3 +78,10 @@ flag {
description: "Allow opening bubbles overflow UI without bubbles being visible"
bug: "340337839"
}
+
+flag {
+ name: "enable_bubble_stashing"
+ namespace: "multitasking"
+ description: "Allow the floating bubble stack to stash on the edge of the screen"
+ bug: "341361249"
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
index 8487e3792993..9e1440d5716b 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -218,11 +218,10 @@ class BubblePositionerTest {
insets = Insets.of(10, 20, 5, 15),
windowBounds = Rect(0, 0, 1800, 2600)
)
- val bubbleBarBounds = Rect(1700, 2500, 1780, 2600)
positioner.setShowingInBubbleBar(true)
positioner.update(deviceConfig)
- positioner.bubbleBarBounds = bubbleBarBounds
+ positioner.bubbleBarTopOnScreen = 2500
val spaceBetweenTopInsetAndBubbleBarInLandscape = 1680
val expandedViewVerticalSpacing =
@@ -246,10 +245,9 @@ class BubblePositionerTest {
insets = Insets.of(10, 20, 5, 15),
windowBounds = Rect(0, 0, screenWidth, 2600)
)
- val bubbleBarBounds = Rect(100, 2500, 280, 2550)
positioner.setShowingInBubbleBar(true)
positioner.update(deviceConfig)
- positioner.bubbleBarBounds = bubbleBarBounds
+ positioner.bubbleBarTopOnScreen = 2500
val spaceBetweenTopInsetAndBubbleBarInLandscape = 180
val expandedViewSpacing =
@@ -597,16 +595,19 @@ class BubblePositionerTest {
private fun testGetBubbleBarExpandedViewBounds(onLeft: Boolean, isOverflow: Boolean) {
positioner.setShowingInBubbleBar(true)
+ val windowBounds = Rect(0, 0, 2000, 2600)
+ val insets = Insets.of(10, 20, 5, 15)
val deviceConfig =
defaultDeviceConfig.copy(
isLargeScreen = true,
isLandscape = true,
- insets = Insets.of(10, 20, 5, 15),
- windowBounds = Rect(0, 0, 2000, 2600)
+ insets = insets,
+ windowBounds = windowBounds
)
positioner.update(deviceConfig)
- positioner.bubbleBarBounds = getBubbleBarBounds(onLeft, deviceConfig)
+ val bubbleBarHeight = 100
+ positioner.bubbleBarTopOnScreen = windowBounds.bottom - insets.bottom - bubbleBarHeight
val expandedViewPadding =
context.resources.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding)
@@ -624,7 +625,7 @@ class BubblePositionerTest {
left = right - positioner.getExpandedViewWidthForBubbleBar(isOverflow)
}
// Above the bubble bar
- val bottom = positioner.bubbleBarBounds.top - expandedViewPadding
+ val bottom = positioner.bubbleBarTopOnScreen - expandedViewPadding
// Calculate right and top based on size
val top = bottom - positioner.getExpandedViewHeightForBubbleBar(isOverflow)
val expectedBounds = Rect(left, top, right, bottom)
@@ -666,21 +667,4 @@ class BubblePositionerTest {
positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
return allowableStackRegion.top + allowableStackRegion.height() * offsetPercent
}
-
- private fun getBubbleBarBounds(onLeft: Boolean, deviceConfig: DeviceConfig): Rect {
- val width = 200
- val height = 100
- val bottom = deviceConfig.windowBounds.bottom - deviceConfig.insets.bottom
- val top = bottom - height
- val left: Int
- val right: Int
- if (onLeft) {
- left = deviceConfig.insets.left
- right = left + width
- } else {
- right = deviceConfig.windowBounds.right - deviceConfig.insets.right
- left = right - width
- }
- return Rect(left, top, right, bottom)
- }
}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
index 076414132e27..12d19279111a 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
@@ -53,7 +53,6 @@ class BubbleExpandedViewPinControllerTest {
const val SCREEN_WIDTH = 2000
const val SCREEN_HEIGHT = 1000
- const val BUBBLE_BAR_WIDTH = 100
const val BUBBLE_BAR_HEIGHT = 50
}
@@ -84,14 +83,8 @@ class BubbleExpandedViewPinControllerTest {
insets = Insets.of(10, 20, 30, 40)
)
positioner.update(deviceConfig)
- positioner.bubbleBarBounds =
- Rect(
- SCREEN_WIDTH - deviceConfig.insets.right - BUBBLE_BAR_WIDTH,
- SCREEN_HEIGHT - deviceConfig.insets.bottom - BUBBLE_BAR_HEIGHT,
- SCREEN_WIDTH - deviceConfig.insets.right,
- SCREEN_HEIGHT - deviceConfig.insets.bottom
- )
-
+ positioner.bubbleBarTopOnScreen =
+ SCREEN_HEIGHT - deviceConfig.insets.bottom - BUBBLE_BAR_HEIGHT
controller = BubbleExpandedViewPinController(context, container, positioner)
testListener = TestLocationChangeListener()
controller.setListener(testListener)
@@ -247,9 +240,10 @@ class BubbleExpandedViewPinControllerTest {
private val dropTargetView: View?
get() = container.findViewById(R.id.bubble_bar_drop_target)
- private fun getExpectedDropTargetBounds(onLeft: Boolean): Rect = Rect().also {
- positioner.getBubbleBarExpandedViewBounds(onLeft, false /* isOveflowExpanded */, it)
- }
+ private fun getExpectedDropTargetBounds(onLeft: Boolean): Rect =
+ Rect().also {
+ positioner.getBubbleBarExpandedViewBounds(onLeft, false /* isOveflowExpanded */, it)
+ }
private fun runOnMainSync(runnable: Runnable) {
InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable)
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 8d24c161e3e4..aa4fb4448ac7 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -247,13 +247,11 @@
<!-- Padding for the bubble popup view contents. -->
<dimen name="bubble_popup_padding">24dp</dimen>
<!-- The size of the caption bar inset at the top of bubble bar expanded view. -->
- <dimen name="bubble_bar_expanded_view_caption_height">32dp</dimen>
+ <dimen name="bubble_bar_expanded_view_caption_height">36dp</dimen>
<!-- The width of the caption bar at the top of bubble bar expanded view. -->
- <dimen name="bubble_bar_expanded_view_caption_width">128dp</dimen>
- <!-- The height of the dots shown for the caption menu in the bubble bar expanded view.. -->
- <dimen name="bubble_bar_expanded_view_caption_dot_size">4dp</dimen>
- <!-- The spacing between the dots for the caption menu in the bubble bar expanded view.. -->
- <dimen name="bubble_bar_expanded_view_caption_dot_spacing">4dp</dimen>
+ <dimen name="bubble_bar_expanded_view_caption_width">80dp</dimen>
+ <!-- The height of the handle shown for the caption menu in the bubble bar expanded view. -->
+ <dimen name="bubble_bar_expanded_view_handle_height">4dp</dimen>
<!-- Width of the expanded bubble bar view shown when the bubble is expanded. -->
<dimen name="bubble_bar_expanded_view_width">412dp</dimen>
<!-- Minimum width of the bubble bar manage menu. -->
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/DesktopModeStatus.java
index bdd89c0e1ac9..8d8655addc65 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/DesktopModeStatus.java
@@ -67,6 +67,16 @@ public class DesktopModeStatus {
private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
"persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
+ /** Override density for tasks when they're inside the desktop. */
+ public static final int DESKTOP_DENSITY_OVERRIDE =
+ SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284);
+
+ /** The minimum override density allowed for tasks inside the desktop. */
+ private static final int DESKTOP_DENSITY_MIN = 100;
+
+ /** The maximum override density allowed for tasks inside the desktop. */
+ private static final int DESKTOP_DENSITY_MAX = 1000;
+
/**
* Default value for {@code MAX_TASK_LIMIT}.
*/
@@ -145,4 +155,12 @@ public class DesktopModeStatus {
public static boolean canEnterDesktopMode(@NonNull Context context) {
return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled();
}
+
+ /**
+ * Return {@code true} if the override desktop density is set.
+ */
+ public static boolean isDesktopDensityOverrideSet() {
+ return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN
+ && DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 38c344322a30..42a4ab2e352d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1189,10 +1189,12 @@ public class BubbleController implements ConfigurationChangeListener,
* A bubble is no longer being dragged in Launcher. And was released in given location.
* Will be called only when bubble bar is expanded.
*
- * @param location location where bubble was released
+ * @param location location where bubble was released
+ * @param topOnScreen top coordinate of the bubble bar on the screen after release
*/
- public void stopBubbleDrag(BubbleBarLocation location) {
+ public void stopBubbleDrag(BubbleBarLocation location, int topOnScreen) {
mBubblePositioner.setBubbleBarLocation(location);
+ mBubblePositioner.setBubbleBarTopOnScreen(topOnScreen);
if (mBubbleData.getSelectedBubble() != null) {
mBubbleBarViewCallback.expansionChanged(/* isExpanded = */ true);
}
@@ -1248,8 +1250,8 @@ public class BubbleController implements ConfigurationChangeListener,
* <p>This is used by external callers (launcher).
*/
@VisibleForTesting
- public void expandStackAndSelectBubbleFromLauncher(String key, Rect bubbleBarBounds) {
- mBubblePositioner.setBubbleBarBounds(bubbleBarBounds);
+ public void expandStackAndSelectBubbleFromLauncher(String key, int topOnScreen) {
+ mBubblePositioner.setBubbleBarTopOnScreen(topOnScreen);
if (BubbleOverflow.KEY.equals(key)) {
mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
@@ -2364,10 +2366,9 @@ public class BubbleController implements ConfigurationChangeListener,
}
@Override
- public void showBubble(String key, Rect bubbleBarBounds) {
+ public void showBubble(String key, int topOnScreen) {
mMainExecutor.execute(
- () -> mController.expandStackAndSelectBubbleFromLauncher(
- key, bubbleBarBounds));
+ () -> mController.expandStackAndSelectBubbleFromLauncher(key, topOnScreen));
}
@Override
@@ -2386,8 +2387,8 @@ public class BubbleController implements ConfigurationChangeListener,
}
@Override
- public void stopBubbleDrag(BubbleBarLocation location) {
- mMainExecutor.execute(() -> mController.stopBubbleDrag(location));
+ public void stopBubbleDrag(BubbleBarLocation location, int topOnScreen) {
+ mMainExecutor.execute(() -> mController.stopBubbleDrag(location, topOnScreen));
}
@Override
@@ -2408,9 +2409,9 @@ public class BubbleController implements ConfigurationChangeListener,
}
@Override
- public void setBubbleBarBounds(Rect bubbleBarBounds) {
+ public void updateBubbleBarTopOnScreen(int topOnScreen) {
mMainExecutor.execute(() -> {
- mBubblePositioner.setBubbleBarBounds(bubbleBarBounds);
+ mBubblePositioner.setBubbleBarTopOnScreen(topOnScreen);
if (mLayerView != null) mLayerView.updateExpandedView();
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index a35a004cdace..1e482cac0b46 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -98,7 +98,7 @@ public class BubblePositioner {
private boolean mShowingInBubbleBar;
private BubbleBarLocation mBubbleBarLocation = BubbleBarLocation.DEFAULT;
- private final Rect mBubbleBarBounds = new Rect();
+ private int mBubbleBarTopOnScreen;
public BubblePositioner(Context context, WindowManager windowManager) {
mContext = context;
@@ -846,17 +846,17 @@ public class BubblePositioner {
}
/**
- * Sets the position of the bubble bar in display coordinates.
+ * Set top coordinate of bubble bar on screen
*/
- public void setBubbleBarBounds(Rect bubbleBarBounds) {
- mBubbleBarBounds.set(bubbleBarBounds);
+ public void setBubbleBarTopOnScreen(int topOnScreen) {
+ mBubbleBarTopOnScreen = topOnScreen;
}
/**
- * Returns the display coordinates of the bubble bar.
+ * Returns the top coordinate of bubble bar on screen
*/
- public Rect getBubbleBarBounds() {
- return mBubbleBarBounds;
+ public int getBubbleBarTopOnScreen() {
+ return mBubbleBarTopOnScreen;
}
/**
@@ -908,7 +908,7 @@ public class BubblePositioner {
/** The bottom position of the expanded view when showing above the bubble bar. */
public int getExpandedViewBottomForBubbleBar() {
- return mBubbleBarBounds.top - mExpandedViewPadding;
+ return mBubbleBarTopOnScreen - mExpandedViewPadding;
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
index 1eff149f2e91..1db556c04180 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
@@ -31,7 +31,7 @@ interface IBubbles {
oneway void unregisterBubbleListener(in IBubblesListener listener) = 2;
- oneway void showBubble(in String key, in Rect bubbleBarBounds) = 3;
+ oneway void showBubble(in String key, in int topOnScreen) = 3;
oneway void dragBubbleToDismiss(in String key) = 4;
@@ -45,7 +45,7 @@ interface IBubbles {
oneway void setBubbleBarLocation(in BubbleBarLocation location) = 9;
- oneway void setBubbleBarBounds(in Rect bubbleBarBounds) = 10;
+ oneway void updateBubbleBarTopOnScreen(in int topOnScreen) = 10;
- oneway void stopBubbleDrag(in BubbleBarLocation location) = 11;
+ oneway void stopBubbleDrag(in BubbleBarLocation location, in int topOnScreen) = 11;
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 45ad6319bbf8..8e58db198b13 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -237,12 +237,10 @@ public class BubbleBarAnimationHelper {
private void setScaleFromBubbleBar(AnimatableScaleMatrix matrix, float scale) {
// Set the pivot point for the scale, so the view animates out from the bubble bar.
- Rect bubbleBarBounds = mPositioner.getBubbleBarBounds();
- matrix.setScale(
- scale,
- scale,
- bubbleBarBounds.centerX(),
- bubbleBarBounds.top);
+ Rect availableRect = mPositioner.getAvailableRect();
+ float pivotX = mPositioner.isBubbleBarOnLeft() ? availableRect.left : availableRect.right;
+ float pivotY = mPositioner.getBubbleBarTopOnScreen();
+ matrix.setScale(scale, scale, pivotX, pivotY);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
index 2b7a0706b4de..d54a6b002e43 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
@@ -37,15 +37,11 @@ import com.android.wm.shell.R;
*/
public class BubbleBarHandleView extends View {
private static final long COLOR_CHANGE_DURATION = 120;
-
- // The handle view is currently rendered as 3 evenly spaced dots.
- private int mDotSize;
- private int mDotSpacing;
// Path used to draw the dots
private final Path mPath = new Path();
- private @ColorInt int mHandleLightColor;
- private @ColorInt int mHandleDarkColor;
+ private final @ColorInt int mHandleLightColor;
+ private final @ColorInt int mHandleDarkColor;
private @Nullable ObjectAnimator mColorChangeAnim;
public BubbleBarHandleView(Context context) {
@@ -63,10 +59,8 @@ public class BubbleBarHandleView extends View {
public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mDotSize = getResources().getDimensionPixelSize(
- R.dimen.bubble_bar_expanded_view_caption_dot_size);
- mDotSpacing = getResources().getDimensionPixelSize(
- R.dimen.bubble_bar_expanded_view_caption_dot_spacing);
+ final int handleHeight = getResources().getDimensionPixelSize(
+ R.dimen.bubble_bar_expanded_view_handle_height);
mHandleLightColor = ContextCompat.getColor(getContext(),
R.color.bubble_bar_expanded_view_handle_light);
mHandleDarkColor = ContextCompat.getColor(getContext(),
@@ -76,27 +70,13 @@ public class BubbleBarHandleView extends View {
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- final int handleCenterX = view.getWidth() / 2;
final int handleCenterY = view.getHeight() / 2;
- final int handleTotalWidth = mDotSize * 3 + mDotSpacing * 2;
- final int handleLeft = handleCenterX - handleTotalWidth / 2;
- final int handleTop = handleCenterY - mDotSize / 2;
- final int handleBottom = handleTop + mDotSize;
- RectF dot1 = new RectF(
- handleLeft, handleTop,
- handleLeft + mDotSize, handleBottom);
- RectF dot2 = new RectF(
- dot1.right + mDotSpacing, handleTop,
- dot1.right + mDotSpacing + mDotSize, handleBottom
- );
- RectF dot3 = new RectF(
- dot2.right + mDotSpacing, handleTop,
- dot2.right + mDotSpacing + mDotSize, handleBottom
- );
+ final int handleTop = handleCenterY - handleHeight / 2;
+ final int handleBottom = handleTop + handleHeight;
+ final int radius = handleHeight / 2;
+ RectF handle = new RectF(/* left = */ 0, handleTop, view.getWidth(), handleBottom);
mPath.reset();
- mPath.addOval(dot1, Path.Direction.CW);
- mPath.addOval(dot2, Path.Direction.CW);
- mPath.addOval(dot3, Path.Direction.CW);
+ mPath.addRoundRect(handle, radius, radius, Path.Direction.CW);
outline.setPath(mPath);
}
});
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 607a3b5423d1..2234041b8c9d 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
@@ -347,7 +347,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
if (mMoving) {
final int position = mSplitLayout.getDividerPosition() + touchPos - mStartPos;
mLastDraggingPosition = position;
- mSplitLayout.updateDividerBounds(position);
+ mSplitLayout.updateDividerBounds(position, true /* shouldUseParallaxEffect */);
}
break;
case MotionEvent.ACTION_UP:
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 30eb8b5d2f05..de016d3ae400 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
@@ -31,7 +31,6 @@ import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
-import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -57,7 +56,13 @@ import com.android.wm.shell.common.SurfaceUtils;
import java.util.function.Consumer;
/**
- * Handles split decor like showing resizing hint for a specific split.
+ * Handles additional layers over a running task in a split pair, for example showing a veil with an
+ * app icon when the task is being resized (usually to hide weird layouts while the app is being
+ * stretched). One SplitDecorManager is initialized on each window.
+ * <br>
+ * Currently, we show a veil when:
+ * a) Task is resizing down from a fullscreen window.
+ * b) Task is being stretched past its original bounds.
*/
public class SplitDecorManager extends WindowlessWindowManager {
private static final String TAG = SplitDecorManager.class.getSimpleName();
@@ -78,7 +83,11 @@ public class SplitDecorManager extends WindowlessWindowManager {
private boolean mShown;
private boolean mIsResizing;
- private final Rect mOldBounds = new Rect();
+ /** The original bounds of the main task, captured at the beginning of a resize transition. */
+ private final Rect mOldMainBounds = new Rect();
+ /** The original bounds of the side task, captured at the beginning of a resize transition. */
+ private final Rect mOldSideBounds = new Rect();
+ /** The current bounds of the main task, mid-resize. */
private final Rect mResizingBounds = new Rect();
private final Rect mTempRect = new Rect();
private ValueAnimator mFadeAnimator;
@@ -184,29 +193,38 @@ public class SplitDecorManager extends WindowlessWindowManager {
mResizingIconView = null;
mIsResizing = false;
mShown = false;
- mOldBounds.setEmpty();
+ mOldMainBounds.setEmpty();
+ mOldSideBounds.setEmpty();
mResizingBounds.setEmpty();
}
/** Showing resizing hint. */
public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
Rect sideBounds, SurfaceControl.Transaction t, int offsetX, int offsetY,
- boolean immediately) {
+ boolean immediately, float[] veilColor) {
if (mResizingIconView == null) {
return;
}
if (!mIsResizing) {
mIsResizing = true;
- mOldBounds.set(newBounds);
+ mOldMainBounds.set(newBounds);
+ mOldSideBounds.set(sideBounds);
}
mResizingBounds.set(newBounds);
mOffsetX = offsetX;
mOffsetY = offsetY;
- final boolean show =
- newBounds.width() > mOldBounds.width() || newBounds.height() > mOldBounds.height();
- final boolean update = show != mShown;
+ // Show a veil when:
+ // a) Task is resizing down from a fullscreen window.
+ // b) Task is being stretched past its original bounds.
+ final boolean isResizingDownFromFullscreen =
+ mOldSideBounds.width() <= 1 || mOldSideBounds.height() <= 1;
+ final boolean isStretchingPastOriginalBounds =
+ newBounds.width() > mOldMainBounds.width()
+ || newBounds.height() > mOldMainBounds.height();
+ final boolean showVeil = isResizingDownFromFullscreen || isStretchingPastOriginalBounds;
+ final boolean update = showVeil != mShown;
if (update && mFadeAnimator != null && mFadeAnimator.isRunning()) {
// If we need to animate and animator still running, cancel it before we ensure both
// background and icon surfaces are non null for next animation.
@@ -216,18 +234,18 @@ public class SplitDecorManager extends WindowlessWindowManager {
if (mBackgroundLeash == null) {
mBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
RESIZING_BACKGROUND_SURFACE_NAME, mSurfaceSession);
- t.setColor(mBackgroundLeash, getResizingBackgroundColor(resizingTask))
+ t.setColor(mBackgroundLeash, veilColor)
.setLayer(mBackgroundLeash, Integer.MAX_VALUE - 1);
}
if (mGapBackgroundLeash == null && !immediately) {
final boolean isLandscape = newBounds.height() == sideBounds.height();
- final int left = isLandscape ? mOldBounds.width() : 0;
- final int top = isLandscape ? 0 : mOldBounds.height();
+ final int left = isLandscape ? mOldMainBounds.width() : 0;
+ final int top = isLandscape ? 0 : mOldMainBounds.height();
mGapBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
GAP_BACKGROUND_SURFACE_NAME, mSurfaceSession);
// Fill up another side bounds area.
- t.setColor(mGapBackgroundLeash, getResizingBackgroundColor(resizingTask))
+ t.setColor(mGapBackgroundLeash, veilColor)
.setLayer(mGapBackgroundLeash, Integer.MAX_VALUE - 2)
.setPosition(mGapBackgroundLeash, left, top)
.setWindowCrop(mGapBackgroundLeash, sideBounds.width(), sideBounds.height());
@@ -251,12 +269,12 @@ public class SplitDecorManager extends WindowlessWindowManager {
if (update) {
if (immediately) {
- t.setVisibility(mBackgroundLeash, show);
- t.setVisibility(mIconLeash, show);
+ t.setVisibility(mBackgroundLeash, showVeil);
+ t.setVisibility(mIconLeash, showVeil);
} else {
- startFadeAnimation(show, false, null);
+ startFadeAnimation(showVeil, false, null);
}
- mShown = show;
+ mShown = showVeil;
}
}
@@ -309,7 +327,8 @@ public class SplitDecorManager extends WindowlessWindowManager {
mIsResizing = false;
mOffsetX = 0;
mOffsetY = 0;
- mOldBounds.setEmpty();
+ mOldMainBounds.setEmpty();
+ mOldSideBounds.setEmpty();
mResizingBounds.setEmpty();
if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
if (!mShown) {
@@ -346,14 +365,14 @@ public class SplitDecorManager extends WindowlessWindowManager {
/** Screenshot host leash and attach on it if meet some conditions */
public void screenshotIfNeeded(SurfaceControl.Transaction t) {
- if (!mShown && mIsResizing && !mOldBounds.equals(mResizingBounds)) {
+ if (!mShown && mIsResizing && !mOldMainBounds.equals(mResizingBounds)) {
if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) {
mScreenshotAnimator.cancel();
} else if (mScreenshot != null) {
t.remove(mScreenshot);
}
- mTempRect.set(mOldBounds);
+ mTempRect.set(mOldMainBounds);
mTempRect.offsetTo(0, 0);
mScreenshot = ScreenshotUtils.takeScreenshot(t, mHostLeash, mTempRect,
Integer.MAX_VALUE - 1);
@@ -364,7 +383,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
public void setScreenshotIfNeeded(SurfaceControl screenshot, SurfaceControl.Transaction t) {
if (screenshot == null || !screenshot.isValid()) return;
- if (!mShown && mIsResizing && !mOldBounds.equals(mResizingBounds)) {
+ if (!mShown && mIsResizing && !mOldMainBounds.equals(mResizingBounds)) {
if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) {
mScreenshotAnimator.cancel();
} else if (mScreenshot != null) {
@@ -465,9 +484,4 @@ public class SplitDecorManager extends WindowlessWindowManager {
mIcon = null;
}
}
-
- private static float[] getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
- final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
- return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).getComponents();
- }
}
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 2ea32f44a78b..8331654839c9 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
@@ -496,10 +496,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
* Updates bounds with the passing position. Usually used to update recording bounds while
* performing animation or dragging divider bar to resize the splits.
*/
- void updateDividerBounds(int position) {
+ void updateDividerBounds(int position, boolean shouldUseParallaxEffect) {
updateBounds(position);
mSplitLayoutHandler.onLayoutSizeChanging(this, mSurfaceEffectPolicy.mParallaxOffset.x,
- mSurfaceEffectPolicy.mParallaxOffset.y);
+ mSurfaceEffectPolicy.mParallaxOffset.y, shouldUseParallaxEffect);
}
void setDividerPosition(int position, boolean applyLayoutChange) {
@@ -647,7 +647,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
.setDuration(duration);
mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
mDividerFlingAnimator.addUpdateListener(
- animation -> updateDividerBounds((int) animation.getAnimatedValue()));
+ animation -> updateDividerBounds(
+ (int) animation.getAnimatedValue(), false /* shouldUseParallaxEffect */)
+ );
mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -897,7 +899,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
* @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl,
* SurfaceControl, SurfaceControl, boolean)
*/
- void onLayoutSizeChanging(SplitLayout layout, int offsetX, int offsetY);
+ void onLayoutSizeChanging(SplitLayout layout, int offsetX, int offsetY,
+ boolean shouldUseParallaxEffect);
/**
* Calls when finish resizing the split bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
index f9259e79472e..e8226051b672 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
@@ -16,8 +16,6 @@
package com.android.wm.shell.common.split;
-import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED;
-
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -26,25 +24,18 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import android.app.ActivityManager;
import android.app.PendingIntent;
-import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.Rect;
-import android.os.UserHandle;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.util.ArrayUtils;
import com.android.wm.shell.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
-import java.util.Arrays;
-import java.util.List;
-
/** Helper utility class for split screen components to use. */
public class SplitScreenUtils {
/** Reverse the split position. */
@@ -137,4 +128,10 @@ public class SplitScreenUtils {
return isLandscape;
}
}
+
+ /** Returns the specified background color that matches a RunningTaskInfo. */
+ public static Color getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
+ final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
+ return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor);
+ }
}
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 fb0a1ab3062e..4e9e8f97620c 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
@@ -100,6 +100,7 @@ import com.android.wm.shell.unfold.qualifier.UnfoldShellTransition;
import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
+import com.android.wm.shell.windowdecor.ResizeHandleSizeRepository;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import dagger.Binds;
@@ -220,7 +221,8 @@ public abstract class WMShellModule {
SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ ResizeHandleSizeRepository resizeHandleSizeRepository) {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return new DesktopModeWindowDecorViewModel(
context,
@@ -237,7 +239,8 @@ public abstract class WMShellModule {
syncQueue,
transitions,
desktopTasksController,
- rootTaskDisplayAreaOrganizer);
+ rootTaskDisplayAreaOrganizer,
+ resizeHandleSizeRepository);
}
return new CaptionWindowDecorViewModel(
context,
@@ -247,7 +250,8 @@ public abstract class WMShellModule {
displayController,
rootTaskDisplayAreaOrganizer,
syncQueue,
- transitions);
+ transitions,
+ resizeHandleSizeRepository);
}
//
@@ -529,7 +533,8 @@ public abstract class WMShellModule {
exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler, desktopModeTaskRepository,
desktopModeLoggerTransitionObserver, launchAdjacentController,
- recentsTransitionHandler, multiInstanceHelper, mainExecutor, desktopTasksLimiter);
+ recentsTransitionHandler, multiInstanceHelper,
+ mainExecutor, desktopTasksLimiter);
}
@WMSingleton
@@ -622,6 +627,12 @@ public abstract class WMShellModule {
return new DesktopModeEventLogger();
}
+ @WMSingleton
+ @Provides
+ static ResizeHandleSizeRepository provideResizeHandleSizeRepository() {
+ return new ResizeHandleSizeRepository();
+ }
+
//
// Drag and drop
//
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 2dc4573b4921..e5bf53a4afdb 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
@@ -73,6 +73,8 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
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.isDesktopDensityOverrideSet
import com.android.wm.shell.shared.annotations.ExternalThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.splitscreen.SplitScreenController
@@ -906,18 +908,22 @@ class DesktopTasksController(
task.taskId
)
return WindowContainerTransaction().also { wct ->
- addMoveToFullscreenChanges(wct, task)
+ bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
+ wct.reorder(task.token, true)
}
}
+ val wct = WindowContainerTransaction()
+ if (isDesktopDensityOverrideSet()) {
+ wct.setDensityDpi(task.token, DESKTOP_DENSITY_OVERRIDE)
+ }
// Desktop Mode is showing and we're launching a new Task - we might need to minimize
// a Task.
- val wct = WindowContainerTransaction()
val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task)
if (taskToMinimize != null) {
addPendingMinimizeTransition(transition, taskToMinimize)
return wct
}
- return null
+ return if (wct.isEmpty) null else wct
}
private fun handleFullscreenTaskLaunch(
@@ -985,7 +991,7 @@ class DesktopTasksController(
wct.setWindowingMode(taskInfo.token, targetWindowingMode)
wct.reorder(taskInfo.token, true /* onTop */)
if (isDesktopDensityOverrideSet()) {
- wct.setDensityDpi(taskInfo.token, getDesktopDensityDpi())
+ wct.setDensityDpi(taskInfo.token, DESKTOP_DENSITY_OVERRIDE)
}
}
@@ -1089,10 +1095,6 @@ class DesktopTasksController(
return context.resources.displayMetrics.densityDpi
}
- private fun getDesktopDensityDpi(): Int {
- return DESKTOP_DENSITY_OVERRIDE
- }
-
/** Creates a new instance of the external interface to pass to another process. */
private fun createExternalInterface(): ExternalInterfaceBinder {
return IDesktopModeImpl(this)
@@ -1466,21 +1468,9 @@ class DesktopTasksController(
}
companion object {
- private val DESKTOP_DENSITY_OVERRIDE =
- SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284)
- private val DESKTOP_DENSITY_ALLOWED_RANGE = (100..1000)
-
@JvmField
val DESKTOP_MODE_INITIAL_BOUNDS_SCALE = SystemProperties
.getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f
-
- /**
- * Check if desktop density override is enabled
- */
- @JvmStatic
- fun isDesktopDensityOverrideSet(): Boolean {
- return DESKTOP_DENSITY_OVERRIDE in DESKTOP_DENSITY_ALLOWED_RANGE
- }
}
/** The positions on a screen that a task can snap to. */
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 6a7d297e83e5..a42ca1905ee7 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
@@ -16,10 +16,9 @@
package com.android.wm.shell.draganddrop;
+import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.ClipDescription.EXTRA_ACTIVITY_OPTIONS;
@@ -47,7 +46,6 @@ import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
-import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
@@ -265,13 +263,14 @@ public class DragAndDropPolicy {
final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
final ActivityOptions baseActivityOpts = ActivityOptions.makeBasic();
baseActivityOpts.setDisallowEnterPictureInPictureWhileLaunching(true);
+ // Put BAL flags to avoid activity start aborted.
+ baseActivityOpts.setPendingIntentBackgroundActivityStartMode(
+ MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ baseActivityOpts.setPendingIntentBackgroundActivityLaunchAllowedByPermission(true);
final Bundle opts = baseActivityOpts.toBundle();
if (session.appData.hasExtra(EXTRA_ACTIVITY_OPTIONS)) {
opts.putAll(session.appData.getBundleExtra(EXTRA_ACTIVITY_OPTIONS));
}
- // Put BAL flags to avoid activity start aborted.
- opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
- opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, true);
final UserHandle user = session.appData.getParcelableExtra(EXTRA_USER);
if (isTask) {
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 59d696918448..4bb10dfdf8c6 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
@@ -22,11 +22,11 @@ import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
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.common.split.SplitScreenUtils.getResizingBackgroundColor;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
@@ -41,7 +41,6 @@ import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Region;
@@ -278,7 +277,7 @@ public class DragLayout extends LinearLayout
final int activityType = taskInfo1.getActivityType();
if (activityType == ACTIVITY_TYPE_STANDARD) {
Drawable icon1 = mIconProvider.getIcon(taskInfo1.topActivityInfo);
- int bgColor1 = getResizingBackgroundColor(taskInfo1);
+ int bgColor1 = getResizingBackgroundColor(taskInfo1).toArgb();
mDropZoneView1.setAppInfo(bgColor1, icon1);
mDropZoneView2.setAppInfo(bgColor1, icon1);
updateDropZoneSizes(null, null); // passing null splits the views evenly
@@ -298,10 +297,10 @@ public class DragLayout extends LinearLayout
mSplitScreenController.getTaskInfo(SPLIT_POSITION_BOTTOM_OR_RIGHT);
if (topOrLeftTask != null && bottomOrRightTask != null) {
Drawable topOrLeftIcon = mIconProvider.getIcon(topOrLeftTask.topActivityInfo);
- int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask);
+ int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask).toArgb();
Drawable bottomOrRightIcon = mIconProvider.getIcon(
bottomOrRightTask.topActivityInfo);
- int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask);
+ int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask).toArgb();
mDropZoneView1.setAppInfo(topOrLeftColor, topOrLeftIcon);
mDropZoneView2.setAppInfo(bottomOrRightColor, bottomOrRightIcon);
}
@@ -556,11 +555,6 @@ public class DragLayout extends LinearLayout
}
}
- private static int getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
- final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
- return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).toArgb();
- }
-
/**
* Dumps information about this drag layout.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 6e5b7673e206..0541a0287179 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -501,10 +501,11 @@ class SplitScreenTransitions {
mAnimatingTransition = null;
mOnFinish.run();
- if (mFinishCallback != null) {
- mFinishCallback.onTransitionFinished(wct /* wct */);
- mFinishCallback = null;
- }
+ if (mFinishCallback != null) {
+ Transitions.TransitionFinishCallback currentFinishCallback = mFinishCallback;
+ mFinishCallback = null;
+ currentFinishCallback.onTransitionFinished(wct /* wct */);
+ }
}
private void startFadeAnimation(@NonNull SurfaceControl leash, boolean show) {
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 8e97068dce84..9f8cb625fe17 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
@@ -16,10 +16,8 @@
package com.android.wm.shell.splitscreen;
-import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
+import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -43,11 +41,11 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.common.split.SplitScreenConstants.splitPositionToString;
+import static com.android.wm.shell.common.split.SplitScreenUtils.getResizingBackgroundColor;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
-import static com.android.wm.shell.shared.TransitionUtil.isOpeningMode;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
@@ -1887,13 +1885,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
private void addActivityOptions(Bundle opts, @Nullable StageTaskListener launchTarget) {
+ ActivityOptions options = ActivityOptions.fromBundle(opts);
if (launchTarget != null) {
- opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, launchTarget.mRootTaskInfo.token);
+ options.setLaunchRootTask(launchTarget.mRootTaskInfo.token);
}
// Put BAL flags to avoid activity start aborted. Otherwise, flows like shortcut to split
// will be canceled.
- opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
- opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, true);
+ options.setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ options.setPendingIntentBackgroundActivityLaunchAllowedByPermission(true);
+ opts.putAll(options.toBundle());
}
void updateActivityOptions(Bundle opts, @SplitPosition int position) {
@@ -2388,14 +2388,20 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
@Override
- public void onLayoutSizeChanging(SplitLayout layout, int offsetX, int offsetY) {
+ public void onLayoutSizeChanging(SplitLayout layout, int offsetX, int offsetY,
+ boolean shouldUseParallaxEffect) {
final SurfaceControl.Transaction t = mTransactionPool.acquire();
t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
- updateSurfaceBounds(layout, t, true /* applyResizingOffset */);
+ updateSurfaceBounds(layout, t, shouldUseParallaxEffect);
getMainStageBounds(mTempRect1);
getSideStageBounds(mTempRect2);
- mMainStage.onResizing(mTempRect1, mTempRect2, t, offsetX, offsetY, mShowDecorImmediately);
- mSideStage.onResizing(mTempRect2, mTempRect1, t, offsetX, offsetY, mShowDecorImmediately);
+ // TODO (b/307490004): "commonColor" below is a temporary fix to ensure the colors on both
+ // sides match. When b/307490004 is fixed, this code can be reverted.
+ float[] commonColor = getResizingBackgroundColor(mSideStage.mRootTaskInfo).getComponents();
+ mMainStage.onResizing(
+ mTempRect1, mTempRect2, t, offsetX, offsetY, mShowDecorImmediately, commonColor);
+ mSideStage.onResizing(
+ mTempRect2, mTempRect1, t, offsetX, offsetY, mShowDecorImmediately, commonColor);
t.apply();
mTransactionPool.release(t);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index f77c80d2ff3b..0f3d6cade95a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -314,10 +314,10 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
void onResizing(Rect newBounds, Rect sideBounds, SurfaceControl.Transaction t, int offsetX,
- int offsetY, boolean immediately) {
+ int offsetY, boolean immediately, float[] veilColor) {
if (mSplitDecorManager != null && mRootTaskInfo != null) {
mSplitDecorManager.onResizing(mRootTaskInfo, newBounds, sideBounds, t, offsetX,
- offsetY, immediately);
+ offsetY, immediately, veilColor);
}
}
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 e85cb6400000..bfa163cb2860 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
@@ -63,6 +63,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
private final SyncTransactionQueue mSyncQueue;
private final Transitions mTransitions;
+ private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
private TaskOperations mTaskOperations;
private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
@@ -75,7 +76,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
DisplayController displayController,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
SyncTransactionQueue syncQueue,
- Transitions transitions) {
+ Transitions transitions,
+ ResizeHandleSizeRepository resizeHandleSizeRepository) {
mContext = context;
mMainHandler = mainHandler;
mMainChoreographer = mainChoreographer;
@@ -84,6 +86,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
mSyncQueue = syncQueue;
mTransitions = transitions;
+ mResizeHandleSizeRepository = resizeHandleSizeRepository;
if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
mTaskOperations = new TaskOperations(null, mContext, mSyncQueue);
}
@@ -231,7 +234,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
taskSurface,
mMainHandler,
mMainChoreographer,
- mSyncQueue);
+ mSyncQueue,
+ mResizeHandleSizeRepository);
mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
final FluidResizeTaskPositioner taskPositioner =
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 6671391efdeb..8a49a73e0253 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
@@ -16,11 +16,11 @@
package com.android.wm.shell.windowdecor;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getFineResizeCornerPixels;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getLargeResizeCornerPixels;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration.WindowingMode;
@@ -45,6 +45,8 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
+import java.util.function.Consumer;
+
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
* {@link CaptionWindowDecorViewModel}. The caption bar contains a back button, minimize button,
@@ -58,12 +60,28 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
private DragPositioningCallback mDragPositioningCallback;
+ // Listener for handling drag resize events. Will be null if the task cannot be resized.
+ @Nullable
private DragResizeInputListener mDragResizeListener;
private DragDetector mDragDetector;
private RelayoutParams mRelayoutParams = new RelayoutParams();
private final RelayoutResult<WindowDecorLinearLayout> mResult =
new RelayoutResult<>();
+ private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
+ private final Consumer<ResizeHandleSizeRepository> mResizeHandleSizeChangedFunction =
+ (ResizeHandleSizeRepository sizeRepository) -> {
+ if (mDragResizeListener == null) {
+ return;
+ }
+ final Resources res = mResult.mRootView.getResources();
+ mDragResizeListener.setGeometry(
+ new DragResizeWindowGeometry(0 /* taskCornerRadius */,
+ new Size(mResult.mWidth, mResult.mHeight),
+ sizeRepository.getResizeEdgeHandlePixels(res),
+ getFineResizeCornerPixels(res), getLargeResizeCornerPixels(res)),
+ mDragDetector.getTouchSlop());
+ };
CaptionWindowDecoration(
Context context,
@@ -73,13 +91,15 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
SurfaceControl taskSurface,
Handler handler,
Choreographer choreographer,
- SyncTransactionQueue syncQueue) {
- super(context, displayController, taskOrganizer, taskInfo, taskSurface,
- taskInfo.getConfiguration());
+ SyncTransactionQueue syncQueue,
+ ResizeHandleSizeRepository resizeHandleSizeRepository) {
+ super(context, displayController, taskOrganizer, taskInfo, taskSurface);
mHandler = handler;
mChoreographer = choreographer;
mSyncQueue = syncQueue;
+ mResizeHandleSizeRepository = resizeHandleSizeRepository;
+ mResizeHandleSizeRepository.registerSizeChangeFunction(mResizeHandleSizeChangedFunction);
}
void setCaptionListeners(
@@ -238,10 +258,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
.getScaledTouchSlop();
mDragDetector.setTouchSlop(touchSlop);
- final Resources res = mResult.mRootView.getResources();
- mDragResizeListener.setGeometry(new DragResizeWindowGeometry(0 /* taskCornerRadius */,
- new Size(mResult.mWidth, mResult.mHeight), getResizeEdgeHandleSize(res),
- getFineResizeCornerSize(res), getLargeResizeCornerSize(res)), touchSlop);
+ mResizeHandleSizeChangedFunction.accept(mResizeHandleSizeRepository);
}
/**
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 9afb057ffbe5..10ab13a74042 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
@@ -149,6 +149,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
new DesktopModeKeyguardChangeListener();
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
private final DisplayInsetsController mDisplayInsetsController;
+ private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
private final Region mExclusionRegion = Region.obtain();
private boolean mInImmersiveMode;
@@ -181,7 +182,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
SyncTransactionQueue syncQueue,
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ ResizeHandleSizeRepository resizeHandleSizeRepository
) {
this(
context,
@@ -202,7 +204,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
new InputMonitorFactory(),
SurfaceControl.Transaction::new,
rootTaskDisplayAreaOrganizer,
- new SparseArray<>());
+ new SparseArray<>(),
+ resizeHandleSizeRepository);
}
@VisibleForTesting
@@ -225,7 +228,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
InputMonitorFactory inputMonitorFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
+ SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId,
+ ResizeHandleSizeRepository resizeHandleSizeRepository) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -246,6 +250,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
mInputManager = mContext.getSystemService(InputManager.class);
mWindowDecorByTaskId = windowDecorByTaskId;
+ mResizeHandleSizeRepository = resizeHandleSizeRepository;
shellInit.addInitCallback(this::onInit, this);
}
@@ -1060,7 +1065,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mMainHandler,
mMainChoreographer,
mSyncQueue,
- mRootTaskDisplayAreaOrganizer);
+ mRootTaskDisplayAreaOrganizer,
+ mResizeHandleSizeRepository);
mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
final DragPositioningCallback dragPositioningCallback;
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 4d4dc3c72420..9c92791f255f 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
@@ -24,11 +24,11 @@ import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getFineResizeCornerPixels;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getLargeResizeCornerPixels;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.WindowConfiguration.WindowingMode;
import android.content.Context;
@@ -60,13 +60,13 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.IconProvider;
+import com.android.window.flags.Flags;
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.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.shared.DesktopModeStatus;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder;
@@ -75,6 +75,7 @@ import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationVi
import kotlin.Unit;
+import java.util.function.Function;
import java.util.function.Supplier;
/**
@@ -96,6 +97,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private View.OnLongClickListener mOnCaptionLongClickListener;
private View.OnGenericMotionListener mOnCaptionGenericMotionListener;
private DragPositioningCallback mDragPositioningCallback;
+ // Listener for handling drag resize events. Will be null if the task cannot be resized.
+ @Nullable
private DragResizeInputListener mDragResizeListener;
private DragDetector mDragDetector;
@@ -118,22 +121,35 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+ private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
+ private final Function<ResizeHandleSizeRepository, Boolean> mResizeHandleSizeChangedFunction =
+ (ResizeHandleSizeRepository sizeRepository) -> {
+ final Resources res = mResult.mRootView.getResources();
+ return mDragResizeListener == null || mDragResizeListener.setGeometry(
+ new DragResizeWindowGeometry(mRelayoutParams.mCornerRadius,
+ new Size(mResult.mWidth, mResult.mHeight),
+ sizeRepository.getResizeEdgeHandlePixels(res),
+ getFineResizeCornerPixels(res),
+ getLargeResizeCornerPixels(res)),
+ mDragDetector.getTouchSlop());
+ };
+
DesktopModeWindowDecoration(
Context context,
DisplayController displayController,
ShellTaskOrganizer taskOrganizer,
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
- Configuration windowDecorConfig,
Handler handler,
Choreographer choreographer,
SyncTransactionQueue syncQueue,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
- this (context, displayController, taskOrganizer, taskInfo, taskSurface, windowDecorConfig,
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ ResizeHandleSizeRepository resizeHandleSizeRepository) {
+ this (context, displayController, taskOrganizer, taskInfo, taskSurface,
handler, choreographer, syncQueue, rootTaskDisplayAreaOrganizer,
- SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
- WindowContainerTransaction::new, SurfaceControl::new,
- new SurfaceControlViewHostFactory() {});
+ resizeHandleSizeRepository, SurfaceControl.Builder::new,
+ SurfaceControl.Transaction::new, WindowContainerTransaction::new,
+ SurfaceControl::new, new SurfaceControlViewHostFactory() {});
}
DesktopModeWindowDecoration(
@@ -142,17 +158,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
ShellTaskOrganizer taskOrganizer,
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
- Configuration windowDecorConfig,
Handler handler,
Choreographer choreographer,
SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ ResizeHandleSizeRepository resizeHandleSizeRepository,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
Supplier<SurfaceControl> surfaceControlSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
- super(context, displayController, taskOrganizer, taskInfo, taskSurface, windowDecorConfig,
+ super(context, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
surfaceControlViewHostFactory);
@@ -160,6 +176,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mChoreographer = choreographer;
mSyncQueue = syncQueue;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+ mResizeHandleSizeRepository = resizeHandleSizeRepository;
+ mResizeHandleSizeRepository.registerSizeChangeFunction(
+ mResizeHandleSizeChangedFunction::apply);
}
void setCaptionListeners(
@@ -305,11 +324,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
// If either task geometry or position have changed, update this task's
// exclusion region listener
- final Resources res = mResult.mRootView.getResources();
- if (mDragResizeListener.setGeometry(
- new DragResizeWindowGeometry(mRelayoutParams.mCornerRadius,
- new Size(mResult.mWidth, mResult.mHeight), getResizeEdgeHandleSize(res),
- getFineResizeCornerSize(res), getLargeResizeCornerSize(res)), touchSlop)
+ if (mResizeHandleSizeChangedFunction.apply(mResizeHandleSizeRepository)
|| !mTaskInfo.positionInParent.equals(mPositionInParent)) {
updateExclusionRegion();
}
@@ -332,13 +347,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
boolean applyStartTransactionOnDraw,
boolean shouldSetTaskPositionAndCrop) {
final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode());
+ final boolean isAppHeader =
+ captionLayoutId == R.layout.desktop_mode_app_controls_window_decor;
+ final boolean isAppHandle = captionLayoutId == R.layout.desktop_mode_focused_window_decor;
relayoutParams.reset();
relayoutParams.mRunningTaskInfo = taskInfo;
relayoutParams.mLayoutResId = captionLayoutId;
relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
- if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor) {
+ if (isAppHeader) {
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
@@ -359,7 +377,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
controlsElement.mWidthResId = R.dimen.desktop_mode_customizable_caption_margin_end;
controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
relayoutParams.mOccludingCaptionElements.add(controlsElement);
- } else if (captionLayoutId == R.layout.desktop_mode_focused_window_decor) {
+ } else if (isAppHandle) {
// The focused decor (fullscreen/split) does not need to handle input because input in
// the App Handle is handled by the InputMonitor in DesktopModeWindowDecorViewModel.
relayoutParams.mInputFeatures
@@ -372,19 +390,25 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
relayoutParams.mSetTaskPositionAndCrop = shouldSetTaskPositionAndCrop;
- // The configuration used to lay out the window decoration. The system context's config is
- // used when the task density has been overridden to a custom density so that the resources
- // and views of the decoration aren't affected and match the rest of the System UI, if not
- // then just use the task's configuration. A copy is made instead of using the original
- // reference so that the configuration isn't mutated on config changes and diff checks can
- // be made in WindowDecoration#relayout using the pre/post-relayout configuration.
- // See b/301119301.
+
+ // The configuration used to layout the window decoration. A copy is made instead of using
+ // the original reference so that the configuration isn't mutated on config changes and
+ // diff checks can be made in WindowDecoration#relayout using the pre/post-relayout
+ // configuration. See b/301119301.
// TODO(b/301119301): consider moving the config data needed for diffs to relayout params
// instead of using a whole Configuration as a parameter.
final Configuration windowDecorConfig = new Configuration();
- windowDecorConfig.setTo(DesktopTasksController.isDesktopDensityOverrideSet()
- ? context.getResources().getConfiguration() // Use system context.
- : taskInfo.configuration); // Use task configuration.
+ if (Flags.enableAppHeaderWithTaskDensity() && isAppHeader) {
+ // Should match the density of the task. The task may have had its density overridden
+ // to be different that SysUI's.
+ windowDecorConfig.setTo(taskInfo.configuration);
+ } else if (DesktopModeStatus.isDesktopDensityOverrideSet()) {
+ // The task has had its density overridden, but keep using the system's density to
+ // layout the header.
+ windowDecorConfig.setTo(context.getResources().getConfiguration());
+ } else {
+ windowDecorConfig.setTo(taskInfo.configuration);
+ }
relayoutParams.mWindowDecorConfig = windowDecorConfig;
if (DesktopModeStatus.useRoundedCorners()) {
@@ -936,22 +960,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
Handler handler,
Choreographer choreographer,
SyncTransactionQueue syncQueue,
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
- final Configuration windowDecorConfig =
- DesktopTasksController.isDesktopDensityOverrideSet()
- ? context.getResources().getConfiguration() // Use system context
- : taskInfo.configuration; // Use task configuration
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+ ResizeHandleSizeRepository resizeHandleSizeRepository) {
return new DesktopModeWindowDecoration(
context,
displayController,
taskOrganizer,
taskInfo,
taskSurface,
- windowDecorConfig,
handler,
choreographer,
syncQueue,
- rootTaskDisplayAreaOrganizer);
+ rootTaskDisplayAreaOrganizer,
+ resizeHandleSizeRepository);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
index da268988bac7..a3b0a7122752 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
@@ -119,6 +119,10 @@ class DragDetector {
mTouchSlop = touchSlop;
}
+ int getTouchSlop() {
+ return mTouchSlop;
+ }
+
private void resetState() {
mIsDragEvent = false;
mInputDownPoint.set(0, 0);
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 4f513f0a0fd8..80d60d4fbdd0 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
@@ -26,7 +26,6 @@ import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED;
import android.annotation.NonNull;
-import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
@@ -36,8 +35,6 @@ import android.view.MotionEvent;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.wm.shell.R;
-
import java.util.Objects;
/**
@@ -63,6 +60,10 @@ final class DragResizeWindowGeometry {
// Extra-large edge bounds for logging to help debug when an edge resize is ignored.
private final @Nullable TaskEdges mDebugTaskEdges;
+ /**
+ * Constructs an instance representing the drag resize touch input regions, where all sizes
+ * are represented in pixels.
+ */
DragResizeWindowGeometry(int taskCornerRadius, @NonNull Size taskSize,
int resizeHandleThickness, int fineCornerSize, int largeCornerSize) {
mTaskCornerRadius = taskCornerRadius;
@@ -82,31 +83,6 @@ final class DragResizeWindowGeometry {
}
/**
- * Returns the resource value to use for the resize handle on the edge of the window.
- */
- static int getResizeEdgeHandleSize(@NonNull Resources res) {
- return enableWindowingEdgeDragResize()
- ? res.getDimensionPixelSize(R.dimen.desktop_mode_edge_handle)
- : res.getDimensionPixelSize(R.dimen.freeform_resize_handle);
- }
-
- /**
- * Returns the resource value to use for course input, such as touch, that benefits from a large
- * square on each of the window's corners.
- */
- static int getLargeResizeCornerSize(@NonNull Resources res) {
- return res.getDimensionPixelSize(R.dimen.desktop_mode_corner_resize_large);
- }
-
- /**
- * Returns the resource value to use for fine input, such as stylus, that can use a smaller
- * square on each of the window's corners.
- */
- static int getFineResizeCornerSize(@NonNull Resources res) {
- return res.getDimensionPixelSize(R.dimen.freeform_resize_corner);
- }
-
- /**
* Returns the size of the task this geometry is calculated for.
*/
@NonNull Size getTaskSize() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt
new file mode 100644
index 000000000000..be7a301ec4c3
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.content.res.Resources
+import com.android.window.flags.Flags.enableWindowingEdgeDragResize
+import com.android.wm.shell.R
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.util.KtProtoLog
+import java.util.function.Consumer
+
+/** Repository for desktop mode drag resize handle sizes. */
+class ResizeHandleSizeRepository {
+ private val TAG = "ResizeHandleSizeRepository"
+ private var edgeResizeHandleSizePixels: Int? = null
+ private var sizeChangeFunctions: MutableList<Consumer<ResizeHandleSizeRepository>> =
+ mutableListOf()
+
+ /**
+ * Resets the window edge resize handle size if necessary.
+ */
+ fun resetResizeEdgeHandlePixels() {
+ if (enableWindowingEdgeDragResize() && edgeResizeHandleSizePixels != null) {
+ edgeResizeHandleSizePixels = null
+ applyToAll()
+ }
+ }
+
+ /**
+ * Sets the window edge resize handle to the given size in pixels.
+ */
+ fun setResizeEdgeHandlePixels(sizePixels: Int) {
+ if (enableWindowingEdgeDragResize()) {
+ KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "$TAG: Set edge handle size to $sizePixels")
+ if (edgeResizeHandleSizePixels != null && edgeResizeHandleSizePixels == sizePixels) {
+ // Skip updating since override is the same size
+ return
+ }
+ edgeResizeHandleSizePixels = sizePixels
+ applyToAll()
+ } else {
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "$TAG: Can't set edge handle size to $sizePixels since " +
+ "enable_windowing_edge_drag_resize disabled"
+ )
+ }
+ }
+
+ /**
+ * Returns the resource value, in pixels, to use for the resize handle on the edge of the
+ * window.
+ */
+ fun getResizeEdgeHandlePixels(res: Resources): Int {
+ try {
+ return if (enableWindowingEdgeDragResize()) {
+ val resPixelSize = res.getDimensionPixelSize(R.dimen.desktop_mode_edge_handle)
+ val size = edgeResizeHandleSizePixels ?: resPixelSize
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "$TAG: Get edge handle size of $size from (vs base value $resPixelSize)"
+ )
+ size
+ } else {
+ KtProtoLog.d(
+ WM_SHELL_DESKTOP_MODE,
+ "$TAG: Get edge handle size from freeform since flag is disabled"
+ )
+ res.getDimensionPixelSize(R.dimen.freeform_resize_handle)
+ }
+ } catch (e: Resources.NotFoundException) {
+ KtProtoLog.e(WM_SHELL_DESKTOP_MODE, "$TAG: Unable to get edge handle size", e)
+ return 0
+ }
+ }
+
+ /** Register function to run when the resize handle size changes. */
+ fun registerSizeChangeFunction(function: Consumer<ResizeHandleSizeRepository>) {
+ sizeChangeFunctions.add(function)
+ }
+
+ private fun applyToAll() {
+ for (f in sizeChangeFunctions) {
+ f.accept(this)
+ }
+ }
+
+ companion object {
+ private val TAG = "ResizeHandleSizeRepositoryCompanion"
+
+ /**
+ * Returns the resource value in pixels to use for course input, such as touch, that
+ * benefits from a large square on each of the window's corners.
+ */
+ @JvmStatic
+ fun getLargeResizeCornerPixels(res: Resources): Int {
+ return try {
+ res.getDimensionPixelSize(R.dimen.desktop_mode_corner_resize_large)
+ } catch (e: Resources.NotFoundException) {
+ KtProtoLog.e(WM_SHELL_DESKTOP_MODE, "$TAG: Unable to get large corner size", e)
+ 0
+ }
+ }
+
+ /**
+ * Returns the resource value, in pixels, to use for fine input, such as stylus, that can
+ * use a smaller square on each of the window's corners.
+ */
+ @JvmStatic
+ fun getFineResizeCornerPixels(res: Resources): Int {
+ return try {
+ res.getDimensionPixelSize(R.dimen.freeform_resize_corner)
+ } catch (e: Resources.NotFoundException) {
+ KtProtoLog.e(WM_SHELL_DESKTOP_MODE, "$TAG: Unable to get fine corner size", e)
+ 0
+ }
+ }
+ }
+}
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 541825437c86..2cbe47212c63 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
@@ -18,6 +18,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.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
import static android.view.WindowInsets.Type.statusBars;
@@ -145,9 +146,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
DisplayController displayController,
ShellTaskOrganizer taskOrganizer,
RunningTaskInfo taskInfo,
- SurfaceControl taskSurface,
- Configuration windowDecorConfig) {
- this(context, displayController, taskOrganizer, taskInfo, taskSurface, windowDecorConfig,
+ SurfaceControl taskSurface) {
+ this(context, displayController, taskOrganizer, taskInfo, taskSurface,
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, SurfaceControl::new,
new SurfaceControlViewHostFactory() {});
@@ -159,7 +159,6 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
ShellTaskOrganizer taskOrganizer,
RunningTaskInfo taskInfo,
@NonNull SurfaceControl taskSurface,
- Configuration windowDecorConfig,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
@@ -176,8 +175,6 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mSurfaceControlViewHostFactory = surfaceControlViewHostFactory;
mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
- mWindowDecorConfig = windowDecorConfig;
- mDecorWindowContext = mContext.createConfigurationContext(mWindowDecorConfig);
}
/**
@@ -220,8 +217,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
outResult.mRootView = rootView;
rootView = null; // Clear it just in case we use it accidentally
- final int oldDensityDpi = mWindowDecorConfig.densityDpi;
- final int oldNightMode = mWindowDecorConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ final int oldDensityDpi = mWindowDecorConfig != null
+ ? mWindowDecorConfig.densityDpi : DENSITY_DPI_UNDEFINED;
+ final int oldNightMode = mWindowDecorConfig != null
+ ? (mWindowDecorConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+ : Configuration.UI_MODE_NIGHT_UNDEFINED;
mWindowDecorConfig = params.mWindowDecorConfig != null ? params.mWindowDecorConfig
: mTaskInfo.getConfiguration();
final int newDensityDpi = mWindowDecorConfig.densityDpi;
@@ -230,7 +230,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
|| mDisplay == null
|| mDisplay.getDisplayId() != mTaskInfo.displayId
|| oldLayoutResId != mLayoutResId
- || oldNightMode != newNightMode) {
+ || oldNightMode != newNightMode
+ || mDecorWindowContext == null) {
releaseViews(wct);
if (!obtainDisplayOrRegisterListener()) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index 8de60b7acc91..cfe8e07aa6e5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -26,6 +26,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_STA
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
@@ -115,9 +116,9 @@ public class SplitLayoutTests extends ShellTestCase {
@Test
public void testUpdateDivideBounds() {
- mSplitLayout.updateDividerBounds(anyInt());
+ mSplitLayout.updateDividerBounds(anyInt(), anyBoolean());
verify(mSplitLayoutHandler).onLayoutSizeChanging(any(SplitLayout.class), anyInt(),
- anyInt());
+ anyInt(), anyBoolean());
}
@Test
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 f67da5573b7d..d8d534bec6ea 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
@@ -25,6 +25,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.content.Intent
import android.content.pm.ActivityInfo
+import android.content.pm.ActivityInfo.CONFIG_DENSITY
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
@@ -115,6 +116,8 @@ import org.mockito.kotlin.atLeastOnce
import org.mockito.kotlin.capture
import org.mockito.quality.Strictness
import java.util.Optional
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
import org.mockito.Mockito.`when` as whenever
/**
@@ -1045,17 +1048,6 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun handleRequest_freeformTask_freeformVisible_returnNull() {
- assumeTrue(ENABLE_SHELL_TRANSITIONS)
-
- val freeformTask1 = setUpFreeformTask()
- markTaskVisible(freeformTask1)
-
- val freeformTask2 = createFreeformTask()
- assertThat(controller.handleRequest(Binder(), createTransition(freeformTask2))).isNull()
- }
-
- @Test
fun handleRequest_freeformTask_freeformVisible_aboveTaskLimit_minimize() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
@@ -1072,7 +1064,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun handleRequest_freeformTask_freeformNotVisible_returnSwitchToFullscreenWCT() {
+ fun handleRequest_freeformTask_freeformNotVisible_reorderedToTop() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
val freeformTask1 = setUpFreeformTask()
@@ -1084,30 +1076,60 @@ class DesktopTasksControllerTest : ShellTestCase() {
Binder(),
createTransition(freeformTask2, type = TRANSIT_TO_FRONT)
)
- assertThat(result?.changes?.get(freeformTask2.token.asBinder())?.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+
+ assertThat(result?.hierarchyOps?.size).isEqualTo(2)
+ result!!.assertReorderAt(1, freeformTask2, toTop = true)
}
@Test
- fun handleRequest_freeformTask_noOtherTasks_returnSwitchToFullscreenWCT() {
+ fun handleRequest_freeformTask_noOtherTasks_reorderedToTop() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
val task = createFreeformTask()
val result = controller.handleRequest(Binder(), createTransition(task))
- assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+
+ assertThat(result?.hierarchyOps?.size).isEqualTo(1)
+ result!!.assertReorderAt(0, task, toTop = true)
}
@Test
- fun handleRequest_freeformTask_freeformOnOtherDisplayOnly_returnSwitchToFullscreenWCT() {
+ fun handleRequest_freeformTask_freeformOnOtherDisplayOnly_reorderedToTop() {
assumeTrue(ENABLE_SHELL_TRANSITIONS)
val taskDefaultDisplay = createFreeformTask(displayId = DEFAULT_DISPLAY)
- createFreeformTask(displayId = SECOND_DISPLAY)
+ val taskSecondDisplay = createFreeformTask(displayId = SECOND_DISPLAY)
val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay))
- assertThat(result?.changes?.get(taskDefaultDisplay.token.asBinder())?.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+ assertThat(result?.hierarchyOps?.size).isEqualTo(1)
+ result!!.assertReorderAt(0, taskDefaultDisplay, toTop = true)
+ }
+
+ @Test
+ fun handleRequest_freeformTask_alreadyInDesktop_noOverrideDensity_noConfigDensityChange() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(false)
+
+ val freeformTask1 = setUpFreeformTask()
+ markTaskVisible(freeformTask1)
+
+ val freeformTask2 = createFreeformTask()
+ val result = controller.handleRequest(freeformTask2.token.asBinder(),
+ createTransition(freeformTask2))
+ assertFalse(result.anyDensityConfigChange(freeformTask2.token))
+ }
+
+ @Test
+ fun handleRequest_freeformTask_alreadyInDesktop_overrideDensity_hasConfigDensityChange() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(true)
+
+ val freeformTask1 = setUpFreeformTask()
+ markTaskVisible(freeformTask1)
+
+ val freeformTask2 = createFreeformTask()
+ val result = controller.handleRequest(freeformTask2.token.asBinder(),
+ createTransition(freeformTask2))
+ assertTrue(result.anyDensityConfigChange(freeformTask2.token))
}
@Test
@@ -1811,3 +1833,11 @@ private fun WindowContainerTransaction.assertPendingIntentAt(index: Int, intent:
assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_PENDING_INTENT)
assertThat(op.pendingIntent?.intent?.component).isEqualTo(intent.component)
}
+
+private fun WindowContainerTransaction?.anyDensityConfigChange(
+ token: WindowContainerToken
+): Boolean {
+ return this?.changes?.any { change ->
+ change.key == token.asBinder() && ((change.value.configSetMask and CONFIG_DENSITY) != 0)
+ } ?: false
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index d7c383523a6f..d18fec2f24ad 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -16,10 +16,7 @@
package com.android.wm.shell.splitscreen;
-import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
-import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -31,8 +28,9 @@ import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;
@@ -45,6 +43,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -54,7 +53,6 @@ import android.os.Looper;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.RemoteTransition;
-import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.test.annotation.UiThreadTest;
@@ -343,14 +341,14 @@ public class StageCoordinatorTests extends ShellTestCase {
@Test
public void testAddActivityOptions_addsBackgroundActivitiesFlags() {
- Bundle options = mStageCoordinator.resolveStartStage(STAGE_TYPE_MAIN,
+ Bundle bundle = mStageCoordinator.resolveStartStage(STAGE_TYPE_MAIN,
SPLIT_POSITION_UNDEFINED, null /* options */, null /* wct */);
+ ActivityOptions options = ActivityOptions.fromBundle(bundle);
- assertEquals(options.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, WindowContainerToken.class),
- mMainStage.mRootTaskInfo.token);
- assertTrue(options.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED));
- assertTrue(options.getBoolean(
- KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION));
+ assertThat(options.getLaunchRootTask()).isEqualTo(mMainStage.mRootTaskInfo.token);
+ assertThat(options.getPendingIntentBackgroundActivityStartMode())
+ .isEqualTo(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ assertThat(options.isPendingIntentBackgroundActivityLaunchAllowedByPermission()).isTrue();
}
@Test
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 aa2cee79fcfc..282495de0fc1 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
@@ -121,6 +121,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Mock private lateinit var mockShellController: ShellController
@Mock private lateinit var mockShellExecutor: ShellExecutor
@Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
+ @Mock private lateinit var mockResizeHandleSizeRepository: ResizeHandleSizeRepository
@Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
@Mock private lateinit var mockWindowManager: IWindowManager
@@ -156,7 +157,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockInputMonitorFactory,
transactionFactory,
mockRootTaskDisplayAreaOrganizer,
- windowDecorByTaskIdSpy
+ windowDecorByTaskIdSpy,
+ mockResizeHandleSizeRepository
)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -197,7 +199,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockMainHandler,
mockMainChoreographer,
mockSyncQueue,
- mockRootTaskDisplayAreaOrganizer
+ mockRootTaskDisplayAreaOrganizer,
+ mockResizeHandleSizeRepository
)
verify(decoration).close()
}
@@ -221,7 +224,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockMainHandler,
mockMainChoreographer,
mockSyncQueue,
- mockRootTaskDisplayAreaOrganizer
+ mockRootTaskDisplayAreaOrganizer,
+ mockResizeHandleSizeRepository
)
task.setWindowingMode(WINDOWING_MODE_FREEFORM)
@@ -236,7 +240,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockMainHandler,
mockMainChoreographer,
mockSyncQueue,
- mockRootTaskDisplayAreaOrganizer
+ mockRootTaskDisplayAreaOrganizer,
+ mockResizeHandleSizeRepository
)
}
@@ -296,7 +301,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onTaskChanging(task)
verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
}
@Test
@@ -309,7 +314,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onTaskOpening(task)
verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
}
@Test
@@ -406,7 +411,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onTaskOpening(task)
verify(mockDesktopModeWindowDecorFactory, never())
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
} finally {
mockitoSession.finishMocking()
}
@@ -430,7 +435,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onTaskOpening(task)
verify(mockDesktopModeWindowDecorFactory)
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
} finally {
mockitoSession.finishMocking()
}
@@ -453,7 +458,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onTaskOpening(task)
verify(mockDesktopModeWindowDecorFactory)
- .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
} finally {
mockitoSession.finishMocking()
}
@@ -497,7 +502,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
val decoration = mock(DesktopModeWindowDecoration::class.java)
whenever(
mockDesktopModeWindowDecorFactory.create(
- any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+ any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
).thenReturn(decoration)
decoration.mTaskInfo = task
whenever(decoration.isFocused).thenReturn(task.isFocused)
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 608f74b95280..e737861873d2 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
@@ -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.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND;
import static com.google.common.truth.Truth.assertThat;
@@ -39,6 +40,9 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.SystemProperties;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.view.Choreographer;
@@ -51,6 +55,7 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
+import com.android.window.flags.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
@@ -61,6 +66,7 @@ import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -83,6 +89,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private static final String USE_ROUNDED_CORNERS_SYSPROP_KEY =
"persist.wm.debug.desktop_use_rounded_corners";
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
@Mock
private DisplayController mMockDisplayController;
@Mock
@@ -107,6 +115,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private WindowDecoration.SurfaceControlViewHostFactory mMockSurfaceControlViewHostFactory;
@Mock
private TypedArray mMockRoundedCornersRadiusArray;
+ @Mock
+ private ResizeHandleSizeRepository mMockResizeHandleSizeRepository;
private final Configuration mConfiguration = new Configuration();
@@ -175,6 +185,48 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY)
+ public void updateRelayoutParams_appHeader_usesTaskDensity() {
+ final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources()
+ .getConfiguration().densityDpi;
+ final int customTaskDensity = systemDensity + 300;
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ taskInfo.configuration.densityDpi = customTaskDensity;
+ final RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false);
+
+ assertThat(relayoutParams.mWindowDecorConfig.densityDpi).isEqualTo(customTaskDensity);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY)
+ public void updateRelayoutParams_appHeader_usesSystemDensity() {
+ final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources()
+ .getConfiguration().densityDpi;
+ final int customTaskDensity = systemDensity + 300;
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ taskInfo.configuration.densityDpi = customTaskDensity;
+ final RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false);
+
+ assertThat(relayoutParams.mWindowDecorConfig.densityDpi).isEqualTo(systemDensity);
+ }
+
+ @Test
public void updateRelayoutParams_freeformAndTransparentAppearance_allowsInputFallthrough() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -294,10 +346,10 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private DesktopModeWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo) {
return new DesktopModeWindowDecoration(mContext, mMockDisplayController,
- mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl, mConfiguration,
+ mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl,
mMockHandler, mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
- SurfaceControl.Builder::new, mMockTransactionSupplier,
- WindowContainerTransaction::new, SurfaceControl::new,
+ mMockResizeHandleSizeRepository, SurfaceControl.Builder::new,
+ mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new,
mMockSurfaceControlViewHostFactory);
}
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 54645083eca8..62fb1c441118 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
@@ -27,10 +27,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.annotation.NonNull;
import android.graphics.Point;
import android.graphics.Region;
-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.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.util.Size;
@@ -74,7 +71,7 @@ public class DragResizeWindowGeometryTests {
TASK_SIZE.getHeight() + EDGE_RESIZE_THICKNESS / 2);
@Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
/**
* Check that both groups of objects satisfy equals/hashcode within each group, and that each
@@ -147,8 +144,8 @@ public class DragResizeWindowGeometryTests {
* capture all eligible input regardless of source (touch or cursor).
*/
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
public void testRegionUnion_edgeDragResizeEnabled_containsLargeCorners() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
Region region = new Region();
GEOMETRY.union(region);
// Make sure we're choosing a point outside of any debug region buffer.
@@ -164,8 +161,8 @@ public class DragResizeWindowGeometryTests {
* size.
*/
@Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
public void testRegionUnion_edgeDragResizeDisabled_containsFineCorners() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
Region region = new Region();
GEOMETRY.union(region);
final int cornerRadius = DragResizeWindowGeometry.DEBUG
@@ -176,16 +173,16 @@ public class DragResizeWindowGeometryTests {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
public void testCalculateControlType_edgeDragResizeEnabled_edges() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
// The input source (touch or cursor) shouldn't impact the edge resize size.
validateCtrlTypeForEdges(/* isTouch= */ false);
validateCtrlTypeForEdges(/* isTouch= */ true);
}
@Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
public void testCalculateControlType_edgeDragResizeDisabled_edges() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
// Edge resizing is not supported when the flag is disabled.
validateCtrlTypeForEdges(/* isTouch= */ false);
validateCtrlTypeForEdges(/* isTouch= */ false);
@@ -203,8 +200,8 @@ public class DragResizeWindowGeometryTests {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
public void testCalculateControlType_edgeDragResizeEnabled_corners() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
final TestPoints fineTestPoints = new TestPoints(TASK_SIZE, FINE_CORNER_SIZE / 2);
final TestPoints largeCornerTestPoints = new TestPoints(TASK_SIZE, LARGE_CORNER_SIZE / 2);
@@ -226,8 +223,8 @@ public class DragResizeWindowGeometryTests {
}
@Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
public void testCalculateControlType_edgeDragResizeDisabled_corners() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
final TestPoints fineTestPoints = new TestPoints(TASK_SIZE, FINE_CORNER_SIZE / 2);
final TestPoints largeCornerTestPoints = new TestPoints(TASK_SIZE, LARGE_CORNER_SIZE / 2);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt
new file mode 100644
index 000000000000..a9fddc623b96
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt
@@ -0,0 +1,150 @@
+/*
+ * 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.content.Context
+import android.platform.test.flag.junit.SetFlagsRule
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import java.util.function.Consumer
+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.Parameter
+import org.junit.runners.Parameterized.Parameters
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for {@link ResizeHandleSizeRepository}.
+ *
+ * Build/Install/Run: atest WMShellUnitTests:ResizeHandleSizeRepositoryParameterizedTests
+ */
+@SmallTest
+@RunWith(Parameterized::class)
+class ResizeHandleSizeRepositoryParameterizedTests {
+ private val resources = ApplicationProvider.getApplicationContext<Context>().resources
+ private val resizeHandleSizeRepository = ResizeHandleSizeRepository()
+ @Mock private lateinit var mockSizeChangeFunctionOne: Consumer<ResizeHandleSizeRepository>
+ @Mock private lateinit var mockSizeChangeFunctionTwo: Consumer<ResizeHandleSizeRepository>
+
+ @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+ @Parameter(0) lateinit var name: String
+ // The current ResizeHandleSizeRepository API under test.
+
+ @Parameter(1) lateinit var operation: (ResizeHandleSizeRepository) -> Unit
+
+ @Before
+ fun setOverrideBeforeResetResizeHandle() {
+ MockitoAnnotations.initMocks(this)
+ if (name != "reset") return
+ val originalEdgeHandle =
+ resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources)
+ resizeHandleSizeRepository.setResizeEdgeHandlePixels(originalEdgeHandle + 2)
+ }
+
+ companion object {
+ @Parameters(name = "{index}: {0}")
+ @JvmStatic
+ fun data(): Iterable<Array<Any>> {
+ return listOf(
+ arrayOf(
+ "reset",
+ { sizeRepository: ResizeHandleSizeRepository ->
+ sizeRepository.resetResizeEdgeHandlePixels()
+ }
+ ),
+ arrayOf(
+ "set",
+ { sizeRepository: ResizeHandleSizeRepository ->
+ sizeRepository.setResizeEdgeHandlePixels(99)
+ }
+ )
+ )
+ }
+ }
+
+ // =================
+ // Validate that listeners are notified correctly for reset resize handle API.
+ // =================
+
+ @Test
+ fun testUpdateResizeHandleSize_flagDisabled() {
+ setFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ registerSizeChangeFunctions()
+ operation.invoke(resizeHandleSizeRepository)
+ // Nothing is notified since flag is disabled.
+ verify(mockSizeChangeFunctionOne, never()).accept(any())
+ verify(mockSizeChangeFunctionTwo, never()).accept(any())
+ }
+
+ @Test
+ fun testUpdateResizeHandleSize_flagEnabled_noListeners() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ operation.invoke(resizeHandleSizeRepository)
+ // Nothing is notified since nothing was registered.
+ verify(mockSizeChangeFunctionOne, never()).accept(any())
+ verify(mockSizeChangeFunctionTwo, never()).accept(any())
+ }
+
+ @Test
+ fun testUpdateResizeHandleSize_flagEnabled_listenersNotified() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ registerSizeChangeFunctions()
+ operation.invoke(resizeHandleSizeRepository)
+ // Functions notified when reset.
+ verify(mockSizeChangeFunctionOne).accept(any())
+ verify(mockSizeChangeFunctionTwo).accept(any())
+ }
+
+ @Test
+ fun testUpdateResizeHandleSize_flagEnabled_listenerFails() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ registerSizeChangeFunctions()
+ operation.invoke(resizeHandleSizeRepository)
+ // Functions notified when reset.
+ verify(mockSizeChangeFunctionOne).accept(any())
+ verify(mockSizeChangeFunctionTwo).accept(any())
+ }
+
+ @Test
+ fun testUpdateResizeHandleSize_flagEnabled_ignoreSecondListener() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ registerSizeChangeFunctions()
+ val extraConsumerMock = mock(Consumer::class.java) as Consumer<ResizeHandleSizeRepository>
+ resizeHandleSizeRepository.registerSizeChangeFunction(extraConsumerMock)
+ // First listener succeeds, second one that fails is ignored.
+ operation.invoke(resizeHandleSizeRepository)
+ // Functions notified when reset.
+ verify(mockSizeChangeFunctionOne).accept(any())
+ verify(mockSizeChangeFunctionTwo).accept(any())
+ verify(extraConsumerMock).accept(any())
+ }
+
+ private fun registerSizeChangeFunctions() {
+ resizeHandleSizeRepository.registerSizeChangeFunction(mockSizeChangeFunctionOne)
+ resizeHandleSizeRepository.registerSizeChangeFunction(mockSizeChangeFunctionTwo)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.kt
new file mode 100644
index 000000000000..59bbc72a733b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.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.wm.shell.windowdecor
+
+import android.content.Context
+import android.platform.test.flag.junit.SetFlagsRule
+import android.testing.AndroidTestingRunner
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for {@link ResizeHandleSizeRepository}. Validate that get/reset/set work correctly.
+ *
+ * Build/Install/Run: atest WMShellUnitTests:ResizeHandleSizeRepositoryTests
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ResizeHandleSizeRepositoryTests {
+ private val resources = ApplicationProvider.getApplicationContext<Context>().resources
+ private val resizeHandleSizeRepository = ResizeHandleSizeRepository()
+
+ @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+ @Test
+ fun testOverrideResizeEdgeHandlePixels_flagEnabled_resetSucceeds() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ // Reset does nothing when no override is set.
+ val originalEdgeHandle =
+ resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources)
+ resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+ assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+ .isEqualTo(originalEdgeHandle)
+
+ // Now try to set the value; reset should succeed.
+ resizeHandleSizeRepository.setResizeEdgeHandlePixels(originalEdgeHandle + 2)
+ resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+ assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+ .isEqualTo(originalEdgeHandle)
+ }
+
+ @Test
+ fun testOverrideResizeEdgeHandlePixels_flagDisabled_resetFails() {
+ setFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+ // Reset does nothing when no override is set.
+ val originalEdgeHandle =
+ resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources)
+ resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+ assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+ .isEqualTo(originalEdgeHandle)
+
+ // Now try to set the value; reset should do nothing.
+ val newEdgeHandle = originalEdgeHandle + 2
+ resizeHandleSizeRepository.setResizeEdgeHandlePixels(newEdgeHandle)
+ resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+ assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+ .isEqualTo(originalEdgeHandle)
+ }
+}
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 8b8cd119effd..48310810e8c9 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
@@ -49,7 +49,6 @@ import static org.mockito.quality.Strictness.LENIENT;
import android.app.ActivityManager;
import android.content.Context;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
@@ -134,7 +133,6 @@ public class WindowDecorationTests extends ShellTestCase {
private SurfaceControl.Transaction mMockSurfaceControlFinishT;
private SurfaceControl.Transaction mMockSurfaceControlAddWindowT;
private WindowDecoration.RelayoutParams mRelayoutParams = new WindowDecoration.RelayoutParams();
- private Configuration mWindowConfiguration = new Configuration();
private int mCaptionMenuWidthId;
@Before
@@ -303,7 +301,6 @@ public class WindowDecorationTests extends ShellTestCase {
taskInfo.isFocused = true;
// Density is 2. Shadow radius is 10px. Caption height is 64px.
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
- mWindowConfiguration.densityDpi = taskInfo.configuration.densityDpi;
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);
@@ -314,14 +311,16 @@ public class WindowDecorationTests extends ShellTestCase {
verify(mMockWindowContainerTransaction, never())
.removeInsetsSource(eq(taskInfo.token), any(), anyInt(), anyInt());
+ final SurfaceControl.Transaction t2 = mock(SurfaceControl.Transaction.class);
+ mMockSurfaceControlTransactions.add(t2);
taskInfo.isVisible = false;
windowDecor.relayout(taskInfo);
- final InOrder releaseOrder = inOrder(t, mMockSurfaceControlViewHost);
+ final InOrder releaseOrder = inOrder(t2, mMockSurfaceControlViewHost);
releaseOrder.verify(mMockSurfaceControlViewHost).release();
- releaseOrder.verify(t).remove(captionContainerSurface);
- releaseOrder.verify(t).remove(decorContainerSurface);
- releaseOrder.verify(t).apply();
+ releaseOrder.verify(t2).remove(captionContainerSurface);
+ releaseOrder.verify(t2).remove(decorContainerSurface);
+ releaseOrder.verify(t2).apply();
// Expect to remove two insets sources, the caption insets and the mandatory gesture insets.
verify(mMockWindowContainerTransaction, Mockito.times(2))
.removeInsetsSource(eq(taskInfo.token), any(), anyInt(), anyInt());
@@ -836,7 +835,7 @@ public class WindowDecorationTests extends ShellTestCase {
private TestWindowDecoration createWindowDecoration(ActivityManager.RunningTaskInfo taskInfo) {
return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
- taskInfo, mMockTaskSurface, mWindowConfiguration,
+ taskInfo, mMockTaskSurface,
new MockObjectSupplier<>(mMockSurfaceControlBuilders,
() -> createMockSurfaceControlBuilder(mock(SurfaceControl.class))),
new MockObjectSupplier<>(mMockSurfaceControlTransactions,
@@ -877,16 +876,15 @@ public class WindowDecorationTests extends ShellTestCase {
TestWindowDecoration(Context context, DisplayController displayController,
ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
- Configuration windowConfiguration,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
Supplier<SurfaceControl> surfaceControlSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
super(context, displayController, taskOrganizer, taskInfo, taskSurface,
- windowConfiguration, surfaceControlBuilderSupplier,
- surfaceControlTransactionSupplier, windowContainerTransactionSupplier,
- surfaceControlSupplier, surfaceControlViewHostFactory);
+ surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
+ windowContainerTransactionSupplier, surfaceControlSupplier,
+ surfaceControlViewHostFactory);
}
@Override
diff --git a/media/java/android/media/IMediaRouter2.aidl b/media/java/android/media/IMediaRouter2.aidl
index e2dddad274e1..85bc8efe2750 100644
--- a/media/java/android/media/IMediaRouter2.aidl
+++ b/media/java/android/media/IMediaRouter2.aidl
@@ -36,6 +36,5 @@ oneway interface IMediaRouter2 {
* Call MediaRouterService#requestCreateSessionWithRouter2 to pass the result.
*/
void requestCreateSessionByManager(long uniqueRequestId, in RoutingSessionInfo oldSession,
- in MediaRoute2Info route, in UserHandle transferInitiatorUserHandle,
- in String transferInitiatorPackageName);
+ in MediaRoute2Info route);
}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 63cb94516739..efbf8da6d17c 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -64,8 +64,7 @@ interface IMediaRouterService {
void requestCreateSessionWithRouter2(IMediaRouter2 router, int requestId, long managerRequestId,
in RoutingSessionInfo oldSession, in MediaRoute2Info route,
- in @nullable Bundle sessionHints, in UserHandle transferInitiatorUserHandle,
- in String transferInitiatorPackageName);
+ in @nullable Bundle sessionHints);
void selectRouteWithRouter2(IMediaRouter2 router, String sessionId, in MediaRoute2Info route);
void deselectRouteWithRouter2(IMediaRouter2 router, String sessionId, in MediaRoute2Info route);
void transferToRouteWithRouter2(IMediaRouter2 router, String sessionId,
diff --git a/media/java/android/media/LoudnessCodecDispatcher.java b/media/java/android/media/LoudnessCodecDispatcher.java
index fa08658a214f..bdd3c7396a5a 100644
--- a/media/java/android/media/LoudnessCodecDispatcher.java
+++ b/media/java/android/media/LoudnessCodecDispatcher.java
@@ -16,6 +16,9 @@
package android.media;
+import static android.media.MediaFormat.KEY_AAC_DRC_ALBUM_MODE;
+import static android.media.MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR;
+import static android.media.MediaFormat.KEY_AAC_DRC_BOOST_FACTOR;
import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
@@ -142,6 +145,18 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
filteredBundle.putInt(KEY_AAC_DRC_EFFECT_TYPE,
bundle.getInt(KEY_AAC_DRC_EFFECT_TYPE));
}
+ if (bundle.containsKey(KEY_AAC_DRC_BOOST_FACTOR)) {
+ filteredBundle.putInt(KEY_AAC_DRC_BOOST_FACTOR,
+ bundle.getInt(KEY_AAC_DRC_BOOST_FACTOR));
+ }
+ if (bundle.containsKey(KEY_AAC_DRC_ATTENUATION_FACTOR)) {
+ filteredBundle.putInt(KEY_AAC_DRC_ATTENUATION_FACTOR,
+ bundle.getInt(KEY_AAC_DRC_ATTENUATION_FACTOR));
+ }
+ if (bundle.containsKey(KEY_AAC_DRC_ALBUM_MODE)) {
+ filteredBundle.putInt(KEY_AAC_DRC_ALBUM_MODE,
+ bundle.getInt(KEY_AAC_DRC_ALBUM_MODE));
+ }
return filteredBundle;
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 7ddf11e41a41..679e8a1b95e6 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -991,9 +991,7 @@ public final class MediaRouter2 {
void requestCreateController(
@NonNull RoutingController controller,
@NonNull MediaRoute2Info route,
- long managerRequestId,
- @NonNull UserHandle transferInitiatorUserHandle,
- @NonNull String transferInitiatorPackageName) {
+ long managerRequestId) {
final int requestId = mNextRequestId.getAndIncrement();
@@ -1022,9 +1020,7 @@ public final class MediaRouter2 {
managerRequestId,
controller.getRoutingSessionInfo(),
route,
- controllerHints,
- transferInitiatorUserHandle,
- transferInitiatorPackageName);
+ controllerHints);
} catch (RemoteException ex) {
Log.e(TAG, "createControllerForTransfer: "
+ "Failed to request for creating a controller.", ex);
@@ -1366,11 +1362,7 @@ public final class MediaRouter2 {
}
void onRequestCreateControllerByManagerOnHandler(
- RoutingSessionInfo oldSession,
- MediaRoute2Info route,
- long managerRequestId,
- @NonNull UserHandle transferInitiatorUserHandle,
- @NonNull String transferInitiatorPackageName) {
+ RoutingSessionInfo oldSession, MediaRoute2Info route, long managerRequestId) {
Log.i(
TAG,
TextUtils.formatSimple(
@@ -1387,8 +1379,7 @@ public final class MediaRouter2 {
if (controller == null) {
return;
}
- requestCreateController(controller, route, managerRequestId, transferInitiatorUserHandle,
- transferInitiatorPackageName);
+ requestCreateController(controller, route, managerRequestId);
}
private List<MediaRoute2Info> getSortedRoutes(
@@ -2423,20 +2414,14 @@ public final class MediaRouter2 {
@Override
public void requestCreateSessionByManager(
- long managerRequestId,
- RoutingSessionInfo oldSession,
- MediaRoute2Info route,
- UserHandle transferInitiatorUserHandle,
- String transferInitiatorPackageName) {
+ long managerRequestId, RoutingSessionInfo oldSession, MediaRoute2Info route) {
mHandler.sendMessage(
obtainMessage(
MediaRouter2::onRequestCreateControllerByManagerOnHandler,
MediaRouter2.this,
oldSession,
route,
- managerRequestId,
- transferInitiatorUserHandle,
- transferInitiatorPackageName));
+ managerRequestId));
}
}
@@ -3581,12 +3566,7 @@ public final class MediaRouter2 {
RoutingController controller = getCurrentController();
if (!controller.tryTransferWithinProvider(route)) {
- requestCreateController(
- controller,
- route,
- MANAGER_REQUEST_ID_NONE,
- Process.myUserHandle(),
- mContext.getPackageName());
+ requestCreateController(controller, route, MANAGER_REQUEST_ID_NONE);
}
}
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index 7b8093e416f0..d9715eefa955 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -48,7 +48,7 @@
<string name="passwords" msgid="5419394230391253816">"mots de passe"</string>
<string name="sign_ins" msgid="4710739369149469208">"connexions"</string>
<string name="sign_in_info" msgid="2627704710674232328">"renseignements de connexion"</string>
- <string name="save_credential_to_title" msgid="3172811692275634301">"Enregistrer la <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> dans"</string>
+ <string name="save_credential_to_title" msgid="3172811692275634301">"Enregistrer le <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> dans"</string>
<string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Créer une clé d\'accès sur un autre appareil?"</string>
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Enregistrer le mot de passe sur un autre appareil?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Enregistrer l\'authentifiant de connexion sur un autre appareil?"</string>
@@ -57,9 +57,9 @@
<string name="set_as_default" msgid="4415328591568654603">"Définir par défaut"</string>
<string name="settings" msgid="6536394145760913145">"Paramètres"</string>
<string name="use_once" msgid="9027366575315399714">"Utiliser une fois"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mots de passe • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> clés d\'accès"</string>
- <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mots de passe"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> clés d\'accès"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mot(s) de passe • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> clé(s) d\'accès"</string>
+ <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mot(s) de passe"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> clé(s) d\'accès"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> authentifiants"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Clé d\'accès"</string>
<string name="another_device" msgid="5147276802037801217">"Un autre appareil"</string>
diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml
index 3ec7da3721e8..630a08a7e903 100644
--- a/packages/CredentialManager/res/values-hy/strings.xml
+++ b/packages/CredentialManager/res/values-hy/strings.xml
@@ -24,15 +24,15 @@
<string name="string_learn_more" msgid="4541600451688392447">"Իմանալ ավելին"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Ցուցադրել գաղտնաբառը"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Թաքցնել գաղտնաբառը"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Անցաբառերի հետ ավելի ապահով է"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Անցաբառերի շնորհիվ դուք բարդ գաղտնաբառեր ստեղծելու կամ հիշելու անհրաժեշտություն չեք ունենա"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Անցաբառերը գաղտնագրված թվային բանալիներ են, որոնք ստեղծվում են մատնահետքի, դեմքով ապակողպման կամ էկրանի կողպման օգտագործմամբ"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Մուտքի բանալիների հետ ավելի ապահով է"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Մուտքի բանալիների շնորհիվ դուք բարդ գաղտնաբառեր ստեղծելու կամ հիշելու անհրաժեշտություն չեք ունենա"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Մուտքի բանալիները գաղտնագրված թվային բանալիներ են, որոնք ստեղծվում են մատնահետքի, դեմքով ապակողպման կամ էկրանի կողպման օգտագործմամբ"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Դուք կարող եք մուտք գործել այլ սարքերում, քանի որ մուտքի բանալիները պահվում են գաղտնաբառերի կառավարիչում"</string>
<string name="more_about_passkeys_title" msgid="7797903098728837795">"Ավելին՝ մուտքի բանալիների մասին"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Գաղտնաբառեր չպահանջող տեխնոլոգիա"</string>
<string name="passwordless_technology_detail" msgid="6853928846532955882">"Մուտքի բանալիները ձեզ թույլ են տալիս մուտք գործել առանց գաղտնաբառերի։ Ձեզ պարզապես հարկավոր է օգտագործել ձեր մատնահետքը, դիմաճանաչումը, PIN կոդը կամ նախշը՝ ձեր ինքնությունը հաստատելու և մուտքի բանալի ստեղծելու համար։"</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>
@@ -61,7 +61,7 @@
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> գաղտնաբառ"</string>
<string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> մուտքի բանալի"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"Մուտքի տվյալներ (<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>)"</string>
- <string name="passkey_before_subtitle" msgid="2448119456208647444">"Անցաբառ"</string>
+ <string name="passkey_before_subtitle" msgid="2448119456208647444">"Մուտքի բանալի"</string>
<string name="another_device" msgid="5147276802037801217">"Այլ սարք"</string>
<string name="other_password_manager" msgid="565790221427004141">"Գաղտնաբառերի այլ կառավարիչներ"</string>
<string name="close_sheet" msgid="1393792015338908262">"Փակել թերթը"</string>
diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml
index 4224da6e70a4..452565cb95a9 100644
--- a/packages/CredentialManager/res/values-ka/strings.xml
+++ b/packages/CredentialManager/res/values-ka/strings.xml
@@ -74,7 +74,7 @@
<string name="get_dialog_description_single_tap" msgid="2797059565126030879">"გამოიყენეთ თქვენი ეკრანის დაბლოკვის ფუნქცია <xliff:g id="APP_NAME">%1$s</xliff:g>-ში <xliff:g id="USERNAME">%2$s</xliff:g>-ით შესასვლელად"</string>
<string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"შესვლის ვარიანტების განბლოკვა <xliff:g id="APP_NAME">%1$s</xliff:g>-ისთვის"</string>
<string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"აირჩიეთ შენახული წვდომის გასაღები <xliff:g id="APP_NAME">%1$s</xliff:g>-სთვის"</string>
- <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"აირჩიეთ შენახული პაროლი <xliff:g id="APP_NAME">%1$s</xliff:g>-სთვის"</string>
+ <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"აირჩიეთ შენახული პაროლი <xliff:g id="APP_NAME">%1$s</xliff:g>-ისთვის"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"აირჩიეთ სისტემაში შესვლის ინფორმაცია <xliff:g id="APP_NAME">%1$s</xliff:g>-სთვის"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"აირჩიეთ ანგარიში <xliff:g id="APP_NAME">%1$s</xliff:g>-ისთვის"</string>
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"გსურთ აირჩიოთ ვარიანტი <xliff:g id="APP_NAME">%1$s</xliff:g>-ისთვის?"</string>
diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml
index 2fd31ee90cdd..c3bfc4f09c59 100644
--- a/packages/CredentialManager/res/values-kk/strings.xml
+++ b/packages/CredentialManager/res/values-kk/strings.xml
@@ -90,7 +90,7 @@
<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>
- <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Басқа құрылғыдан жасау"</string>
+ <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Басқа құрылғыдан"</string>
<string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Басқа құрылғыны пайдалану"</string>
<string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы сұрауды тоқтатты."</string>
<string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Кіру опциялары"</string>
diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml
index 07775e007835..7ac1d1ac4d94 100644
--- a/packages/CredentialManager/res/values-ne/strings.xml
+++ b/packages/CredentialManager/res/values-ne/strings.xml
@@ -91,7 +91,7 @@
<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>
<string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"अर्को डिभाइसका लागि"</string>
- <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"अर्कै डिभाइस प्रयोग गरी हेर्नुहोस्"</string>
+ <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"अर्कै डिभाइस प्रयोग गर्नुहोस्"</string>
<string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले अनुरोध रद्द गरेको छ"</string>
<string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"साइन इनसम्बन्धी विकल्पहरू"</string>
<string name="more_options_content_description" msgid="1323427365788198808">"थप"</string>
diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml
index a3476d927da7..9186c59caaee 100644
--- a/packages/CredentialManager/res/values-pt-rPT/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml
@@ -91,7 +91,7 @@
<string name="no_sign_in_info_in" msgid="2641118151920288356">"Sem informações de início de sessão em <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
<string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Faça a gestão dos inícios de sessão"</string>
<string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De outro dispositivo"</string>
- <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use um dispositivo diferente"</string>
+ <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use outro diferente"</string>
<string name="request_cancelled_by" msgid="3735222326886267820">"Pedido cancelado pela app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="dropdown_presentation_more_sign_in_options_text" msgid="1693727354272417902">"Opções de início de sessão"</string>
<string name="more_options_content_description" msgid="1323427365788198808">"Mais"</string>
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
index 04175335b9db..473094cc1308 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
@@ -22,6 +22,7 @@ import com.android.credentialmanager.CredentialSelectorUiState
import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerUserNameEntries
import com.android.credentialmanager.model.CredentialType
import com.android.credentialmanager.model.get.CredentialEntryInfo
+import java.time.Instant
fun Request.Get.toGet(isPrimary: Boolean): CredentialSelectorUiState.Get {
val accounts = providerInfos
@@ -67,4 +68,4 @@ fun Request.Get.toGet(isPrimary: Boolean): CredentialSelectorUiState.Get {
val comparator = compareBy<CredentialEntryInfo> { entryInfo ->
// Passkey type always go first
entryInfo.credentialType.let { if (it == CredentialType.PASSKEY) 0 else 1 }
-}.thenByDescending { it.lastUsedTimeMillis ?: 0 }
+}.thenByDescending { it.lastUsedTimeMillis ?: Instant.EPOCH }
diff --git a/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm b/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm
index 03b5c19f8184..723c187d818f 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm
@@ -348,13 +348,13 @@ key COMMA {
label: ','
base: ','
shift: '\''
- ralt: '_'
+ ralt: '\u00af'
}
key PERIOD {
label: '.'
base: '.'
- ralt: '-'
+ ralt: '\u00ad'
}
key SLASH {
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_preference_category_no_title.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_preference_category_no_title.xml
new file mode 100644
index 000000000000..eda7daaf7072
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_preference_category_no_title.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:baselineAligned="false"
+ android:layout_marginTop="16dp">
+</LinearLayout>
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
index 6e9bde45e061..8276e18898c6 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
@@ -29,36 +29,46 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
interface IAppOpsController {
- val mode: Flow<Int>
+ val modeFlow: Flow<Int>
val isAllowed: Flow<Boolean>
- get() = mode.map { it == MODE_ALLOWED }
+ get() = modeFlow.map { it == MODE_ALLOWED }
fun setAllowed(allowed: Boolean)
@Mode fun getMode(): Int
}
+data class AppOps(
+ val op: Int,
+ val modeForNotAllowed: Int = MODE_ERRORED,
+
+ /**
+ * Use AppOpsManager#setUidMode() instead of AppOpsManager#setMode() when set allowed.
+ *
+ * Security or privacy related app-ops should be set with setUidMode() instead of setMode().
+ */
+ val setModeByUid: Boolean = false,
+)
+
class AppOpsController(
context: Context,
private val app: ApplicationInfo,
- private val op: Int,
- private val modeForNotAllowed: Int = MODE_ERRORED,
- private val setModeByUid: Boolean = false,
+ private val appOps: AppOps,
) : IAppOpsController {
private val appOpsManager = context.appOpsManager
private val packageManager = context.packageManager
- override val mode = appOpsManager.opModeFlow(op, app)
+ override val modeFlow = appOpsManager.opModeFlow(appOps.op, app)
override fun setAllowed(allowed: Boolean) {
- val mode = if (allowed) MODE_ALLOWED else modeForNotAllowed
+ val mode = if (allowed) MODE_ALLOWED else appOps.modeForNotAllowed
- if (setModeByUid) {
- appOpsManager.setUidMode(op, app.uid, mode)
+ if (appOps.setModeByUid) {
+ appOpsManager.setUidMode(appOps.op, app.uid, mode)
} else {
- appOpsManager.setMode(op, app.uid, app.packageName, mode)
+ appOpsManager.setMode(appOps.op, app.uid, app.packageName, mode)
}
- val permission = AppOpsManager.opToPermission(op)
+ val permission = AppOpsManager.opToPermission(appOps.op)
if (permission != null) {
packageManager.updatePermissionFlags(permission, app.packageName,
PackageManager.FLAG_PERMISSION_USER_SET,
@@ -67,5 +77,6 @@ class AppOpsController(
}
}
- @Mode override fun getMode(): Int = appOpsManager.getOpMode(op, app)
+ @Mode
+ override fun getMode(): Int = appOpsManager.getOpMode(appOps.op, app)
}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionController.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionController.kt
new file mode 100644
index 000000000000..9350f98841a4
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionController.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.settingslib.spaprivileged.model.app
+
+import android.app.AppOpsManager
+import android.content.Context
+import android.content.pm.ApplicationInfo
+import android.util.Log
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+
+interface IAppOpsPermissionController {
+ val isAllowedFlow: Flow<Boolean>
+ fun setAllowed(allowed: Boolean)
+}
+
+class AppOpsPermissionController(
+ context: Context,
+ private val app: ApplicationInfo,
+ appOps: AppOps,
+ private val permission: String,
+ private val packageManagers: IPackageManagers = PackageManagers,
+ private val appOpsController: IAppOpsController = AppOpsController(context, app, appOps),
+) : IAppOpsPermissionController {
+ override val isAllowedFlow: Flow<Boolean> = appOpsController.modeFlow.map { mode ->
+ when (mode) {
+ AppOpsManager.MODE_ALLOWED -> true
+
+ AppOpsManager.MODE_DEFAULT -> {
+ with(packageManagers) { app.hasGrantPermission(permission) }
+ }
+
+ else -> false
+ }
+ }.conflate().onEach { Log.d(TAG, "isAllowed: $it") }.flowOn(Dispatchers.Default)
+
+ override fun setAllowed(allowed: Boolean) {
+ appOpsController.setAllowed(allowed)
+ }
+
+ private companion object {
+ private const val TAG = "AppOpsPermissionControl"
+ }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
index 5db5eae22745..120b75ecb666 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
@@ -20,12 +20,14 @@ import android.app.AppOpsManager
import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.framework.util.asyncMapItem
import com.android.settingslib.spa.framework.util.filterItem
-import com.android.settingslib.spaprivileged.model.app.AppOpsController
+import com.android.settingslib.spaprivileged.model.app.AppOps
+import com.android.settingslib.spaprivileged.model.app.AppOpsPermissionController
import com.android.settingslib.spaprivileged.model.app.AppRecord
-import com.android.settingslib.spaprivileged.model.app.IAppOpsController
+import com.android.settingslib.spaprivileged.model.app.IAppOpsPermissionController
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
import com.android.settingslib.spaprivileged.model.app.PackageManagers
import kotlinx.coroutines.flow.Flow
@@ -36,7 +38,7 @@ data class AppOpPermissionRecord(
override val app: ApplicationInfo,
val hasRequestBroaderPermission: Boolean,
val hasRequestPermission: Boolean,
- var appOpsController: IAppOpsController,
+ var appOpsPermissionController: IAppOpsPermissionController,
) : AppRecord
abstract class AppOpPermissionListModel(
@@ -44,11 +46,11 @@ abstract class AppOpPermissionListModel(
private val packageManagers: IPackageManagers = PackageManagers,
) : TogglePermissionAppListModel<AppOpPermissionRecord> {
- abstract val appOp: Int
+ abstract val appOps: AppOps
abstract val permission: String
override val enhancedConfirmationKey: String?
- get() = AppOpsManager.opToPublicName(appOp)
+ get() = AppOpsManager.opToPublicName(appOps.op)
/**
* When set, specifies the broader permission who trumps the [permission].
@@ -65,27 +67,12 @@ abstract class AppOpPermissionListModel(
*/
open val permissionHasAppOpFlag: Boolean = true
- open val modeForNotAllowed: Int = AppOpsManager.MODE_ERRORED
-
- /**
- * Use AppOpsManager#setUidMode() instead of AppOpsManager#setMode() when set allowed.
- *
- * Security or privacy related app-ops should be set with setUidMode() instead of setMode().
- */
- open val setModeByUid = false
-
/** These not changeable packages will also be hidden from app list. */
private val notChangeablePackages =
setOf("android", "com.android.systemui", context.packageName)
- private fun createAppOpsController(app: ApplicationInfo) =
- AppOpsController(
- context = context,
- app = app,
- op = appOp,
- setModeByUid = setModeByUid,
- modeForNotAllowed = modeForNotAllowed,
- )
+ private fun createAppOpsPermissionController(app: ApplicationInfo) =
+ AppOpsPermissionController(context, app, appOps, permission)
private fun createRecord(
app: ApplicationInfo,
@@ -98,7 +85,7 @@ abstract class AppOpPermissionListModel(
app.hasRequestPermission(it)
} ?: false,
hasRequestPermission = hasRequestPermission,
- appOpsController = createAppOpsController(app),
+ appOpsPermissionController = createAppOpsPermissionController(app),
)
}
@@ -131,14 +118,20 @@ abstract class AppOpPermissionListModel(
override fun filter(userIdFlow: Flow<Int>, recordListFlow: Flow<List<AppOpPermissionRecord>>) =
recordListFlow.filterItem(::isChangeable)
+ /**
+ * Defining the default behavior as permissible as long as the package requested this permission
+ * (This means pre-M gets approval during install time; M apps gets approval during runtime).
+ */
@Composable
- override fun isAllowed(record: AppOpPermissionRecord): () -> Boolean? =
- isAllowed(
- record = record,
- appOpsController = record.appOpsController,
- permission = permission,
- packageManagers = packageManagers,
- )
+ override fun isAllowed(record: AppOpPermissionRecord): () -> Boolean? {
+ if (record.hasRequestBroaderPermission) {
+ // Broader permission trumps the specific permission.
+ return { true }
+ }
+ val isAllowed by record.appOpsPermissionController.isAllowedFlow
+ .collectAsStateWithLifecycle(initialValue = null)
+ return { isAllowed }
+ }
override fun isChangeable(record: AppOpPermissionRecord) =
record.hasRequestPermission &&
@@ -146,36 +139,6 @@ abstract class AppOpPermissionListModel(
record.app.packageName !in notChangeablePackages
override fun setAllowed(record: AppOpPermissionRecord, newAllowed: Boolean) {
- record.appOpsController.setAllowed(newAllowed)
- }
-}
-
-/**
- * Defining the default behavior as permissible as long as the package requested this permission
- * (This means pre-M gets approval during install time; M apps gets approval during runtime).
- */
-@Composable
-internal fun isAllowed(
- record: AppOpPermissionRecord,
- appOpsController: IAppOpsController,
- permission: String,
- packageManagers: IPackageManagers = PackageManagers,
-): () -> Boolean? {
- if (record.hasRequestBroaderPermission) {
- // Broader permission trumps the specific permission.
- return { true }
- }
-
- val mode = appOpsController.mode.collectAsStateWithLifecycle(initialValue = null)
- return {
- when (mode.value) {
- null -> null
- AppOpsManager.MODE_ALLOWED -> true
- AppOpsManager.MODE_DEFAULT -> {
- with(packageManagers) { record.app.hasGrantPermission(permission) }
- }
-
- else -> false
- }
+ record.appOpsPermissionController.setAllowed(newAllowed)
}
}
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
index 91bbd9f9a5c1..74a7c146b2ab 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
@@ -27,16 +27,14 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spaprivileged.framework.common.appOpsManager
import com.google.common.truth.Truth.assertThat
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Spy
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
-import org.mockito.kotlin.any
-import org.mockito.kotlin.doNothing
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -44,28 +42,18 @@ import org.mockito.kotlin.whenever
class AppOpsControllerTest {
@get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
- @Spy private val context: Context = ApplicationProvider.getApplicationContext()
+ private val appOpsManager = mock<AppOpsManager>()
- @Mock private lateinit var appOpsManager: AppOpsManager
+ private val packageManager = mock<PackageManager>()
- @Mock private lateinit var packageManager: PackageManager
-
- @Before
- fun setUp() {
- whenever(context.appOpsManager).thenReturn(appOpsManager)
- whenever(context.packageManager).thenReturn(packageManager)
- doNothing().whenever(packageManager)
- .updatePermissionFlags(any(), any(), any(), any(), any())
+ private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+ on { appOpsManager } doReturn appOpsManager
+ on { packageManager } doReturn packageManager
}
@Test
fun setAllowed_setToTrue() {
- val controller =
- AppOpsController(
- context = context,
- app = APP,
- op = OP,
- )
+ val controller = AppOpsController(context = context, app = APP, appOps = AppOps(OP))
controller.setAllowed(true)
@@ -74,12 +62,7 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToFalse() {
- val controller =
- AppOpsController(
- context = context,
- app = APP,
- op = OP,
- )
+ val controller = AppOpsController(context = context, app = APP, appOps = AppOps(OP))
controller.setAllowed(false)
@@ -88,13 +71,11 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToFalseWithModeForNotAllowed() {
- val controller =
- AppOpsController(
- context = context,
- app = APP,
- op = OP,
- modeForNotAllowed = MODE_IGNORED,
- )
+ val controller = AppOpsController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP, modeForNotAllowed = MODE_IGNORED),
+ )
controller.setAllowed(false)
@@ -103,13 +84,11 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToTrueByUid() {
- val controller =
- AppOpsController(
- context = context,
- app = APP,
- op = OP,
- setModeByUid = true,
- )
+ val controller = AppOpsController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP, setModeByUid = true),
+ )
controller.setAllowed(true)
@@ -118,13 +97,11 @@ class AppOpsControllerTest {
@Test
fun setAllowed_setToFalseByUid() {
- val controller =
- AppOpsController(
- context = context,
- app = APP,
- op = OP,
- setModeByUid = true,
- )
+ val controller = AppOpsController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP, setModeByUid = true),
+ )
controller.setAllowed(false)
@@ -135,12 +112,7 @@ class AppOpsControllerTest {
fun getMode() {
whenever(appOpsManager.checkOpNoThrow(OP, APP.uid, APP.packageName))
.thenReturn(MODE_ALLOWED)
- val controller =
- AppOpsController(
- context = context,
- app = APP,
- op = OP,
- )
+ val controller = AppOpsController(context = context, app = APP, appOps = AppOps(OP))
val mode = controller.getMode()
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.kt
new file mode 100644
index 000000000000..9f80b92548d2
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsPermissionControllerTest.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.settingslib.spaprivileged.model.app
+
+import android.app.AppOpsManager
+import android.content.Context
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
+import com.android.settingslib.spaprivileged.framework.common.appOpsManager
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.verify
+
+@RunWith(AndroidJUnit4::class)
+class AppOpsPermissionControllerTest {
+
+ private val appOpsManager = mock<AppOpsManager>()
+ private val packageManager = mock<PackageManager>()
+ private val packageManagers = mock<IPackageManagers>()
+ private val appOpsController = mock<IAppOpsController>()
+
+ private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+ on { appOpsManager } doReturn appOpsManager
+ on { packageManager } doReturn packageManager
+ }
+
+ @Test
+ fun isAllowedFlow_appOpsAllowed_returnTrue() = runBlocking {
+ appOpsController.stub {
+ on { modeFlow } doReturn flowOf(AppOpsManager.MODE_ALLOWED)
+ }
+ val controller = AppOpsPermissionController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP),
+ permission = PERMISSION,
+ appOpsController = appOpsController,
+ )
+
+ val isAllowed = controller.isAllowedFlow.firstWithTimeoutOrNull()
+
+ assertThat(isAllowed).isTrue()
+ }
+
+ @Test
+ fun isAllowedFlow_appOpsDefaultAndPermissionGranted_returnTrue() = runBlocking {
+ appOpsController.stub {
+ on { modeFlow } doReturn flowOf(AppOpsManager.MODE_DEFAULT)
+ }
+ packageManagers.stub {
+ on { APP.hasGrantPermission(PERMISSION) } doReturn true
+ }
+ val controller = AppOpsPermissionController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP),
+ permission = PERMISSION,
+ packageManagers = packageManagers,
+ appOpsController = appOpsController,
+ )
+
+ val isAllowed = controller.isAllowedFlow.firstWithTimeoutOrNull()
+
+ assertThat(isAllowed).isTrue()
+ }
+
+ @Test
+ fun isAllowedFlow_appOpsDefaultAndPermissionNotGranted_returnFalse() = runBlocking {
+ appOpsController.stub {
+ on { modeFlow } doReturn flowOf(AppOpsManager.MODE_DEFAULT)
+ }
+ packageManagers.stub {
+ on { APP.hasGrantPermission(PERMISSION) } doReturn false
+ }
+ val controller = AppOpsPermissionController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP),
+ permission = PERMISSION,
+ packageManagers = packageManagers,
+ appOpsController = appOpsController,
+ )
+
+ val isAllowed = controller.isAllowedFlow.firstWithTimeoutOrNull()
+
+ assertThat(isAllowed).isFalse()
+ }
+
+ @Test
+ fun isAllowedFlow_appOpsError_returnFalse() = runBlocking {
+ appOpsController.stub {
+ on { modeFlow } doReturn flowOf(AppOpsManager.MODE_ERRORED)
+ }
+ val controller = AppOpsPermissionController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP),
+ permission = PERMISSION,
+ appOpsController = appOpsController,
+ )
+
+ val isAllowed = controller.isAllowedFlow.firstWithTimeoutOrNull()
+
+ assertThat(isAllowed).isFalse()
+ }
+
+ @Test
+ fun setAllowed_notSetModeByUid() {
+ val controller = AppOpsPermissionController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP, setModeByUid = false),
+ permission = PERMISSION,
+ )
+
+ controller.setAllowed(true)
+
+ verify(appOpsManager).setMode(OP, APP.uid, APP.packageName, AppOpsManager.MODE_ALLOWED)
+ }
+
+ @Test
+ fun setAllowed_setModeByUid() {
+ val controller = AppOpsPermissionController(
+ context = context,
+ app = APP,
+ appOps = AppOps(op = OP, setModeByUid = true),
+ permission = PERMISSION,
+ )
+
+ controller.setAllowed(true)
+
+ verify(appOpsManager).setUidMode(OP, APP.uid, AppOpsManager.MODE_ALLOWED)
+ }
+
+ private companion object {
+ const val OP = 1
+ const val PERMISSION = "Permission"
+ val APP = ApplicationInfo().apply {
+ packageName = "package.name"
+ uid = 123
+ }
+ }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
index bb25cf3b6d48..9d12fc7611cb 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
@@ -25,7 +25,8 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spaprivileged.framework.common.appOpsManager
-import com.android.settingslib.spaprivileged.model.app.IAppOpsController
+import com.android.settingslib.spaprivileged.model.app.AppOps
+import com.android.settingslib.spaprivileged.model.app.IAppOpsPermissionController
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
import com.android.settingslib.spaprivileged.test.R
import com.google.common.truth.Truth.assertThat
@@ -39,7 +40,6 @@ import org.mockito.kotlin.doNothing
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
-import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
@@ -119,7 +119,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = false,
hasRequestPermission = false,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val recordListFlow = listModel.filter(flowOf(USER_ID), flowOf(listOf(record)))
@@ -135,7 +135,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = false,
hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ALLOWED),
+ appOpsPermissionController = FakeAppOpsPermissionController(true),
)
val isAllowed = getIsAllowed(record)
@@ -144,38 +144,6 @@ class AppOpPermissionAppListTest {
}
@Test
- fun isAllowed_defaultAndHasGrantPermission() {
- with(packageManagers) { whenever(APP.hasGrantPermission(PERMISSION)).thenReturn(true) }
- val record =
- AppOpPermissionRecord(
- app = APP,
- hasRequestBroaderPermission = false,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
-
- val isAllowed = getIsAllowed(record)
-
- assertThat(isAllowed).isTrue()
- }
-
- @Test
- fun isAllowed_defaultAndNotGrantPermission() {
- with(packageManagers) { whenever(APP.hasGrantPermission(PERMISSION)).thenReturn(false) }
- val record =
- AppOpPermissionRecord(
- app = APP,
- hasRequestBroaderPermission = false,
- hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
- )
-
- val isAllowed = getIsAllowed(record)
-
- assertThat(isAllowed).isFalse()
- }
-
- @Test
fun isAllowed_broaderPermissionTrumps() {
listModel.broaderPermission = BROADER_PERMISSION
with(packageManagers) {
@@ -187,7 +155,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = true,
hasRequestPermission = false,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ERRORED),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val isAllowed = getIsAllowed(record)
@@ -202,7 +170,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = false,
hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_ERRORED),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val isAllowed = getIsAllowed(record)
@@ -217,7 +185,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = false,
hasRequestPermission = false,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val isChangeable = listModel.isChangeable(record)
@@ -232,7 +200,7 @@ class AppOpPermissionAppListTest {
app = NOT_CHANGEABLE_APP,
hasRequestBroaderPermission = false,
hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val isChangeable = listModel.isChangeable(record)
@@ -247,7 +215,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = false,
hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val isChangeable = listModel.isChangeable(record)
@@ -263,7 +231,7 @@ class AppOpPermissionAppListTest {
app = APP,
hasRequestBroaderPermission = true,
hasRequestPermission = true,
- appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT),
+ appOpsPermissionController = FakeAppOpsPermissionController(false),
)
val isChangeable = listModel.isChangeable(record)
@@ -273,28 +241,18 @@ class AppOpPermissionAppListTest {
@Test
fun setAllowed() {
- val appOpsController = FakeAppOpsController(fakeMode = AppOpsManager.MODE_DEFAULT)
+ val appOpsPermissionController = FakeAppOpsPermissionController(false)
val record =
AppOpPermissionRecord(
app = APP,
hasRequestBroaderPermission = false,
hasRequestPermission = true,
- appOpsController = appOpsController,
+ appOpsPermissionController = appOpsPermissionController,
)
listModel.setAllowed(record = record, newAllowed = true)
- assertThat(appOpsController.setAllowedCalledWith).isTrue()
- }
-
- @Test
- fun setAllowed_setModeByUid() {
- listModel.setModeByUid = true
- val record = listModel.transformItem(APP)
-
- listModel.setAllowed(record = record, newAllowed = true)
-
- verify(appOpsManager).setUidMode(listModel.appOp, APP.uid, AppOpsManager.MODE_ALLOWED)
+ assertThat(appOpsPermissionController.setAllowedCalledWith).isTrue()
}
private fun getIsAllowed(record: AppOpPermissionRecord): Boolean? {
@@ -309,11 +267,9 @@ class AppOpPermissionAppListTest {
override val switchTitleResId = R.string.test_app_op_permission_switch_title
override val footerResId = R.string.test_app_op_permission_footer
- override val appOp = AppOpsManager.OP_MANAGE_MEDIA
+ override val appOps = AppOps(AppOpsManager.OP_MANAGE_MEDIA)
override val permission = PERMISSION
override var broaderPermission: String? = null
-
- override var setModeByUid = false
}
private companion object {
@@ -326,14 +282,12 @@ class AppOpPermissionAppListTest {
}
}
-private class FakeAppOpsController(private val fakeMode: Int) : IAppOpsController {
+private class FakeAppOpsPermissionController(allowed: Boolean) : IAppOpsPermissionController {
var setAllowedCalledWith: Boolean? = null
- override val mode = flowOf(fakeMode)
+ override val isAllowedFlow = flowOf(allowed)
override fun setAllowed(allowed: Boolean) {
setAllowedCalledWith = allowed
}
-
- override fun getMode() = fakeMode
}
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 9c0d29df420f..32557b979bf5 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -69,3 +69,13 @@ flag {
description: "Allow all widgets on the lock screen by default."
bug: "328261690"
}
+
+flag {
+ name: "enable_determining_advanced_details_header_with_metadata"
+ namespace: "pixel_cross_device_control"
+ description: "Use metadata instead of device type to determine whether a bluetooth device should use advanced details header."
+ bug: "328556903"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 4ea746007f76..363045ec1d83 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -214,6 +214,10 @@
<string name="bluetooth_battery_level_untethered_left">Left: <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g> battery</string>
<!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for the right part of the untethered headset. [CHAR LIMIT=NONE] -->
<string name="bluetooth_battery_level_untethered_right">Right: <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g> battery</string>
+ <!-- Connected devices settings. Message when Bluetooth is connected, showing remote device battery level for the left part of the untethered headset. [CHAR LIMIT=NONE] -->
+ <string name="tv_bluetooth_battery_level_untethered_left">Left <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g></string>
+ <!-- Connected devices settings. Message when Bluetooth is connected, showing remote device battery level for the right part of the untethered headset. [CHAR LIMIT=NONE] -->
+ <string name="tv_bluetooth_battery_level_untethered_right">Right <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g></string>
<!-- Connected devices settings. Message when Bluetooth is connected and active but no battery information, showing remote device status. [CHAR LIMIT=NONE] -->
<string name="bluetooth_active_no_battery_level">Active</string>
<!-- Connected devices settings. Message shown when bluetooth device is disconnected but is a known, previously connected device [CHAR LIMIT=NONE] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 89174125a296..721e7b93fd32 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -276,6 +276,14 @@ public class BluetoothUtils {
if (isUntetheredHeadset(bluetoothDevice)) {
return true;
}
+ if (Flags.enableDeterminingAdvancedDetailsHeaderWithMetadata()) {
+ // A FastPair device that use advanced details header must have METADATA_MAIN_ICON
+ if (getUriMetaData(bluetoothDevice, BluetoothDevice.METADATA_MAIN_ICON) != null) {
+ Log.d(TAG, "isAdvancedDetailsHeader is true with main icon uri");
+ return true;
+ }
+ return false;
+ }
// The metadata is for Android S
String deviceType =
getStringMetaData(bluetoothDevice, BluetoothDevice.METADATA_DEVICE_TYPE);
@@ -302,12 +310,15 @@ public class BluetoothUtils {
if (isUntetheredHeadset(bluetoothDevice)) {
return true;
}
- // The metadata is for Android S
- String deviceType =
- getStringMetaData(bluetoothDevice, BluetoothDevice.METADATA_DEVICE_TYPE);
- if (TextUtils.equals(deviceType, BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET)) {
- Log.d(TAG, "isAdvancedUntetheredDevice: is untethered device ");
- return true;
+ if (!Flags.enableDeterminingAdvancedDetailsHeaderWithMetadata()) {
+ // The METADATA_IS_UNTETHERED_HEADSET of an untethered FastPair headset is always true,
+ // so there's no need to check the device type.
+ String deviceType =
+ getStringMetaData(bluetoothDevice, BluetoothDevice.METADATA_DEVICE_TYPE);
+ if (TextUtils.equals(deviceType, BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET)) {
+ Log.d(TAG, "isAdvancedUntetheredDevice: is untethered device");
+ return true;
+ }
}
return false;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index c2a83b1e772f..0fec61c5affe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1532,7 +1532,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
// the left.
if (leftBattery >= 0) {
String left = res.getString(
- R.string.bluetooth_battery_level_untethered_left,
+ R.string.tv_bluetooth_battery_level_untethered_left,
Utils.formatPercentage(leftBattery));
addBatterySpan(spannableBuilder, left, isBatteryLow(leftBattery,
BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD),
@@ -1543,7 +1543,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
spannableBuilder.append(" ");
}
String right = res.getString(
- R.string.bluetooth_battery_level_untethered_right,
+ R.string.tv_bluetooth_battery_level_untethered_right,
Utils.formatPercentage(rightBattery));
addBatterySpan(spannableBuilder, right, isBatteryLow(rightBattery,
BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD),
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 7a2818dbf299..a638df524740 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
@@ -15,6 +15,8 @@
*/
package com.android.settingslib.bluetooth;
+import static com.android.settingslib.flags.Flags.FLAG_ENABLE_DETERMINING_ADVANCED_DETAILS_HEADER_WITH_METADATA;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -33,11 +35,13 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.Pair;
import com.android.settingslib.widget.AdaptiveIcon;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -83,11 +87,15 @@ public class BluetoothUtilsTest {
private static final String TEST_EXCLUSIVE_MANAGER_PACKAGE = "com.test.manager";
private static final String TEST_EXCLUSIVE_MANAGER_COMPONENT = "com.test.manager/.component";
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_DETERMINING_ADVANCED_DETAILS_HEADER_WITH_METADATA);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
when(mProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
when(mProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
@@ -253,6 +261,25 @@ public class BluetoothUtilsTest {
}
@Test
+ public void isAdvancedDetailsHeader_noMainIcon_returnFalse() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_DETERMINING_ADVANCED_DETAILS_HEADER_WITH_METADATA);
+
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON)).thenReturn(null);
+
+ assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isFalse();
+ }
+
+ @Test
+ public void isAdvancedDetailsHeader_hasMainIcon_returnTrue() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_DETERMINING_ADVANCED_DETAILS_HEADER_WITH_METADATA);
+
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON))
+ .thenReturn(STRING_METADATA.getBytes());
+
+ assertThat(BluetoothUtils.isAdvancedDetailsHeader(mBluetoothDevice)).isTrue();
+ }
+
+ @Test
public void isAdvancedUntetheredDevice_untetheredHeadset_returnTrue() {
when(mBluetoothDevice.getMetadata(
BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
@@ -294,6 +321,18 @@ public class BluetoothUtilsTest {
}
@Test
+ public void isAdvancedUntetheredDevice_untetheredHeadsetMetadataIsFalse_returnFalse() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_DETERMINING_ADVANCED_DETAILS_HEADER_WITH_METADATA);
+
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
+ .thenReturn("false".getBytes());
+ when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE))
+ .thenReturn(BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET.getBytes());
+
+ assertThat(BluetoothUtils.isAdvancedUntetheredDevice(mBluetoothDevice)).isFalse();
+ }
+
+ @Test
public void isAvailableMediaBluetoothDevice_isConnectedLeAudioDevice_returnTrue() {
when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index b9bf9caddac7..0d814947527c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -780,9 +780,8 @@ public class CachedBluetoothDeviceTest {
mBatteryLevel = 10;
// Act & Assert:
- // Get "Left: 10% battery" result with Battery Level 10.
- assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
- "Left: 10% battery");
+ // Get "Left 10%" result with Battery Level 10.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Left 10%");
}
@Test
@@ -815,9 +814,9 @@ public class CachedBluetoothDeviceTest {
mBatteryLevel = 10;
// Act & Assert:
- // Get "Left: 10% battery" result with Battery Level 10.
+ // Get "Left 10%" result with Battery Level 10.
assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
- "Left: 10% battery");
+ "Left 10%");
}
@Test
@@ -925,9 +924,9 @@ public class CachedBluetoothDeviceTest {
mBatteryLevel = 10;
// Act & Assert:
- // Get "Left: 10% battery Right: 10% battery" result with Battery Level 10.
+ // Get "Left 10% Right 10%" result with Battery Level 10.
assertThat(mCachedDevice.getTvConnectionSummary().toString())
- .isEqualTo("Left: 10% battery Right: 10% battery");
+ .isEqualTo("Left 10% Right 10%");
}
@Test
@@ -1226,7 +1225,7 @@ public class CachedBluetoothDeviceTest {
TWS_BATTERY_RIGHT.getBytes());
assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
- "Left: 15% battery Right: 25% battery");
+ "Left 15% Right 25%");
}
@Test
@@ -1262,11 +1261,7 @@ public class CachedBluetoothDeviceTest {
TWS_BATTERY_RIGHT.getBytes());
assertThat(mCachedDevice.getTvConnectionSummary().toString())
- .isEqualTo(
- mContext.getString(R.string.bluetooth_battery_level_untethered_left, "15%")
- + " "
- + mContext.getString(
- R.string.bluetooth_battery_level_untethered_right, "25%"));
+ .isEqualTo("Left 15% Right 25%");
}
@Test
@@ -1283,10 +1278,8 @@ public class CachedBluetoothDeviceTest {
.thenReturn(TWS_BATTERY_RIGHT.getBytes());
int lowBatteryColor = mContext.getColor(LOW_BATTERY_COLOR);
- String leftBattery =
- mContext.getString(R.string.bluetooth_battery_level_untethered_left, "15%");
- String rightBattery =
- mContext.getString(R.string.bluetooth_battery_level_untethered_right, "25%");
+ String leftBattery = "Left 15%";
+ String rightBattery = "Right 25%";
// Default low battery threshold, only left battery is low
CharSequence summary = mCachedDevice.getTvConnectionSummary(LOW_BATTERY_COLOR);
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index d2ca11207084..8b60ed035d07 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -87,6 +87,52 @@ filegroup {
"tests/src/**/systemui/util/sensors/AsyncManagerTest.java",
"tests/src/**/systemui/util/sensors/ThresholdSensorImplTest.java",
"tests/src/**/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java",
+ "tests/src/**/systemui/statusbar/KeyboardShortcutListSearchTest.java",
+ "tests/src/**/systemui/statusbar/KeyboardShortcutsTest.java",
+ "tests/src/**/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt",
+ "tests/src/**/systemui/statusbar/notification/AssistantFeedbackControllerTest.java",
+ "tests/src/**/systemui/statusbar/notification/collection/NotifCollectionTest.java",
+ "tests/src/**/systemui/statusbar/notification/collection/NotificationEntryTest.java",
+ "tests/src/**/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt",
+ "tests/src/**/systemui/statusbar/notification/collection/ShadeListBuilderTest.java",
+ "tests/src/**/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java",
+ "tests/src/**/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java",
+ "tests/src/**/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt",
+ "tests/src/**/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt",
+ "tests/src/**/systemui/statusbar/NotificationLockscreenUserManagerTest.java",
+ "tests/src/**/systemui/statusbar/notification/logging/NotificationLoggerTest.java",
+ "tests/src/**/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java",
+ "tests/src/**/systemui/statusbar/notification/row/NotificationContentInflaterTest.java",
+ "tests/src/**/systemui/statusbar/notification/row/NotificationContentViewTest.kt",
+ "tests/src/**/systemui/statusbar/notification/row/NotificationConversationInfoTest.java",
+ "tests/src/**/systemui/statusbar/notification/row/NotificationGutsManagerTest.java",
+ "tests/src/**/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt",
+ "tests/src/**/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt",
+ "tests/src/**/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt",
+ "tests/src/**/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java",
+ "tests/src/**/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java",
+ "tests/src/**/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt",
+ "tests/src/**/systemui/statusbar/phone/AutoTileManagerTest.java",
+ "tests/src/**/systemui/statusbar/phone/CentralSurfacesImplTest.java",
+ "tests/src/**/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java",
+ "tests/src/**/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt",
+ "tests/src/**/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt",
+ "tests/src/**/systemui/statusbar/phone/PhoneStatusBarView.java",
+ "tests/src/**/systemui/statusbar/phone/PhoneStatusBarViewTest.kt",
+ "tests/src/**/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt",
+ "tests/src/**/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt",
+ "tests/src/**/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt",
+ "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt",
+ "tests/src/**/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt",
+ "tests/src/**/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt",
+ "tests/src/**/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt",
+ "tests/src/**/systemui/statusbar/policy/CallbackControllerTest.java",
+ "tests/src/**/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java",
+ "tests/src/**/systemui/statusbar/policy/InflatedSmartRepliesTest.java",
+ "tests/src/**/systemui/statusbar/policy/LocationControllerImplTest.java",
+ "tests/src/**/systemui/statusbar/policy/RemoteInputViewTest.java",
+ "tests/src/**/systemui/statusbar/policy/SmartReplyViewTest.java",
+ "tests/src/**/systemui/statusbar/StatusBarStateControllerImplTest.kt",
],
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
index d868d5c7c4c4..ba842877fc79 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
@@ -9,3 +9,13 @@ flag {
description: "Hides the AccessibilityMenuService UI before taking action instead of after."
bug: "292020123"
}
+
+flag {
+ name: "a11y_menu_snackbar_live_region"
+ namespace: "accessibility"
+ description: "configures live region on snackbar so its contents are announced when it appears."
+ bug: "338351484"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index 1be04f854c9a..7b43b72ee757 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -17,6 +17,7 @@
package com.android.systemui.accessibility.accessibilitymenu.view;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static java.lang.Math.max;
@@ -321,7 +322,14 @@ public class A11yMenuOverlayLayout {
AccessibilityManager.FLAG_CONTENT_TEXT);
final TextView snackbar = mLayout.findViewById(R.id.snackbar);
+ if (snackbar == null) {
+ return;
+ }
snackbar.setText(text);
+ if (com.android.systemui.accessibility.accessibilitymenu
+ .Flags.a11yMenuSnackbarLiveRegion()) {
+ snackbar.setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
+ }
// Remove any existing fade-out animation before starting any new animations.
mHandler.removeCallbacksAndMessages(null);
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index 755fe2a4476a..55edff6d9518 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -4,6 +4,13 @@ container: "system"
# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
flag {
+ name: "create_windowless_window_magnifier"
+ namespace: "accessibility"
+ description: "Uses SurfaceControlViewHost to create the magnifier for window magnification."
+ bug: "280992417"
+}
+
+flag {
name: "delay_show_magnification_button"
namespace: "accessibility"
description: "Delays the showing of magnification mode switch button."
@@ -66,8 +73,11 @@ flag {
}
flag {
- name: "create_windowless_window_magnifier"
+ name: "save_and_restore_magnification_settings_buttons"
namespace: "accessibility"
- description: "Uses SurfaceControlViewHost to create the magnifier for window magnification."
- bug: "280992417"
+ description: "Saves the selected button status in magnification settings and restore the status when revisiting the same smallest screen DP."
+ bug: "325567876"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 10ba7bdc00c0..f3e2272792a8 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -26,14 +26,6 @@ flag {
}
flag {
-
- name: "notification_heads_up_cycling"
- namespace: "systemui"
- description: "Heads-up notification cycling animation for the Notification Avalanche feature."
- bug: "316404716"
-}
-
-flag {
name: "priority_people_section"
namespace: "systemui"
description: "Add a new section for priority people (aka important conversations)."
@@ -422,6 +414,13 @@ flag {
}
flag {
+ name: "confine_notification_touch_to_view_width"
+ namespace: "systemui"
+ description: "Use notification view width when detecting gestures."
+ bug: "335828150"
+}
+
+flag {
name: "fix_image_wallpaper_crash_surface_already_released"
namespace: "systemui"
description: "Make sure ImageWallpaper doesn't return from OnSurfaceDestroyed until any drawing is finished"
@@ -976,3 +975,13 @@ flag {
description: "Shows a vertical bar at the right edge to indicate the user can swipe to open the glanceable hub"
bug: "339667383"
}
+
+flag {
+ name: "register_wallpaper_notifier_background"
+ namespace: "systemui"
+ description: "Decide whether to register wallpaper change broadcast receiver on background executor."
+ bug: "327315860"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
index d1099883c5e5..54a98ddaa01a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
@@ -69,7 +69,7 @@ object QuickSettings {
private fun SceneScope.stateForQuickSettingsContent(
isSplitShade: Boolean,
- squishiness: Float = QuickSettings.SharedValues.SquishinessValues.Default
+ squishiness: () -> Float = { QuickSettings.SharedValues.SquishinessValues.Default }
): QSSceneAdapter.State {
return when (val transitionState = layoutState.transitionState) {
is TransitionState.Idle -> {
@@ -125,9 +125,9 @@ fun SceneScope.QuickSettings(
heightProvider: () -> Int,
isSplitShade: Boolean,
modifier: Modifier = Modifier,
- squishiness: Float = QuickSettings.SharedValues.SquishinessValues.Default,
+ squishiness: () -> Float = { QuickSettings.SharedValues.SquishinessValues.Default },
) {
- val contentState = stateForQuickSettingsContent(isSplitShade, squishiness)
+ val contentState = { stateForQuickSettingsContent(isSplitShade, squishiness) }
val transitionState = layoutState.transitionState
val isClosing =
transitionState is TransitionState.Transition &&
@@ -161,7 +161,7 @@ fun SceneScope.QuickSettings(
@Composable
private fun QuickSettingsContent(
qsSceneAdapter: QSSceneAdapter,
- state: QSSceneAdapter.State,
+ state: () -> QSSceneAdapter.State,
modifier: Modifier = Modifier,
) {
val qsView by qsSceneAdapter.qsView.collectAsStateWithLifecycle(null)
@@ -185,10 +185,10 @@ private fun QuickSettingsContent(
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = { _ ->
- qsSceneAdapter.setState(state)
+ qsSceneAdapter.setState(state())
view
},
- update = { qsSceneAdapter.setState(state) }
+ update = { qsSceneAdapter.setState(state()) }
)
}
}
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 a0278a616857..9d689fc25b23 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
@@ -279,7 +279,7 @@ private fun SceneScope.SingleShade(
viewModel.qsSceneAdapter,
{ viewModel.qsSceneAdapter.qqsHeight },
isSplitShade = false,
- squishiness = tileSquishiness,
+ squishiness = { tileSquishiness },
)
}
@@ -468,7 +468,7 @@ private fun SceneScope.SplitShade(
heightProvider = { viewModel.qsSceneAdapter.qsHeight },
isSplitShade = true,
modifier = Modifier.fillMaxWidth(),
- squishiness = tileSquishiness,
+ squishiness = { tileSquishiness },
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt
index ca824cbdd53b..5757f67cc1dd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt
@@ -42,7 +42,6 @@ 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.ArgumentMatchers
@@ -90,11 +89,6 @@ class NightDisplayRepositoryTest : SysuiTestCase() {
locationController,
)
- @Before
- fun setup() {
- enrollInForcedNightDisplayAutoMode(INITIALLY_FORCE_AUTO_MODE, testUser)
- }
-
@Test
fun nightDisplayState_matchesAutoMode() =
scope.runTest {
@@ -126,6 +120,8 @@ class NightDisplayRepositoryTest : SysuiTestCase() {
@Test
fun nightDisplayState_matchesIsNightDisplayActivated() =
scope.runTest {
+ enrollInForcedNightDisplayAutoMode(INITIALLY_FORCE_AUTO_MODE, testUser)
+
val callbackCaptor = argumentCaptor<NightDisplayListener.Callback>()
val lastState by collectLastValue(underTest.nightDisplayState(testUser))
@@ -148,6 +144,7 @@ class NightDisplayRepositoryTest : SysuiTestCase() {
scope.runTest {
whenever(colorDisplayManager.nightDisplayAutoMode)
.thenReturn(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME)
+ enrollInForcedNightDisplayAutoMode(INITIALLY_FORCE_AUTO_MODE, testUser)
val lastState by collectLastValue(underTest.nightDisplayState(testUser))
runCurrent()
@@ -160,6 +157,7 @@ class NightDisplayRepositoryTest : SysuiTestCase() {
scope.runTest {
whenever(colorDisplayManager.nightDisplayAutoMode)
.thenReturn(ColorDisplayManager.AUTO_MODE_TWILIGHT)
+ enrollInForcedNightDisplayAutoMode(INITIALLY_FORCE_AUTO_MODE, testUser)
val lastState by collectLastValue(underTest.nightDisplayState(testUser))
runCurrent()
@@ -167,6 +165,24 @@ class NightDisplayRepositoryTest : SysuiTestCase() {
assertThat(lastState!!.autoMode).isEqualTo(ColorDisplayManager.AUTO_MODE_TWILIGHT)
}
+ /**
+ * When the value of the raw auto mode is missing the call to nightDisplayState should not crash
+ */
+ @Test
+ fun nightDisplayState_whenAutoModeSettingIsNotInitialized_loadsDataWithoutException() =
+ scope.runTest {
+ // only auto mode_available is set, and the raw auto_mode has nothing set
+ globalSettings.putString(
+ Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE,
+ NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE
+ )
+
+ val lastState by collectLastValue(underTest.nightDisplayState(testUser))
+ runCurrent()
+
+ assertThat(lastState!!.shouldForceAutoMode).isTrue()
+ }
+
@Test
fun nightDisplayState_matchesForceAutoMode() =
scope.runTest {
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 766798c2c2c3..83227e1fc597 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
@@ -204,14 +204,14 @@ class CommunalInteractorTest : SysuiTestCase() {
}
@Test
- fun isCommunalAvailable_whenDreaming_true() =
+ fun isCommunalAvailable_whenKeyguardShowing_true() =
testScope.runTest {
val isAvailable by collectLastValue(underTest.isCommunalAvailable)
assertThat(isAvailable).isFalse()
keyguardRepository.setIsEncryptedOrLockdown(false)
userRepository.setSelectedUserInfo(mainUser)
- keyguardRepository.setDreaming(true)
+ keyguardRepository.setKeyguardShowing(true)
assertThat(isAvailable).isTrue()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/FingerprintPropertyRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/FingerprintPropertyRepositoryTest.kt
deleted file mode 100644
index 1e7ed6316f7f..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/FingerprintPropertyRepositoryTest.kt
+++ /dev/null
@@ -1,103 +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.keyguard.data.repository
-
-import android.hardware.fingerprint.FingerprintManager
-import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepositoryImpl
-import com.android.systemui.coroutines.collectLastValue
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
-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.Rule
-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.junit.MockitoJUnit
-import org.mockito.junit.MockitoRule
-
-@ExperimentalCoroutinesApi
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class FingerprintPropertyRepositoryTest : SysuiTestCase() {
- @JvmField @Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
- private val testScope = TestScope()
- private lateinit var underTest: FingerprintPropertyRepositoryImpl
- @Mock private lateinit var fingerprintManager: FingerprintManager
- @Captor
- private lateinit var fingerprintCallbackCaptor:
- ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback>
-
- @Before
- fun setup() {
- underTest =
- FingerprintPropertyRepositoryImpl(
- testScope.backgroundScope,
- Dispatchers.Main.immediate,
- fingerprintManager,
- )
- }
-
- @Test
- fun propertiesInitialized_onStartFalse() =
- testScope.runTest {
- val propertiesInitialized by collectLastValue(underTest.propertiesInitialized)
- assertThat(propertiesInitialized).isFalse()
- }
-
- @Test
- fun propertiesInitialized_onStartTrue() =
- testScope.runTest {
- // // collect sensorType to update fingerprintCallback before
- // propertiesInitialized
- // // is listened for
- val sensorType by collectLastValue(underTest.sensorType)
- runCurrent()
- captureFingerprintCallback()
-
- fingerprintCallbackCaptor.value.onAllAuthenticatorsRegistered(emptyList())
- val propertiesInitialized by collectLastValue(underTest.propertiesInitialized)
- assertThat(propertiesInitialized).isTrue()
- }
-
- @Test
- fun propertiesInitialized_updatedToTrue() =
- testScope.runTest {
- val propertiesInitialized by collectLastValue(underTest.propertiesInitialized)
- assertThat(propertiesInitialized).isFalse()
-
- captureFingerprintCallback()
- fingerprintCallbackCaptor.value.onAllAuthenticatorsRegistered(emptyList())
- assertThat(propertiesInitialized).isTrue()
- }
-
- private fun captureFingerprintCallback() {
- verify(fingerprintManager)
- .addAuthenticatorsRegisteredCallback(fingerprintCallbackCaptor.capture())
- }
-}
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 c660ff3a7297..afe7b8f8d50b 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
@@ -257,7 +257,7 @@ class QSSceneAdapterImplTest : SysuiTestCase() {
runCurrent()
clearInvocations(qsImpl!!)
- underTest.setState(QSSceneAdapter.State.UnsquishingQQS(squishiness))
+ underTest.setState(QSSceneAdapter.State.UnsquishingQQS { squishiness })
with(qsImpl!!) {
verify(this).setQsVisible(true)
verify(this)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterTest.kt
index ebd65fdcd538..63ce67c5eb28 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterTest.kt
@@ -32,7 +32,7 @@ class QSSceneAdapterTest : SysuiTestCase() {
@Test
fun expanding_squishiness1() {
- assertThat(QSSceneAdapter.State.Expanding(0.3f).squishiness).isEqualTo(1f)
+ assertThat(QSSceneAdapter.State.Expanding(0.3f).squishiness()).isEqualTo(1f)
}
@Test
@@ -51,14 +51,14 @@ class QSSceneAdapterTest : SysuiTestCase() {
@Test
fun unsquishingQQS_expansionSameAsQQS() {
val squishiness = 0.6f
- assertThat(QSSceneAdapter.State.UnsquishingQQS(squishiness).expansion)
+ assertThat(QSSceneAdapter.State.UnsquishingQQS { squishiness }.expansion)
.isEqualTo(QSSceneAdapter.State.QQS.expansion)
}
@Test
fun unsquishingQS_expansionSameAsQS() {
val squishiness = 0.6f
- assertThat(QSSceneAdapter.State.UnsquishingQS(squishiness).expansion)
+ assertThat(QSSceneAdapter.State.UnsquishingQS { squishiness }.expansion)
.isEqualTo(QSSceneAdapter.State.QS.expansion)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt
index dddf582908c7..9a952742f735 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt
@@ -18,20 +18,13 @@ package com.android.systemui.volume.panel.component.anc.data.repository
import android.bluetooth.BluetoothDevice
import android.net.Uri
+import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.bluetooth.CachedBluetoothDevice
-import com.android.settingslib.media.BluetoothMediaDevice
-import com.android.settingslib.media.MediaDevice
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.util.mockito.any
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.volume.localMediaRepository
-import com.android.systemui.volume.localMediaRepositoryFactory
import com.android.systemui.volume.panel.component.anc.FakeSliceFactory
import com.android.systemui.volume.panel.component.anc.sliceViewManager
import com.google.common.truth.Truth.assertThat
@@ -41,10 +34,14 @@ 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.mock
+import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
class AncSliceRepositoryTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -57,23 +54,23 @@ class AncSliceRepositoryTest : SysuiTestCase() {
val slice = FakeSliceFactory.createSlice(hasError = false, hasSliceItem = true)
whenever(sliceViewManager.bindSlice(any<Uri>())).thenReturn(slice)
- underTest =
- AncSliceRepositoryImpl(
- localMediaRepositoryFactory,
- testScope.testScheduler,
- testScope.testScheduler,
- sliceViewManager,
- )
+ underTest = AncSliceRepositoryImpl(testScope.testScheduler, sliceViewManager)
}
}
@Test
- fun noConnectedDevice_noSlice() {
+ fun connectedDevice_noUri_noSlice() {
with(kosmos) {
testScope.runTest {
- localMediaRepository.updateCurrentConnectedDevice(null)
-
- val slice by collectLastValue(underTest.ancSlice(1, false, false))
+ val slice by
+ collectLastValue(
+ underTest.ancSlice(
+ device = createMediaDevice(""),
+ width = 1,
+ isCollapsed = false,
+ hideLabel = false,
+ )
+ )
runCurrent()
assertThat(slice).isNull()
@@ -82,12 +79,18 @@ class AncSliceRepositoryTest : SysuiTestCase() {
}
@Test
- fun connectedDevice_sliceReturned() {
+ fun connectedDevice_hasUri_sliceReturned() {
with(kosmos) {
testScope.runTest {
- localMediaRepository.updateCurrentConnectedDevice(createMediaDevice())
-
- val slice by collectLastValue(underTest.ancSlice(1, false, false))
+ val slice by
+ collectLastValue(
+ underTest.ancSlice(
+ device = createMediaDevice("content://test.slice"),
+ width = 1,
+ isCollapsed = false,
+ hideLabel = false,
+ )
+ )
runCurrent()
assertThat(slice).isNotNull()
@@ -95,21 +98,13 @@ class AncSliceRepositoryTest : SysuiTestCase() {
}
}
- private fun createMediaDevice(sliceUri: String = "content://test.slice"): MediaDevice {
- val bluetoothDevice: BluetoothDevice = mock {
- whenever(getMetadata(any()))
- .thenReturn(
- ("<HEARABLE_CONTROL_SLICE_WITH_WIDTH>" +
- sliceUri +
- "</HEARABLE_CONTROL_SLICE_WITH_WIDTH>")
- .toByteArray()
- )
- }
- val cachedBluetoothDevice: CachedBluetoothDevice = mock {
- whenever(device).thenReturn(bluetoothDevice)
- }
- return mock<BluetoothMediaDevice> {
- whenever(cachedDevice).thenReturn(cachedBluetoothDevice)
- }
+ private fun createMediaDevice(sliceUri: String): BluetoothDevice = mock {
+ on { getMetadata(any()) }
+ .thenReturn(
+ ("<HEARABLE_CONTROL_SLICE_WITH_WIDTH>" +
+ sliceUri +
+ "</HEARABLE_CONTROL_SLICE_WITH_WIDTH>")
+ .toByteArray()
+ )
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt
index 553aed8cfb05..8d052fe12a5a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt
@@ -16,7 +16,9 @@
package com.android.systemui.volume.panel.component.anc.domain
+import android.media.AudioManager
import android.net.Uri
+import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -26,10 +28,13 @@ 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.volume.data.repository.audioRepository
+import com.android.systemui.volume.localMediaRepository
import com.android.systemui.volume.panel.component.anc.FakeSliceFactory
import com.android.systemui.volume.panel.component.anc.ancSliceInteractor
import com.android.systemui.volume.panel.component.anc.ancSliceRepository
import com.android.systemui.volume.panel.component.anc.sliceViewManager
+import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.TestMediaDevicesFactory
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
@@ -41,6 +46,7 @@ import org.junit.runner.RunWith
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
class AncAvailabilityCriteriaTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -74,6 +80,10 @@ class AncAvailabilityCriteriaTest : SysuiTestCase() {
fun hasSlice_available() {
with(kosmos) {
testScope.runTest {
+ audioRepository.setMode(AudioManager.MODE_NORMAL)
+ localMediaRepository.updateCurrentConnectedDevice(
+ TestMediaDevicesFactory.bluetoothMediaDevice()
+ )
ancSliceRepository.putSlice(
1,
FakeSliceFactory.createSlice(hasError = false, hasSliceItem = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt
index 81e6ac412404..741671e6a8a3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt
@@ -16,15 +16,21 @@
package com.android.systemui.volume.panel.component.anc.domain.interactor
+import android.media.AudioManager
+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.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
+import com.android.systemui.volume.data.repository.audioRepository
+import com.android.systemui.volume.localMediaRepository
import com.android.systemui.volume.panel.component.anc.FakeSliceFactory
+import com.android.systemui.volume.panel.component.anc.ancSliceInteractor
import com.android.systemui.volume.panel.component.anc.ancSliceRepository
import com.android.systemui.volume.panel.component.anc.domain.model.AncSlices
+import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.TestMediaDevicesFactory
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
@@ -36,6 +42,7 @@ import org.junit.runner.RunWith
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
class AncSliceInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -43,14 +50,12 @@ class AncSliceInteractorTest : SysuiTestCase() {
private lateinit var underTest: AncSliceInteractor
@Before
- fun setup() {
- with(kosmos) {
- underTest = AncSliceInteractor(ancSliceRepository, testScope.backgroundScope)
- }
+ fun setUp() {
+ underTest = kosmos.ancSliceInteractor
}
@Test
- fun errorSlice_returnsNull() {
+ fun errorSlice_returnsUnavailable() {
with(kosmos) {
testScope.runTest {
ancSliceRepository.putSlice(
@@ -67,7 +72,7 @@ class AncSliceInteractorTest : SysuiTestCase() {
}
@Test
- fun noSliceItem_returnsNull() {
+ fun noSliceItem_returnsUnavailable() {
with(kosmos) {
testScope.runTest {
ancSliceRepository.putSlice(
@@ -84,9 +89,31 @@ class AncSliceInteractorTest : SysuiTestCase() {
}
@Test
+ fun sliceItem_noError_noDevice_returnsUnavailable() {
+ with(kosmos) {
+ testScope.runTest {
+ ancSliceRepository.putSlice(
+ 1,
+ FakeSliceFactory.createSlice(hasError = false, hasSliceItem = true)
+ )
+
+ val slice by collectLastValue(underTest.ancSlices)
+ runCurrent()
+
+ assertThat(slice).isInstanceOf(AncSlices.Unavailable::class.java)
+ }
+ }
+ }
+
+ @Test
fun sliceItem_noError_returnsSlice() {
with(kosmos) {
testScope.runTest {
+ audioRepository.setMode(AudioManager.MODE_NORMAL)
+ localMediaRepository.updateCurrentConnectedDevice(
+ TestMediaDevicesFactory.bluetoothMediaDevice()
+ )
+
ancSliceRepository.putSlice(
1,
FakeSliceFactory.createSlice(hasError = false, hasSliceItem = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt
index 737b7f3e0af0..777240c57c2e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt
@@ -19,13 +19,13 @@ package com.android.systemui.volume.panel.component.spatial
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.spatializerInteractor
-import com.android.systemui.volume.mediaOutputInteractor
+import com.android.systemui.volume.domain.interactor.audioOutputInteractor
import com.android.systemui.volume.panel.component.spatial.domain.interactor.SpatialAudioComponentInteractor
val Kosmos.spatialAudioComponentInteractor by
Kosmos.Fixture {
SpatialAudioComponentInteractor(
- mediaOutputInteractor,
+ audioOutputInteractor,
spatializerInteractor,
testScope.backgroundScope
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt
index e36ae60ebe7d..c6c46faf97f7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt
@@ -29,7 +29,6 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.spatializerInteractor
import com.android.systemui.media.spatializerRepository
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
@@ -37,9 +36,9 @@ import com.android.systemui.util.mockito.whenever
import com.android.systemui.volume.localMediaController
import com.android.systemui.volume.localMediaRepository
import com.android.systemui.volume.mediaControllerRepository
-import com.android.systemui.volume.mediaOutputInteractor
import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioAvailabilityModel
import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioEnabledModel
+import com.android.systemui.volume.panel.component.spatial.spatialAudioComponentInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
@@ -76,12 +75,7 @@ class SpatialAudioComponentInteractorTest : SysuiTestCase() {
mediaControllerRepository.setActiveSessions(listOf(localMediaController))
- underTest =
- SpatialAudioComponentInteractor(
- mediaOutputInteractor,
- spatializerInteractor,
- testScope.backgroundScope,
- )
+ underTest = spatialAudioComponentInteractor
}
}
diff --git a/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml b/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml
index a30a12221105..c32acf2fdea2 100644
--- a/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml
+++ b/packages/SystemUI/res/drawable/qs_tile_background_flagged.xml
@@ -15,16 +15,10 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/qs_tile_ripple_color">
- <!-- We don't really use the ripple effect here, but changing it to LayerDrawable causes
- performance regression, see: b/339412453.
- Since this ripple has just one layer inside, we can try to remove that extra "background"
- layer. However this should only be done when the flag
- com.android.systemui.qs_tile_focus_state has completed all its stages and this drawable
- fully replaces the previous one to ensure consistency with code sections searching for
- specific ids in drawable hierarchy
- -->
<item
- android:id="@id/background">
+ android:id="@android:id/mask"
+ android:drawable="@drawable/qs_tile_background_shape" />
+ <item android:id="@id/background">
<layer-list>
<item
android:id="@+id/qs_tile_background_base"
@@ -32,22 +26,8 @@
<item android:id="@+id/qs_tile_background_overlay">
<selector>
<item
- android:state_hovered="true"
- android:drawable="@drawable/qs_tile_background_shape" />
- </selector>
- </item>
- <!-- In the layer below we have negative insets because we need the focus outline
- to draw outside the bounds, around the main background. We use 5dp because
- the outline stroke is 3dp and the required padding is 2dp.-->
- <item
- android:top="-5dp"
- android:right="-5dp"
- android:left="-5dp"
- android:bottom="-5dp">
- <selector>
- <item
- android:state_focused="true"
- android:drawable="@drawable/qs_tile_focused_background"/>
+ android:drawable="@drawable/qs_tile_background_shape"
+ android:state_hovered="true" />
</selector>
</item>
</layer-list>
diff --git a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
index fd456df2c9d8..33f0d02efb2a 100644
--- a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
+++ b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
@@ -13,10 +13,14 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<shape
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:shape="rectangle">
- <corners android:radius="30dp"/>
- <stroke android:width="3dp" android:color="?androidprv:attr/materialColorSecondaryFixed"/>
-</shape> \ No newline at end of file
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:inset="-5dp">
+ <shape xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+ <corners android:radius="30dp" />
+ <stroke
+ android:width="3dp"
+ android:color="?androidprv:attr/materialColorSecondaryFixed" />
+ </shape>
+</inset> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
index 05f6faea464e..8b9eabc5bd93 100644
--- a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
@@ -33,8 +33,7 @@
layout="@layout/biometric_prompt_button_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginBottom="40dp"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/bottomGuideline"
app:layout_constraintEnd_toEndOf="@id/panel"
app:layout_constraintStart_toStartOf="@id/panel" />
diff --git a/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml b/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
index 0bbe73c36fc7..9f4ad0ec8677 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
@@ -23,11 +23,12 @@
<!-- Negative Button, reserved for app -->
<Button
android:id="@+id/button_negative"
- style="@style/Widget.Dialog.Button.BorderButton"
+ style="@style/AuthCredentialNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="24dp"
+ android:layout_marginBottom="8dp"
android:ellipsize="end"
android:maxLines="2"
android:visibility="invisible"
@@ -37,11 +38,12 @@
<!-- Cancel Button, replaces negative button when biometric is accepted -->
<Button
android:id="@+id/button_cancel"
- style="@style/Widget.Dialog.Button.BorderButton"
+ style="@style/AuthCredentialNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="24dp"
+ android:layout_marginBottom="8dp"
android:text="@string/cancel"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
@@ -50,11 +52,12 @@
<!-- "Use Credential" Button, replaces if device credential is allowed -->
<Button
android:id="@+id/button_use_credential"
- style="@style/Widget.Dialog.Button.BorderButton"
+ style="@style/AuthCredentialNegativeButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="24dp"
+ android:layout_marginBottom="8dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
@@ -67,6 +70,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="24dp"
+ android:layout_marginBottom="8dp"
android:ellipsize="end"
android:maxLines="2"
android:text="@string/biometric_dialog_confirm"
@@ -82,6 +86,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="24dp"
+ android:layout_marginBottom="8dp"
android:ellipsize="end"
android:maxLines="2"
android:text="@string/biometric_dialog_try_again"
diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
index fa4d9a868fd7..9b5b59fc116f 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
@@ -31,8 +31,7 @@
layout="@layout/biometric_prompt_button_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginBottom="40dp"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/bottomGuideline"
app:layout_constraintEnd_toEndOf="@id/panel"
app:layout_constraintStart_toStartOf="@id/panel" />
diff --git a/packages/SystemUI/res/layout/screenshot_shelf.xml b/packages/SystemUI/res/layout/screenshot_shelf.xml
index 49d3a8ec8ad8..6b65e9c49ca6 100644
--- a/packages/SystemUI/res/layout/screenshot_shelf.xml
+++ b/packages/SystemUI/res/layout/screenshot_shelf.xml
@@ -26,36 +26,6 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
- <FrameLayout
- android:id="@+id/actions_container_background"
- android:visibility="gone"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:elevation="4dp"
- android:background="@drawable/shelf_action_chip_container_background"
- android:layout_marginHorizontal="@dimen/overlay_action_container_minimum_edge_spacing"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toTopOf="@id/guideline"
- >
- <HorizontalScrollView
- android:id="@+id/actions_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginVertical="@dimen/overlay_action_container_padding_vertical"
- android:layout_marginHorizontal="@dimen/overlay_action_chip_margin_start"
- android:background="@drawable/shelf_action_container_clipping_shape"
- android:clipToOutline="true"
- android:scrollbars="none">
- <LinearLayout
- android:id="@+id/screenshot_actions"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:showDividers="middle"
- android:divider="@drawable/shelf_action_chip_divider"
- android:animateLayoutChanges="true"
- />
- </HorizontalScrollView>
- </FrameLayout>
<View
android:id="@+id/screenshot_preview_border"
android:layout_width="0dp"
@@ -101,6 +71,37 @@
android:visibility="invisible"
app:layout_constraintStart_toStartOf="@id/screenshot_preview_border"
app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"/>
+ <!-- Action bar should be drawn on top of the thumbnail -->
+ <FrameLayout
+ android:id="@+id/actions_container_background"
+ android:visibility="gone"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:elevation="4dp"
+ android:background="@drawable/shelf_action_chip_container_background"
+ android:layout_marginHorizontal="@dimen/overlay_action_container_minimum_edge_spacing"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/guideline"
+ >
+ <HorizontalScrollView
+ android:id="@+id/actions_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginVertical="@dimen/overlay_action_container_padding_vertical"
+ android:layout_marginHorizontal="@dimen/overlay_action_chip_margin_start"
+ android:background="@drawable/shelf_action_container_clipping_shape"
+ android:clipToOutline="true"
+ android:scrollbars="none">
+ <LinearLayout
+ android:id="@+id/screenshot_actions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:showDividers="middle"
+ android:divider="@drawable/shelf_action_chip_divider"
+ android:animateLayoutChanges="true"
+ android:orientation="horizontal" />
+ </HorizontalScrollView>
+ </FrameLayout>
<ImageView
android:id="@+id/screenshot_badge"
android:layout_width="56dp"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9d0319c2471b..b9608134b1f8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -913,10 +913,6 @@
obvious when corner radii differ.-->
<dimen name="communal_enforced_rounded_corner_max_radius">28dp</dimen>
- <!-- Width and height used to filter widgets displayed in the communal widget picker -->
- <dimen name="communal_widget_picker_desired_width">360dp</dimen>
- <dimen name="communal_widget_picker_desired_height">240dp</dimen>
-
<!-- The width/height of the unlock icon view on keyguard. -->
<dimen name="keyguard_lock_height">42dp</dimen>
<dimen name="keyguard_lock_padding">20dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8da8316f624b..6df48a0d25fd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -765,7 +765,7 @@
<!-- QuickSettings: Wifi secondary label shown when the wifi is being enabled [CHAR LIMIT=NONE] -->
<string name="quick_settings_wifi_secondary_label_transient">Turning on&#8230;</string>
<!-- QuickSettings: Cast title [CHAR LIMIT=NONE] -->
- <string name="quick_settings_cast_title">Screen Cast</string>
+ <string name="quick_settings_cast_title">Cast</string>
<!-- QuickSettings: Cast detail panel, status text when casting [CHAR LIMIT=NONE] -->
<string name="quick_settings_casting">Casting</string>
<!-- QuickSettings: Cast detail panel, default device name [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 393a1aaec74a..88135880f61b 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -375,6 +375,12 @@
<item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
</style>
+ <style name="AuthCredentialNegativeButtonStyle" parent="TextAppearance.Material3.LabelLarge">
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
+ <item name="android:background">@color/transparent</item>
+ <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+ </style>
+
<style name="DeviceManagementDialogTitle">
<item name="android:gravity">center</item>
<item name="android:textAppearance">@style/TextAppearance.Dialog.Title</item>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index e66261c459c7..5458ab1196d7 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -240,7 +240,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
private boolean mEditSizeEnable = false;
private boolean mSettingsPanelVisibility = false;
@VisibleForTesting
- WindowMagnificationSizePrefs mWindowMagnificationSizePrefs;
+ WindowMagnificationFrameSizePrefs mWindowMagnificationFrameSizePrefs;
@Nullable
private final MirrorWindowControl mMirrorWindowControl;
@@ -270,7 +270,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mSysUiState = sysUiState;
mScvhSupplier = scvhSupplier;
mConfiguration = new Configuration(context.getResources().getConfiguration());
- mWindowMagnificationSizePrefs = new WindowMagnificationSizePrefs(mContext);
+ mWindowMagnificationFrameSizePrefs = new WindowMagnificationFrameSizePrefs(mContext);
final Display display = mContext.getDisplay();
mDisplayId = mContext.getDisplayId();
@@ -457,7 +457,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
if (!enable) {
// Keep the magnifier size when exiting edit mode
- mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(
+ mWindowMagnificationFrameSizePrefs.saveSizeForCurrentDensity(
new Size(mMagnificationFrame.width(), mMagnificationFrame.height()));
}
}
@@ -944,7 +944,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
private void setMagnificationFrame(int width, int height, int centerX, int centerY) {
- mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(new Size(width, height));
+ mWindowMagnificationFrameSizePrefs.saveSizeForCurrentDensity(new Size(width, height));
// Sets the initial frame area for the mirror and place it to the given center on the
// display.
@@ -954,11 +954,11 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
private Size restoreMagnificationWindowFrameSizeIfPossible() {
- if (!mWindowMagnificationSizePrefs.isPreferenceSavedForCurrentDensity()) {
+ if (!mWindowMagnificationFrameSizePrefs.isPreferenceSavedForCurrentDensity()) {
return getDefaultMagnificationWindowFrameSize();
}
- return mWindowMagnificationSizePrefs.getSizeForCurrentDensity();
+ return mWindowMagnificationFrameSizePrefs.getSizeForCurrentDensity();
}
private Size getDefaultMagnificationWindowFrameSize() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java
index a401f2a980c1..e83e85e1af1a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefs.java
@@ -23,14 +23,14 @@ import android.util.Size;
/**
* Class to handle SharedPreference for window magnification size.
*/
-final class WindowMagnificationSizePrefs {
+final class WindowMagnificationFrameSizePrefs {
private static final String WINDOW_MAGNIFICATION_PREFERENCES =
"window_magnification_preferences";
Context mContext;
SharedPreferences mWindowMagnificationSizePreferences;
- public WindowMagnificationSizePrefs(Context context) {
+ WindowMagnificationFrameSizePrefs(Context context) {
mContext = context;
mWindowMagnificationSizePreferences = mContext
.getSharedPreferences(WINDOW_MAGNIFICATION_PREFERENCES, Context.MODE_PRIVATE);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/NightDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/NightDisplayRepository.kt
index bf44fabc31c4..b33746c7a25f 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/NightDisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/NightDisplayRepository.kt
@@ -149,12 +149,7 @@ constructor(
secureSettings
.observerFlow(userHandle.identifier, DISPLAY_AUTO_MODE_RAW_SETTING_NAME)
.onStart { emit(Unit) }
- .map {
- secureSettings.getIntForUser(
- DISPLAY_AUTO_MODE_RAW_SETTING_NAME,
- userHandle.identifier
- ) == NIGHT_DISPLAY_AUTO_MODE_RAW_NOT_SET
- }
+ .map { isNightDisplayAutoModeRawSettingNotSet(userHandle.identifier) }
}
.distinctUntilChanged()
@@ -179,12 +174,19 @@ constructor(
colorDisplayManager.nightDisplayCustomEndTime,
globalSettings.getString(IS_FORCE_AUTO_MODE_AVAILABLE_SETTING_NAME) ==
NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE &&
- secureSettings.getIntForUser(DISPLAY_AUTO_MODE_RAW_SETTING_NAME, user.identifier) ==
- NIGHT_DISPLAY_AUTO_MODE_RAW_NOT_SET,
+ isNightDisplayAutoModeRawSettingNotSet(user.identifier),
locationController.isLocationEnabled,
)
}
+ private fun isNightDisplayAutoModeRawSettingNotSet(userId: Int): Boolean {
+ return secureSettings.getIntForUser(
+ DISPLAY_AUTO_MODE_RAW_SETTING_NAME,
+ NIGHT_DISPLAY_AUTO_MODE_RAW_NOT_SET,
+ userId
+ ) == NIGHT_DISPLAY_AUTO_MODE_RAW_NOT_SET
+ }
+
private companion object {
const val NIGHT_DISPLAY_AUTO_MODE_RAW_NOT_SET = -1
const val NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE = "1"
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
index 1f0459978c3c..d5e911efe570 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
@@ -37,7 +37,6 @@ import androidx.dynamicanimation.animation.SpringForce;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Flags;
import java.util.HashMap;
@@ -339,15 +338,11 @@ class MenuAnimationController {
mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ true);
final PointF position = mMenuView.getMenuPosition();
final PointF tuckedPosition = getTuckedMenuPosition();
- if (Flags.floatingMenuAnimatedTuck()) {
- flingThenSpringMenuWith(DynamicAnimation.TRANSLATION_X,
- Math.signum(tuckedPosition.x - position.x) * ESCAPE_VELOCITY,
- FLING_FRICTION_SCALAR,
- createDefaultSpringForce(),
- tuckedPosition.x);
- } else {
- moveToPosition(tuckedPosition);
- }
+ flingThenSpringMenuWith(DynamicAnimation.TRANSLATION_X,
+ Math.signum(tuckedPosition.x - position.x) * ESCAPE_VELOCITY,
+ FLING_FRICTION_SCALAR,
+ createDefaultSpringForce(),
+ tuckedPosition.x);
// Keep the touch region let users could click extra space to pop up the menu view
// from the screen edge
@@ -359,23 +354,19 @@ class MenuAnimationController {
void moveOutEdgeAndShow() {
mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false);
- if (Flags.floatingMenuAnimatedTuck()) {
- PointF position = mMenuView.getMenuPosition();
- springMenuWith(DynamicAnimation.TRANSLATION_X,
- createDefaultSpringForce(),
- 0,
- position.x,
- true
- );
- springMenuWith(DynamicAnimation.TRANSLATION_Y,
- createDefaultSpringForce(),
- 0,
- position.y,
- true
- );
- } else {
- mMenuView.onPositionChanged();
- }
+ PointF position = mMenuView.getMenuPosition();
+ springMenuWith(DynamicAnimation.TRANSLATION_X,
+ createDefaultSpringForce(),
+ 0,
+ position.x,
+ true
+ );
+ springMenuWith(DynamicAnimation.TRANSLATION_Y,
+ createDefaultSpringForce(),
+ 0,
+ position.y,
+ true
+ );
mMenuView.onEdgeChangedIfNeeded();
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
index be75e1035ea6..9d9e7dfb7032 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
@@ -321,22 +321,6 @@ class MenuView extends FrameLayout implements
if (mMoveToTuckedListener != null) {
mMoveToTuckedListener.onMoveToTuckedChanged(isMoveToTucked);
}
-
- if (!Flags.floatingMenuAnimatedTuck()) {
- if (isMoveToTucked) {
- final float halfWidth = getMenuWidth() / 2.0f;
- final boolean isOnLeftSide = mMenuAnimationController.isOnLeftSide();
- final Rect clipBounds = new Rect(
- (int) (!isOnLeftSide ? 0 : halfWidth),
- 0,
- (int) (!isOnLeftSide ? halfWidth : getMenuWidth()),
- getMenuHeight()
- );
- setClipBounds(clipBounds);
- } else {
- setClipBounds(null);
- }
- }
}
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 6dce1bb22921..0c67c5093faf 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -322,9 +322,8 @@ class MenuViewLayer extends FrameLayout implements
}
addView(mMessageView, LayerIndex.MESSAGE_VIEW);
- if (Flags.floatingMenuAnimatedTuck()) {
- setClipChildren(true);
- }
+ setClipChildren(true);
+
setClickable(false);
setFocusable(false);
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
@@ -476,10 +475,8 @@ class MenuViewLayer extends FrameLayout implements
mMenuAnimationController.startTuckedAnimationPreview();
}
- if (Flags.floatingMenuAnimatedTuck()) {
- if (!mMenuView.isMoveToTucked()) {
- setClipBounds(null);
- }
+ if (!mMenuView.isMoveToTucked()) {
+ setClipBounds(null);
}
mMenuView.onArrivalAtPosition(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 298c0f782b79..b75b292be597 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -362,7 +362,7 @@ public class AuthContainerView extends LinearLayout
mPromptSelectorInteractorProvider = promptSelectorInteractorProvider;
mPromptSelectorInteractorProvider.get().setPrompt(mConfig.mPromptInfo, mEffectiveUserId,
- biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName,
+ getRequestId(), biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName,
false /*onSwitchToCredential*/);
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
@@ -436,7 +436,7 @@ public class AuthContainerView extends LinearLayout
addCredentialView(true, false);
}
} else {
- mPromptSelectorInteractorProvider.get().resetPrompt();
+ mPromptSelectorInteractorProvider.get().resetPrompt(getRequestId());
}
}
@@ -884,7 +884,8 @@ public class AuthContainerView extends LinearLayout
final Runnable endActionRunnable = () -> {
setVisibility(View.INVISIBLE);
if (Flags.customBiometricPrompt() && constraintBp()) {
- mPromptSelectorInteractorProvider.get().resetPrompt();
+ // TODO(b/288175645): resetPrompt calls should be lifecycle aware
+ mPromptSelectorInteractorProvider.get().resetPrompt(getRequestId());
}
removeWindowIfAttached();
};
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
index 6b61adce3c84..ba51d02fd288 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
@@ -30,10 +30,10 @@ import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.biometrics.shared.model.toSensorStrength
import com.android.systemui.biometrics.shared.model.toSensorType
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.utils.coroutines.flow.conflatedCallbackFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -41,6 +41,8 @@ import kotlinx.coroutines.channels.awaitClose
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.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
@@ -111,9 +113,6 @@ constructor(
initialValue = UNINITIALIZED_PROPS,
)
- override val propertiesInitialized: Flow<Boolean> =
- props.map { it != UNINITIALIZED_PROPS }.onStart { emit(props.value != UNINITIALIZED_PROPS) }
-
override val sensorId: Flow<Int> = props.map { it.sensorId }
override val strength: Flow<SensorStrength> = props.map { it.sensorStrength.toSensorStrength() }
@@ -134,9 +133,25 @@ constructor(
}
}
+ override val propertiesInitialized: Flow<Boolean> =
+ combine(
+ props
+ .map { it != UNINITIALIZED_PROPS }
+ .onStart { emit(props.value != UNINITIALIZED_PROPS) },
+ sensorId.map {}.onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+ sensorLocations
+ .map {}
+ .onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+ sensorType.map {}.onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+ strength.map {}.onStart { if (props.value != UNINITIALIZED_PROPS) emit(Unit) },
+ ) { initialized, _, _, _, _ ->
+ initialized
+ }
+ .distinctUntilChanged()
+
companion object {
private const val TAG = "FingerprintPropertyRepositoryImpl"
- val UNINITIALIZED_PROPS =
+ private val UNINITIALIZED_PROPS =
FingerprintSensorPropertiesInternal(
-2 /* sensorId */,
SensorProperties.STRENGTH_CONVENIENCE,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
index 58b238b820c3..230b30bc548e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.data.repository
import android.hardware.biometrics.PromptInfo
+import android.util.Log
import com.android.systemui.biometrics.AuthController
import com.android.systemui.biometrics.shared.model.PromptKind
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -49,6 +50,9 @@ interface PromptRepository {
/** The user that the prompt is for. */
val userId: StateFlow<Int?>
+ /** The request that the prompt is for. */
+ val requestId: StateFlow<Long?>
+
/** The gatekeeper challenge, if one is associated with this prompt. */
val challenge: StateFlow<Long?>
@@ -69,13 +73,14 @@ interface PromptRepository {
fun setPrompt(
promptInfo: PromptInfo,
userId: Int,
+ requestId: Long,
gatekeeperChallenge: Long?,
kind: PromptKind,
opPackageName: String,
)
/** Unset the prompt info. */
- fun unsetPrompt()
+ fun unsetPrompt(requestId: Long)
}
@SysUISingleton
@@ -109,6 +114,9 @@ constructor(
private val _userId: MutableStateFlow<Int?> = MutableStateFlow(null)
override val userId = _userId.asStateFlow()
+ private val _requestId: MutableStateFlow<Long?> = MutableStateFlow(null)
+ override val requestId = _requestId.asStateFlow()
+
private val _promptKind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.None)
override val promptKind = _promptKind.asStateFlow()
@@ -132,23 +140,30 @@ constructor(
override fun setPrompt(
promptInfo: PromptInfo,
userId: Int,
+ requestId: Long,
gatekeeperChallenge: Long?,
kind: PromptKind,
opPackageName: String,
) {
_promptKind.value = kind
_userId.value = userId
+ _requestId.value = requestId
_challenge.value = gatekeeperChallenge
_promptInfo.value = promptInfo
_opPackageName.value = opPackageName
}
- override fun unsetPrompt() {
- _promptInfo.value = null
- _userId.value = null
- _challenge.value = null
- _promptKind.value = PromptKind.None
- _opPackageName.value = null
+ override fun unsetPrompt(requestId: Long) {
+ if (requestId == _requestId.value) {
+ _promptInfo.value = null
+ _userId.value = null
+ _requestId.value = null
+ _challenge.value = null
+ _promptKind.value = PromptKind.None
+ _opPackageName.value = null
+ } else {
+ Log.w(TAG, "Ignoring unsetPrompt - requestId mismatch")
+ }
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
index d5b450d1e2a8..a74b0b07299c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
@@ -52,7 +52,7 @@ constructor(
.map { it.isUdfps() }
.stateIn(
scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
+ started = SharingStarted.Eagerly,
initialValue = repository.sensorType.value.isUdfps(),
)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
index 4ba780fcec69..dc338d07f9e7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
@@ -86,6 +86,7 @@ interface PromptSelectorInteractor {
fun setPrompt(
promptInfo: PromptInfo,
effectiveUserId: Int,
+ requestId: Long,
modalities: BiometricModalities,
challenge: Long,
opPackageName: String,
@@ -93,7 +94,7 @@ interface PromptSelectorInteractor {
)
/** Unset the current authentication request. */
- fun resetPrompt()
+ fun resetPrompt(requestId: Long)
}
@SysUISingleton
@@ -161,6 +162,7 @@ constructor(
setPrompt(
promptRepository.promptInfo.value!!,
promptRepository.userId.value!!,
+ promptRepository.requestId.value!!,
modalities,
promptRepository.challenge.value!!,
promptRepository.opPackageName.value!!,
@@ -171,6 +173,7 @@ constructor(
override fun setPrompt(
promptInfo: PromptInfo,
effectiveUserId: Int,
+ requestId: Long,
modalities: BiometricModalities,
challenge: Long,
opPackageName: String,
@@ -198,13 +201,14 @@ constructor(
promptRepository.setPrompt(
promptInfo = promptInfo,
userId = effectiveUserId,
+ requestId = requestId,
gatekeeperChallenge = challenge,
kind = kind,
opPackageName = opPackageName,
)
}
- override fun resetPrompt() {
- promptRepository.unsetPrompt()
+ override fun resetPrompt(requestId: Long) {
+ promptRepository.unsetPrompt(requestId)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index 13ea3f56d911..47174c006735 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -321,6 +321,12 @@ object BiometricViewSizeBinder {
lifecycleScope.launch {
viewModel.guidelineBounds.collect { bounds ->
+ val bottomInset =
+ windowManager.maximumWindowMetrics.windowInsets
+ .getInsets(WindowInsets.Type.navigationBars())
+ .bottom
+ mediumConstraintSet.setGuidelineEnd(R.id.bottomGuideline, bottomInset)
+
if (bounds.left >= 0) {
mediumConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left)
smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left)
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 06c83962df6b..9599a8864bcc 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
@@ -61,7 +61,6 @@ 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.anyOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.util.kotlin.emitOnStart
import javax.inject.Inject
@@ -130,7 +129,7 @@ constructor(
allOf(
communalSettingsInteractor.isCommunalEnabled,
not(keyguardInteractor.isEncryptedOrLockdown),
- anyOf(keyguardInteractor.isKeyguardShowing, keyguardInteractor.isDreaming)
+ keyguardInteractor.isKeyguardShowing
)
.distinctUntilChanged()
.onEach { available ->
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 f6122ad48300..650852ce5876 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
@@ -35,7 +35,6 @@ import com.android.systemui.log.core.Logger
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 javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.CoroutineDispatcher
@@ -96,6 +95,8 @@ constructor(
uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_REORDER_WIDGET_CANCEL)
}
+ val isIdleOnCommunal: StateFlow<Boolean> = communalInteractor.isIdleOnCommunal
+
/** Launch the widget picker activity using the given {@link ActivityResultLauncher}. */
suspend fun onOpenWidgetPicker(
resources: Resources,
@@ -136,14 +137,6 @@ constructor(
return Intent(Intent.ACTION_PICK).apply {
setPackage(packageName)
putExtra(
- EXTRA_DESIRED_WIDGET_WIDTH,
- resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_width)
- )
- putExtra(
- EXTRA_DESIRED_WIDGET_HEIGHT,
- resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_height)
- )
- putExtra(
AppWidgetManager.EXTRA_CATEGORY_FILTER,
communalSettingsInteractor.communalWidgetCategories.value
)
@@ -168,8 +161,6 @@ constructor(
companion object {
private const val TAG = "CommunalEditModeViewModel"
- private const val EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width"
- private const val EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height"
private const val EXTRA_UI_SURFACE_KEY = "ui_surface"
private const val EXTRA_UI_SURFACE_VALUE = "widgets_hub"
const val EXTRA_ADDED_APP_WIDGETS_KEY = "added_app_widgets"
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index f20fafccfd19..426f484e4d02 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -44,6 +44,7 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
import javax.inject.Inject
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
/** An Activity for editing the widgets that appear in hub mode. */
@@ -69,6 +70,8 @@ constructor(
private var shouldOpenWidgetPickerOnStart = false
+ private var lockOnDestroy = false
+
private val addWidgetActivityLauncher: ActivityResultLauncher<Intent> =
registerForActivityResult(StartActivityForResult()) { result ->
when (result.resultCode) {
@@ -149,15 +152,18 @@ constructor(
}
private fun onEditDone() {
- try {
+ lifecycleScope.launch {
communalViewModel.changeScene(
CommunalScenes.Communal,
CommunalTransitionKeys.SimpleFade
)
- checkNotNull(windowManagerService).lockNow(/* options */ null)
+
+ // Wait for the current scene to be idle on communal.
+ communalViewModel.isIdleOnCommunal.first { it }
+ // Then finish the activity (this helps to avoid a flash of lockscreen when locking
+ // in onDestroy()).
+ lockOnDestroy = true
finish()
- } catch (e: RemoteException) {
- Log.e(TAG, "Couldn't lock the device as WindowManager is dead.")
}
}
@@ -190,5 +196,15 @@ constructor(
override fun onDestroy() {
super.onDestroy()
communalViewModel.setEditModeOpen(false)
+
+ if (lockOnDestroy) lockNow()
+ }
+
+ private fun lockNow() {
+ try {
+ checkNotNull(windowManagerService).lockNow(/* options */ null)
+ } catch (e: RemoteException) {
+ Log.e(TAG, "Couldn't lock the device as WindowManager is dead.")
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
index 80b52ed0e055..6c6d730819f3 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.deviceentry.domain.interactor
import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
+import com.android.systemui.biometrics.shared.model.SensorLocation
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
@@ -58,4 +59,17 @@ constructor(
flowOf(false)
}
}
+
+ /**
+ * Location of the under-display fingerprint sensor on the display. Null if the device does not
+ * support UDFPS.
+ */
+ val udfpsLocation: Flow<SensorLocation?> =
+ isUdfpsSupported.flatMapLatest {
+ if (it) {
+ fingerprintPropertyInteractor.sensorLocation
+ } else {
+ flowOf(null)
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java
index ee3706a3ba62..a0b25b930d15 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java
@@ -32,6 +32,8 @@ import android.view.View;
public class KeyguardIndication {
@Nullable
private final CharSequence mMessage;
+ @Nullable
+ private final boolean mForceAccessibilityLiveRegionAssertive;
@NonNull
private final ColorStateList mTextColor;
@Nullable
@@ -49,13 +51,15 @@ public class KeyguardIndication {
Drawable icon,
View.OnClickListener onClickListener,
Drawable background,
- Long minVisibilityMillis) {
+ Long minVisibilityMillis,
+ Boolean foceAssertive) {
mMessage = message;
mTextColor = textColor;
mIcon = icon;
mOnClickListener = onClickListener;
mBackground = background;
mMinVisibilityMillis = minVisibilityMillis;
+ mForceAccessibilityLiveRegionAssertive = foceAssertive;
}
/**
@@ -101,6 +105,15 @@ public class KeyguardIndication {
return mMinVisibilityMillis;
}
+
+ /**
+ * Whether to force the accessibility live region to be assertive.
+ */
+ public boolean getForceAssertiveAccessibilityLiveRegion() {
+ return mForceAccessibilityLiveRegionAssertive;
+ }
+
+
@Override
public String toString() {
String str = "KeyguardIndication{";
@@ -109,6 +122,7 @@ public class KeyguardIndication {
if (mOnClickListener != null) str += " mOnClickListener=" + mOnClickListener;
if (mBackground != null) str += " mBackground=" + mBackground;
if (mMinVisibilityMillis != null) str += " mMinVisibilityMillis=" + mMinVisibilityMillis;
+ if (mForceAccessibilityLiveRegionAssertive) str += "mForceAccessibilityLiveRegionAssertive";
str += "}";
return str;
}
@@ -123,6 +137,7 @@ public class KeyguardIndication {
private ColorStateList mTextColor;
private Drawable mBackground;
private Long mMinVisibilityMillis;
+ private boolean mForceAccessibilityLiveRegionAssertive;
public Builder() { }
@@ -178,6 +193,14 @@ public class KeyguardIndication {
}
/**
+ * Optional. Can force the accessibility live region to be assertive for this message.
+ */
+ public Builder setForceAccessibilityLiveRegionAssertive() {
+ this.mForceAccessibilityLiveRegionAssertive = true;
+ return this;
+ }
+
+ /**
* Build the KeyguardIndication.
*/
public KeyguardIndication build() {
@@ -190,7 +213,7 @@ public class KeyguardIndication {
return new KeyguardIndication(
mMessage, mTextColor, mIcon, mOnClickListener, mBackground,
- mMinVisibilityMillis);
+ mMinVisibilityMillis, mForceAccessibilityLiveRegionAssertive);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 674c128a580e..f9adc473b119 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -84,20 +84,25 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardSurfaceBehindViewModel
import com.android.systemui.keyguard.ui.viewmodel.WindowManagerLockscreenVisibilityViewModel;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.power.shared.model.ScreenPowerState;
+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.DisplayTracker;
import com.android.wm.shell.shared.CounterRotator;
import com.android.wm.shell.shared.ShellTransitions;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.transition.Transitions;
+import dagger.Lazy;
+
+import kotlinx.coroutines.CoroutineScope;
+
import java.util.ArrayList;
import java.util.Map;
import java.util.WeakHashMap;
import javax.inject.Inject;
-import kotlinx.coroutines.CoroutineScope;
-
public class KeyguardService extends Service {
static final String TAG = "KeyguardService";
static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
@@ -109,6 +114,7 @@ public class KeyguardService extends Service {
private final ShellTransitions mShellTransitions;
private final DisplayTracker mDisplayTracker;
private final PowerInteractor mPowerInteractor;
+ private final Lazy<SceneInteractor> mSceneInteractorLazy;
private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
@@ -316,7 +322,8 @@ public class KeyguardService extends Service {
@Application CoroutineScope scope,
FeatureFlags featureFlags,
PowerInteractor powerInteractor,
- WindowManagerOcclusionManager windowManagerOcclusionManager) {
+ WindowManagerOcclusionManager windowManagerOcclusionManager,
+ Lazy<SceneInteractor> sceneInteractorLazy) {
super();
mKeyguardViewMediator = keyguardViewMediator;
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
@@ -325,6 +332,7 @@ public class KeyguardService extends Service {
mDisplayTracker = displayTracker;
mFlags = featureFlags;
mPowerInteractor = powerInteractor;
+ mSceneInteractorLazy = sceneInteractorLazy;
if (KeyguardWmStateRefactor.isEnabled()) {
WindowManagerLockscreenVisibilityViewBinder.bind(
@@ -601,6 +609,10 @@ public class KeyguardService extends Service {
trace("showDismissibleKeyguard");
checkPermission();
mKeyguardViewMediator.showDismissibleKeyguard();
+ if (SceneContainerFlag.isEnabled()) {
+ mSceneInteractorLazy.get().changeScene(
+ Scenes.Lockscreen, "KeyguardService.showDismissibleKeyguard");
+ }
}
@Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt
index 956125ce372f..a1e4af5d5d20 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt
@@ -51,10 +51,6 @@ constructor(
) : KeyguardSmartspaceRepository {
private val _bcSmartspaceVisibility: MutableStateFlow<Int> = MutableStateFlow(View.GONE)
override val bcSmartspaceVisibility: StateFlow<Int> = _bcSmartspaceVisibility.asStateFlow()
- val defaultValue =
- context.resources.getBoolean(
- com.android.internal.R.bool.config_lockscreenWeatherEnabledByDefault
- )
override val isWeatherEnabled: StateFlow<Boolean> =
secureSettings
.observerFlow(
@@ -76,7 +72,7 @@ constructor(
private fun getLockscreenWeatherEnabled(): Boolean {
return secureSettings.getIntForUser(
Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED,
- if (defaultValue) 1 else 0,
+ 1,
userTracker.userId
) == 1
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index 7655d7a89dc3..f488d3b67fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -34,6 +34,7 @@ import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -42,6 +43,7 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.sync.Mutex
/**
* The source of truth for all keyguard transitions.
@@ -129,6 +131,7 @@ constructor(
private var lastStep: TransitionStep = TransitionStep()
private var lastAnimator: ValueAnimator? = null
+ private val _currentTransitionMutex = Mutex()
private val _currentTransitionInfo: MutableStateFlow<TransitionInfo> =
MutableStateFlow(
TransitionInfo(
@@ -146,6 +149,9 @@ constructor(
*/
private var updateTransitionId: UUID? = null
+ // Only used in a test environment
+ var forceDelayForRaceConditionTest = false
+
init {
// Start with a FINISHED transition in OFF. KeyguardBootInteractor will transition from OFF
// to either GONE or LOCKSCREEN once we're booted up and can determine which state we should
@@ -162,9 +168,21 @@ constructor(
override suspend fun startTransition(info: TransitionInfo): UUID? {
_currentTransitionInfo.value = info
+ Log.d(TAG, "(Internal) Setting current transition info: $info")
+
+ // There is no fairness guarantee with 'withContext', which means that transitions could
+ // be processed out of order. Use a Mutex to guarantee ordering.
+ _currentTransitionMutex.lock()
+
+ // Only used in a test environment
+ if (forceDelayForRaceConditionTest) {
+ delay(50L)
+ }
// Animators must be started on the main thread.
return withContext("$TAG#startTransition", mainDispatcher) {
+ _currentTransitionMutex.unlock()
+
if (lastStep.from == info.from && lastStep.to == info.to) {
Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
return@withContext null
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 b1ef76eba481..7cee258dc39f 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
@@ -20,7 +20,6 @@
package com.android.systemui.keyguard.domain.interactor
import android.content.Context
-import android.util.Log
import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
@@ -43,7 +42,6 @@ import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@SysUISingleton
@@ -80,15 +78,7 @@ constructor(
private val refreshEvents: Flow<Unit> =
merge(
configurationInteractor.onAnyConfigurationChange,
- fingerprintPropertyInteractor.propertiesInitialized
- .filter { it }
- .map { Unit }
- .onEach {
- Log.d(
- "KeyguardBlueprintInteractor",
- "triggering refreshEvent from fpPropertiesInitialized"
- )
- },
+ fingerprintPropertyInteractor.propertiesInitialized.filter { it }.map {},
)
init {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index 75c4d6f6fea6..cf6942e2f245 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -56,12 +56,6 @@ constructor(
}
scope.launch {
- sharedNotificationContainerViewModel
- .getMaxNotifications { height, useExtraShelfSpace -> height.toInt() }
- .collect { logger.log(TAG, VERBOSE, "Notif: max height in px", it) }
- }
-
- scope.launch {
sharedNotificationContainerViewModel.isOnLockscreen.collect {
logger.log(TAG, VERBOSE, "Notif: isOnLockscreen", it)
}
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 b2a24ca85b07..323ceef06a97 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
@@ -229,6 +229,7 @@ sealed class TransitionInteractor(
startTransitionTo(
toState = KeyguardState.OCCLUDED,
modeOnCanceled = TransitionModeOnCanceled.RESET,
+ ownerReason = "keyguardInteractor.onCameraLaunchDetected",
)
}
}
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 1e2db7c36432..350527a85e18 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
@@ -14,20 +14,21 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
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.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.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.pairwise
import com.android.systemui.util.kotlin.sample
+import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -48,7 +49,8 @@ constructor(
fromBouncerInteractor: FromPrimaryBouncerTransitionInteractor,
fromAlternateBouncerInteractor: FromAlternateBouncerTransitionInteractor,
notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
- sceneInteractor: SceneInteractor,
+ sceneInteractor: Lazy<SceneInteractor>,
+ deviceEntryInteractor: Lazy<DeviceEntryInteractor>,
) {
private val defaultSurfaceBehindVisibility =
transitionInteractor.finishedKeyguardState.map(::isSurfaceVisible)
@@ -112,7 +114,7 @@ constructor(
val usingKeyguardGoingAwayAnimation: Flow<Boolean> =
if (SceneContainerFlag.isEnabled) {
combine(
- sceneInteractor.transitionState,
+ sceneInteractor.get().transitionState,
surfaceBehindInteractor.isAnimatingSurface,
notificationLaunchAnimationInteractor.isLaunchAnimationRunning,
) { transition, isAnimatingSurface, isLaunchAnimationRunning ->
@@ -156,19 +158,7 @@ constructor(
*/
val lockscreenVisibility: Flow<Boolean> =
if (SceneContainerFlag.isEnabled) {
- sceneInteractor.transitionState
- .pairwise(ObservableTransitionState.Idle(Scenes.Lockscreen))
- .map { (prevTransitionState, transitionState) ->
- val isReturningToGoneAfterCancellation =
- prevTransitionState.isTransitioning(from = Scenes.Gone) &&
- transitionState.isTransitioning(to = Scenes.Gone)
- val isNotOnGone =
- !transitionState.isTransitioning(from = Scenes.Gone) &&
- !transitionState.isIdle(Scenes.Gone)
-
- isNotOnGone && !isReturningToGoneAfterCancellation
- }
- .distinctUntilChanged()
+ deviceEntryInteractor.get().isDeviceEntered.map { !it }
} else {
transitionInteractor.currentKeyguardState
.sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair)
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 c846cbe76770..f2821a0f49d2 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,6 @@ 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 kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
object KeyguardClockViewBinder {
@@ -113,24 +112,17 @@ object KeyguardClockViewBinder {
launch {
if (!MigrateClocksToBlueprint.isEnabled) return@launch
- combine(
- rootViewModel.translationX,
- rootViewModel.translationY,
- rootViewModel.scale,
- ::Triple
- )
- .collect { (translationX, translationY, scale) ->
- viewModel.currentClock.value
- ?.largeClock
- ?.layout
- ?.applyAodBurnIn(
- AodClockBurnInModel(
- translationX = translationX.value!!,
- translationY = translationY,
- scale = scale.scale
- )
+ rootViewModel.burnInModel.collect { burnInModel ->
+ viewModel.currentClock.value?.let {
+ it.largeClock.layout.applyAodBurnIn(
+ AodClockBurnInModel(
+ translationX = burnInModel.translationX.toFloat(),
+ translationY = burnInModel.translationY.toFloat(),
+ scale = burnInModel.scale
)
+ )
}
+ }
}
}
}
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 29041d1665c3..0b8376af811c 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
@@ -21,6 +21,7 @@ import android.content.Context
import android.graphics.Point
import android.graphics.Rect
import android.util.DisplayMetrics
+import android.util.Log
import android.view.View
import android.view.WindowManager
import androidx.annotation.VisibleForTesting
@@ -116,6 +117,10 @@ constructor(
override fun applyConstraints(constraintSet: ConstraintSet) {
val isUdfpsSupported =
if (DeviceEntryUdfpsRefactor.isEnabled) {
+ Log.d(
+ "DefaultDeviceEntrySection",
+ "isUdfpsSupported=${deviceEntryIconViewModel.get().isUdfpsSupported.value}"
+ )
deviceEntryIconViewModel.get().isUdfpsSupported.value
} else {
authController.isUdfpsSupported
@@ -138,8 +143,24 @@ constructor(
val iconRadiusPx = (defaultDensity * 36).toInt()
if (isUdfpsSupported) {
- authController.udfpsLocation?.let { udfpsLocation ->
- centerIcon(udfpsLocation, authController.udfpsRadius, constraintSet)
+ if (DeviceEntryUdfpsRefactor.isEnabled) {
+ deviceEntryIconViewModel.get().udfpsLocation.value?.let { udfpsLocation ->
+ Log.d(
+ "DeviceEntrySection",
+ "udfpsLocation=$udfpsLocation" +
+ " unusedAuthController=${authController.udfpsLocation}"
+ )
+ centerIcon(
+ Point(udfpsLocation.centerX.toInt(), udfpsLocation.centerY.toInt()),
+ udfpsLocation.radius,
+ constraintSet
+ )
+ }
+ } else {
+ authController.udfpsLocation?.let { udfpsLocation ->
+ Log.d("DeviceEntrySection", "udfpsLocation=$udfpsLocation")
+ centerIcon(udfpsLocation, authController.udfpsRadius, constraintSet)
+ }
}
} else {
centerIcon(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index ae83c9e720a3..8d90933b2d5a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -20,6 +20,7 @@ import android.animation.FloatEvaluator
import android.animation.IntEvaluator
import com.android.keyguard.KeyguardViewController
import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
+import com.android.systemui.biometrics.shared.model.SensorLocation
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -73,6 +74,12 @@ constructor(
@Application private val scope: CoroutineScope,
) {
val isUdfpsSupported: StateFlow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
+ val udfpsLocation: StateFlow<SensorLocation?> =
+ deviceEntryUdfpsInteractor.udfpsLocation.stateIn(
+ scope = scope,
+ started = SharingStarted.Eagerly,
+ initialValue = null,
+ )
private val intEvaluator = IntEvaluator()
private val floatEvaluator = FloatEvaluator()
private val showingAlternateBouncer: Flow<Boolean> =
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 f405b9d5a07c..f8a9310e091f 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
@@ -58,6 +58,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.combineTransform
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -117,7 +118,8 @@ constructor(
private val shadeInteractor: ShadeInteractor,
) {
private var burnInJob: Job? = null
- internal val burnInModel = MutableStateFlow(BurnInModel())
+ private val _burnInModel = MutableStateFlow(BurnInModel())
+ val burnInModel = _burnInModel.asStateFlow()
val burnInLayerVisibility: Flow<Int> =
keyguardTransitionInteractor.startedKeyguardState
@@ -279,7 +281,7 @@ constructor(
burnInJob =
scope.launch("$TAG#aodBurnInViewModel") {
- aodBurnInViewModel.movement(params).collect { burnInModel.value = it }
+ aodBurnInViewModel.movement(params).collect { _burnInModel.value = it }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index 6a6eba163a40..1e7bc0cacf1d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -54,5 +54,6 @@ class MediaFlags @Inject constructor(private val featureFlags: FeatureFlagsClass
fun isSceneContainerEnabled() = SceneContainerFlag.isEnabled
/** Check whether to use media refactor code */
- fun isMediaControlsRefactorEnabled() = MediaControlsRefactorFlag.isEnabled
+ fun isMediaControlsRefactorEnabled() =
+ MediaControlsRefactorFlag.isEnabled && SceneContainerFlag.isEnabled
}
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 4fd0df4d3f8f..c6dfdd5c137b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -148,7 +148,8 @@ open class QSTileViewImpl @JvmOverloads constructor(
*/
protected var showRippleEffect = true
- private lateinit var qsTileBackground: LayerDrawable
+ private lateinit var qsTileBackground: RippleDrawable
+ private lateinit var qsTileFocusBackground: Drawable
private lateinit var backgroundDrawable: LayerDrawable
private lateinit var backgroundBaseDrawable: Drawable
private lateinit var backgroundOverlayDrawable: Drawable
@@ -313,10 +314,11 @@ open class QSTileViewImpl @JvmOverloads constructor(
private fun createTileBackground(): Drawable {
qsTileBackground = if (Flags.qsTileFocusState()) {
- mContext.getDrawable(R.drawable.qs_tile_background_flagged) as LayerDrawable
+ mContext.getDrawable(R.drawable.qs_tile_background_flagged) as RippleDrawable
} else {
mContext.getDrawable(R.drawable.qs_tile_background) as RippleDrawable
}
+ qsTileFocusBackground = mContext.getDrawable(R.drawable.qs_tile_focused_background)!!
backgroundDrawable =
qsTileBackground.findDrawableByLayerId(R.id.background) as LayerDrawable
backgroundBaseDrawable =
@@ -332,6 +334,17 @@ open class QSTileViewImpl @JvmOverloads constructor(
updateHeight()
}
+ override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
+ if (Flags.qsTileFocusState()) {
+ if (gainFocus) {
+ qsTileFocusBackground.setBounds(0, 0, width, height)
+ overlay.add(qsTileFocusBackground)
+ } else {
+ overlay.clear()
+ }
+ }
+ }
private fun updateHeight() {
// TODO(b/332900989): Find a more robust way of resetting the tile if not reset by the
// launch animation.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
index 63acbb0d730d..fb872d538e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
@@ -127,28 +127,28 @@ interface QSSceneAdapter {
val isVisible: Boolean
val expansion: Float
- val squishiness: Float
+ val squishiness: () -> Float
data object CLOSED : State {
override val isVisible = false
override val expansion = 0f
- override val squishiness = 1f
+ override val squishiness = { 1f }
}
/** State for expanding between QQS and QS */
data class Expanding(override val expansion: Float) : State {
override val isVisible = true
- override val squishiness = 1f
+ override val squishiness = { 1f }
}
/** State for appearing QQS from Lockscreen or Gone */
- data class UnsquishingQQS(override val squishiness: Float) : State {
+ data class UnsquishingQQS(override val squishiness: () -> Float) : State {
override val isVisible = true
override val expansion = 0f
}
/** State for appearing QS from Lockscreen or Gone, used in Split shade */
- data class UnsquishingQS(override val squishiness: Float) : State {
+ data class UnsquishingQS(override val squishiness: () -> Float) : State {
override val isVisible = true
override val expansion = 1f
}
@@ -370,7 +370,7 @@ constructor(
setQsVisible(state.isVisible)
setExpanded(state.isVisible && state.expansion > 0f)
setListening(state.isVisible)
- setQsExpansion(state.expansion, 1f, 0f, state.squishiness)
+ setQsExpansion(state.expansion, 1f, 0f, state.squishiness())
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 32e383a73821..3826b50ab024 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -4218,7 +4218,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
private void registerAnimatorForTest(Animator animator) {
- if (mTestSetOfAnimatorsUsed != null) {
+ if (mTestSetOfAnimatorsUsed != null && animator != null) {
mTestSetOfAnimatorsUsed.add(animator);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 2446473c3b31..3d4b421fcc50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -633,6 +633,7 @@ public class KeyguardIndicationController {
INDICATION_TYPE_BIOMETRIC_MESSAGE,
new KeyguardIndication.Builder()
.setMessage(mBiometricMessage)
+ .setForceAccessibilityLiveRegionAssertive()
.setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
.setTextColor(mInitialTextColorState)
.build(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 446a0d746227..455c96441927 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -310,11 +310,9 @@ constructor(
fun isWeatherEnabled(): Boolean {
execution.assertIsMainThread()
- val defaultValue = context.getResources().getBoolean(
- com.android.internal.R.bool.config_lockscreenWeatherEnabledByDefault)
val showWeather = secureSettings.getIntForUser(
LOCK_SCREEN_WEATHER_ENABLED,
- if (defaultValue) 1 else 0,
+ 1,
userTracker.userId) == 1
return showWeather
}
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 bd9383de3bab..2f293e072c84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -22,11 +22,13 @@ 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.shared.PriorityPeopleSection
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
import com.android.systemui.statusbar.notification.stack.BUCKET_MEDIA_CONTROLS
import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
+import com.android.systemui.statusbar.notification.stack.BUCKET_PRIORITY_PEOPLE
import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
import com.android.systemui.util.DeviceConfigProxy
import com.android.systemui.util.Utils
@@ -53,6 +55,18 @@ class NotificationSectionsFeatureManager @Inject constructor(
}
fun getNotificationBuckets(): IntArray {
+ if (PriorityPeopleSection.isEnabled) {
+ // We don't need this list to be adaptive, it can be the superset of all features.
+ return intArrayOf(
+ BUCKET_MEDIA_CONTROLS,
+ BUCKET_HEADS_UP,
+ BUCKET_FOREGROUND_SERVICE,
+ BUCKET_PRIORITY_PEOPLE,
+ BUCKET_PEOPLE,
+ BUCKET_ALERTING,
+ BUCKET_SILENT,
+ )
+ }
return when {
isFilteringEnabled() && isMediaControlsEnabled() ->
intArrayOf(BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE, BUCKET_MEDIA_CONTROLS,
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 a901c5f8ae2a..87f11f131f32 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
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.interruption
+import android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST
import android.app.Notification
import android.app.Notification.BubbleMetadata
import android.app.Notification.CATEGORY_EVENT
@@ -23,6 +24,8 @@ import android.app.Notification.CATEGORY_REMINDER
import android.app.Notification.VISIBILITY_PRIVATE
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.database.ContentObserver
import android.hardware.display.AmbientDisplayConfiguration
import android.os.Handler
@@ -234,6 +237,7 @@ class AvalancheSuppressor(
private val avalancheProvider: AvalancheProvider,
private val systemClock: SystemClock,
private val systemSettings: SystemSettings,
+ private val packageManager: PackageManager,
) :
VisualInterruptionFilter(
types = setOf(PEEK, PULSE),
@@ -249,6 +253,7 @@ class AvalancheSuppressor(
ALLOW_CATEGORY_EVENT,
ALLOW_FSI_WITH_PERMISSION_ON,
ALLOW_COLORIZED,
+ ALLOW_EMERGENCY,
SUPPRESS
}
@@ -299,13 +304,20 @@ class AvalancheSuppressor(
if (entry.sbn.notification.isColorized) {
return State.ALLOW_COLORIZED
}
+ if (entry.sbn.notification.isColorized) {
+ return State.ALLOW_COLORIZED
+ }
+ if (
+ packageManager.checkPermission(RECEIVE_EMERGENCY_BROADCAST, entry.sbn.packageName) ==
+ PERMISSION_GRANTED
+ ) {
+ return State.ALLOW_EMERGENCY
+ }
return State.SUPPRESS
}
private fun isCooldownEnabled(): Boolean {
- return systemSettings.getInt(
- Settings.System.NOTIFICATION_COOLDOWN_ENABLED,
- /* def */ 1
- ) == 1
+ return systemSettings.getInt(Settings.System.NOTIFICATION_COOLDOWN_ENABLED, /* def */ 1) ==
+ 1
}
}
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 e6d97c211dc5..f68e194aace2 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
@@ -15,6 +15,7 @@
*/
package com.android.systemui.statusbar.notification.interruption
+import android.content.pm.PackageManager
import android.hardware.display.AmbientDisplayConfiguration
import android.os.Handler
import android.os.PowerManager
@@ -63,7 +64,8 @@ constructor(
private val uiEventLogger: UiEventLogger,
private val userTracker: UserTracker,
private val avalancheProvider: AvalancheProvider,
- private val systemSettings: SystemSettings
+ private val systemSettings: SystemSettings,
+ private val packageManager: PackageManager
) : VisualInterruptionDecisionProvider {
init {
@@ -172,7 +174,9 @@ constructor(
addFilter(AlertKeyguardVisibilitySuppressor(keyguardNotificationVisibilityProvider))
if (NotificationAvalancheSuppression.isEnabled) {
- addFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings))
+ addFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ )
avalancheProvider.register()
}
started = true
@@ -232,14 +236,17 @@ constructor(
private fun makeLoggablePeekDecision(entry: NotificationEntry): LoggableDecision =
checkConditions(PEEK)
- ?: checkFilters(PEEK, entry) ?: checkSuppressInterruptions(entry)
- ?: checkSuppressAwakeInterruptions(entry) ?: checkSuppressAwakeHeadsUp(entry)
- ?: LoggableDecision.unsuppressed
+ ?: checkFilters(PEEK, entry)
+ ?: checkSuppressInterruptions(entry)
+ ?: checkSuppressAwakeInterruptions(entry)
+ ?: checkSuppressAwakeHeadsUp(entry)
+ ?: LoggableDecision.unsuppressed
private fun makeLoggablePulseDecision(entry: NotificationEntry): LoggableDecision =
checkConditions(PULSE)
- ?: checkFilters(PULSE, entry) ?: checkSuppressInterruptions(entry)
- ?: LoggableDecision.unsuppressed
+ ?: checkFilters(PULSE, entry)
+ ?: checkSuppressInterruptions(entry)
+ ?: LoggableDecision.unsuppressed
override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision =
traceSection("VisualInterruptionDecisionProviderImpl#makeAndLogBubbleDecision") {
@@ -252,8 +259,10 @@ constructor(
private fun makeLoggableBubbleDecision(entry: NotificationEntry): LoggableDecision =
checkConditions(BUBBLE)
- ?: checkFilters(BUBBLE, entry) ?: checkSuppressInterruptions(entry)
- ?: checkSuppressAwakeInterruptions(entry) ?: LoggableDecision.unsuppressed
+ ?: checkFilters(BUBBLE, entry)
+ ?: checkSuppressInterruptions(entry)
+ ?: checkSuppressAwakeInterruptions(entry)
+ ?: LoggableDecision.unsuppressed
private fun logDecision(
type: VisualInterruptionType,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCompactMessagingTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCompactMessagingTemplateViewWrapper.kt
index bb40b5622159..20f04f950fb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCompactMessagingTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCompactMessagingTemplateViewWrapper.kt
@@ -32,6 +32,12 @@ constructor(ctx: Context, view: View, row: ExpandableNotificationRow) :
private var conversationIconView: CachingIconView? = null
private var expandBtn: View? = null
+ private var titleView: View? = null
+ private var headerTextSecondary: View? = null
+ private var subText: View? = null
+ private var facePileTop: View? = null
+ private var facePileBottom: View? = null
+ private var facePileBottomBg: View? = null
override fun onContentUpdated(row: ExpandableNotificationRow?) {
resolveViews()
super.onContentUpdated(row)
@@ -39,6 +45,14 @@ constructor(ctx: Context, view: View, row: ExpandableNotificationRow) :
private fun resolveViews() {
conversationIconView = compactMessagingView.requireViewById(R.id.conversation_icon)
+ titleView = compactMessagingView.findViewById(R.id.title)
+ headerTextSecondary = compactMessagingView.findViewById(R.id.header_text_secondary)
+ subText = compactMessagingView.findViewById(R.id.header_text)
+ facePileTop = compactMessagingView.findViewById(R.id.conversation_face_pile_top)
+ facePileBottom = compactMessagingView.findViewById(R.id.conversation_face_pile_bottom)
+ facePileBottomBg =
+ compactMessagingView.findViewById(R.id.conversation_face_pile_bottom_background)
+
expandBtn = compactMessagingView.requireViewById(R.id.expand_button)
}
@@ -47,6 +61,12 @@ constructor(ctx: Context, view: View, row: ExpandableNotificationRow) :
addViewsTransformingToSimilar(
conversationIconView,
+ titleView,
+ headerTextSecondary,
+ subText,
+ facePileTop,
+ facePileBottom,
+ facePileBottomBg,
expandBtn,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt
index d4f8ea385667..d6c73a9dda9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt
@@ -23,8 +23,8 @@ import com.android.systemui.flags.RefactorFlagUtils
/** Helper for reading or using the heads-up cycling flag state. */
@Suppress("NOTHING_TO_INLINE")
object NotificationHeadsUpCycling {
- /** The aconfig flag name */
- const val FLAG_NAME = Flags.FLAG_NOTIFICATION_HEADS_UP_CYCLING
+ /** The aconfig flag name - enable this feature when FLAG_NOTIFICATION_THROTTLE_HUN is on. */
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_THROTTLE_HUN
/** A token used for dependency declaration */
val token: FlagToken
@@ -33,7 +33,7 @@ object NotificationHeadsUpCycling {
/** Is the heads-up cycling animation enabled */
@JvmStatic
inline val isEnabled
- get() = Flags.notificationHeadsUpCycling()
+ get() = Flags.notificationThrottleHun()
/** Whether to animate the bottom line when transiting from a tall HUN to a short HUN */
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index 2d0395a2f606..5a433a1f1a04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -16,17 +16,6 @@
package com.android.systemui.statusbar.notification.stack;
-import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_MEDIA_CONTROLS;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.graphics.Rect;
-import android.view.View;
-import android.view.animation.Interpolator;
-
-import com.android.app.animation.Interpolators;
import com.android.systemui.statusbar.notification.row.ExpandableView;
/**
@@ -35,165 +24,18 @@ import com.android.systemui.statusbar.notification.row.ExpandableView;
*/
public class NotificationSection {
private @PriorityBucket final int mBucket;
- private final View mOwningView;
- private final Rect mBounds = new Rect();
- private final Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
- private final Rect mStartAnimationRect = new Rect();
- private final Rect mEndAnimationRect = new Rect();
- private ObjectAnimator mTopAnimator = null;
- private ObjectAnimator mBottomAnimator = null;
private ExpandableView mFirstVisibleChild;
private ExpandableView mLastVisibleChild;
- NotificationSection(View owningView, @PriorityBucket int bucket) {
- mOwningView = owningView;
+ NotificationSection(@PriorityBucket int bucket) {
mBucket = bucket;
}
- public void cancelAnimators() {
- if (mBottomAnimator != null) {
- mBottomAnimator.cancel();
- }
- if (mTopAnimator != null) {
- mTopAnimator.cancel();
- }
- }
-
- public Rect getCurrentBounds() {
- return mCurrentBounds;
- }
-
- public Rect getBounds() {
- return mBounds;
- }
-
- public boolean didBoundsChange() {
- return !mCurrentBounds.equals(mBounds);
- }
-
- public boolean areBoundsAnimating() {
- return mBottomAnimator != null || mTopAnimator != null;
- }
-
@PriorityBucket
public int getBucket() {
return mBucket;
}
- public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) {
- // Left and right bounds are always applied immediately.
- mCurrentBounds.left = mBounds.left;
- mCurrentBounds.right = mBounds.right;
- startBottomAnimation(animateBottom);
- startTopAnimation(animateTop);
- }
-
-
- private void startTopAnimation(boolean animate) {
- int previousEndValue = mEndAnimationRect.top;
- int newEndValue = mBounds.top;
- ObjectAnimator previousAnimator = mTopAnimator;
- if (previousAnimator != null && previousEndValue == newEndValue) {
- return;
- }
- if (!animate) {
- // just a local update was performed
- if (previousAnimator != null) {
- // we need to increase all animation keyframes of the previous animator by the
- // relative change to the end value
- int previousStartValue = mStartAnimationRect.top;
- PropertyValuesHolder[] values = previousAnimator.getValues();
- values[0].setIntValues(previousStartValue, newEndValue);
- mStartAnimationRect.top = previousStartValue;
- mEndAnimationRect.top = newEndValue;
- previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
- return;
- } else {
- // no new animation needed, let's just apply the value
- setBackgroundTop(newEndValue);
- return;
- }
- }
- if (previousAnimator != null) {
- previousAnimator.cancel();
- }
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
- mCurrentBounds.top, newEndValue);
- Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
- animator.setInterpolator(interpolator);
- animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartAnimationRect.top = -1;
- mEndAnimationRect.top = -1;
- mTopAnimator = null;
- }
- });
- animator.start();
- mStartAnimationRect.top = mCurrentBounds.top;
- mEndAnimationRect.top = newEndValue;
- mTopAnimator = animator;
- }
-
- private void startBottomAnimation(boolean animate) {
- int previousStartValue = mStartAnimationRect.bottom;
- int previousEndValue = mEndAnimationRect.bottom;
- int newEndValue = mBounds.bottom;
- ObjectAnimator previousAnimator = mBottomAnimator;
- if (previousAnimator != null && previousEndValue == newEndValue) {
- return;
- }
- if (!animate) {
- // just a local update was performed
- if (previousAnimator != null) {
- // we need to increase all animation keyframes of the previous animator by the
- // relative change to the end value
- PropertyValuesHolder[] values = previousAnimator.getValues();
- values[0].setIntValues(previousStartValue, newEndValue);
- mStartAnimationRect.bottom = previousStartValue;
- mEndAnimationRect.bottom = newEndValue;
- previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
- return;
- } else {
- // no new animation needed, let's just apply the value
- setBackgroundBottom(newEndValue);
- return;
- }
- }
- if (previousAnimator != null) {
- previousAnimator.cancel();
- }
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
- mCurrentBounds.bottom, newEndValue);
- Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
- animator.setInterpolator(interpolator);
- animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartAnimationRect.bottom = -1;
- mEndAnimationRect.bottom = -1;
- mBottomAnimator = null;
- }
- });
- animator.start();
- mStartAnimationRect.bottom = mCurrentBounds.bottom;
- mEndAnimationRect.bottom = newEndValue;
- mBottomAnimator = animator;
- }
-
- private void setBackgroundTop(int top) {
- mCurrentBounds.top = top;
- mOwningView.invalidate();
- }
-
- private void setBackgroundBottom(int bottom) {
- mCurrentBounds.bottom = bottom;
- mOwningView.invalidate();
- }
public ExpandableView getFirstVisibleChild() {
return mFirstVisibleChild;
@@ -215,91 +57,4 @@ public class NotificationSection {
return changed;
}
- public void resetCurrentBounds() {
- mCurrentBounds.set(mBounds);
- }
-
- /**
- * Returns true if {@code top} is equal to the top of this section (if not currently animating)
- * or where the top of this section will be when animation completes.
- */
- public boolean isTargetTop(int top) {
- return (mTopAnimator == null && mCurrentBounds.top == top)
- || (mTopAnimator != null && mEndAnimationRect.top == top);
- }
-
- /**
- * Returns true if {@code bottom} is equal to the bottom of this section (if not currently
- * animating) or where the bottom of this section will be when animation completes.
- */
- public boolean isTargetBottom(int bottom) {
- return (mBottomAnimator == null && mCurrentBounds.bottom == bottom)
- || (mBottomAnimator != null && mEndAnimationRect.bottom == bottom);
- }
-
- /**
- * Update the bounds of this section based on it's views
- *
- * @param minTopPosition the minimum position that the top needs to have
- * @param minBottomPosition the minimum position that the bottom needs to have
- * @return the position of the new bottom
- */
- public int updateBounds(int minTopPosition, int minBottomPosition,
- boolean shiftBackgroundWithFirst) {
- int top = minTopPosition;
- int bottom = minTopPosition;
- ExpandableView firstView = getFirstVisibleChild();
- if (firstView != null) {
- // Round Y up to avoid seeing the background during animation
- int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
- // TODO: look into the already animating part
- int newTop;
- if (isTargetTop(finalTranslationY)) {
- // we're ending up at the same location as we are now, let's just skip the
- // animation
- newTop = finalTranslationY;
- } else {
- newTop = (int) Math.ceil(firstView.getTranslationY());
- }
- top = Math.max(newTop, top);
- if (firstView.showingPulsing()) {
- // If we're pulsing, the notification can actually go below!
- bottom = Math.max(bottom, finalTranslationY
- + ExpandableViewState.getFinalActualHeight(firstView));
- if (shiftBackgroundWithFirst) {
- mBounds.left += Math.max(firstView.getTranslation(), 0);
- mBounds.right += Math.min(firstView.getTranslation(), 0);
- }
- }
- }
- ExpandableView lastView = getLastVisibleChild();
- if (lastView != null) {
- float finalTranslationY = ViewState.getFinalTranslationY(lastView);
- int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
- // Round Y down to avoid seeing the background during animation
- int finalBottom = (int) Math.floor(
- finalTranslationY + finalHeight - lastView.getClipBottomAmount());
- int newBottom;
- if (isTargetBottom(finalBottom)) {
- // we're ending up at the same location as we are now, lets just skip the animation
- newBottom = finalBottom;
- } else {
- newBottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
- - lastView.getClipBottomAmount());
- // The background can never be lower than the end of the last view
- minBottomPosition = (int) Math.min(
- lastView.getTranslationY() + lastView.getActualHeight(),
- minBottomPosition);
- }
- bottom = Math.max(bottom, Math.max(newBottom, minBottomPosition));
- }
- bottom = Math.max(top, bottom);
- mBounds.top = top;
- mBounds.bottom = bottom;
- return bottom;
- }
-
- public boolean needsBackground() {
- return mFirstVisibleChild != null && mBucket != BUCKET_MEDIA_CONTROLS;
- }
}
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 d269eda6795a..3400ad107133 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
@@ -40,7 +40,9 @@ import javax.inject.Inject
*
* TODO: Move remaining sections logic from NSSL into this class.
*/
-class NotificationSectionsManager @Inject internal constructor(
+class NotificationSectionsManager
+@Inject
+internal constructor(
private val configurationController: ConfigurationController,
private val keyguardMediaController: KeyguardMediaController,
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
@@ -52,11 +54,12 @@ class NotificationSectionsManager @Inject internal constructor(
@SilentHeader private val silentHeaderController: SectionHeaderController
) : SectionProvider {
- private val configurationListener = object : ConfigurationController.ConfigurationListener {
- override fun onLocaleListChanged() {
- reinflateViews()
+ private val configurationListener =
+ object : ConfigurationController.ConfigurationListener {
+ override fun onLocaleListChanged() {
+ reinflateViews()
+ }
}
- }
private lateinit var parent: NotificationStackScrollLayout
private var initialized = false
@@ -81,7 +84,7 @@ class NotificationSectionsManager @Inject internal constructor(
val mediaControlsView: MediaContainerView?
get() = mediaContainerController.mediaContainerView
- /** Must be called before use. */
+ /** Must be called before use. */
fun initialize(parent: NotificationStackScrollLayout) {
check(!initialized) { "NotificationSectionsManager already initialized" }
initialized = true
@@ -91,13 +94,12 @@ class NotificationSectionsManager @Inject internal constructor(
}
fun createSectionsForBuckets(): Array<NotificationSection> =
- sectionsFeatureManager.getNotificationBuckets()
- .map { NotificationSection(parent, it) }
- .toTypedArray()
+ sectionsFeatureManager
+ .getNotificationBuckets()
+ .map { NotificationSection(it) }
+ .toTypedArray()
- /**
- * Reinflates the entire notification header, including all decoration views.
- */
+ /** Reinflates the entire notification header, including all decoration views. */
fun reinflateViews() {
silentHeaderController.reinflateView(parent)
alertingHeaderController.reinflateView(parent)
@@ -108,44 +110,44 @@ class NotificationSectionsManager @Inject internal constructor(
}
override fun beginsSection(view: View, previous: View?): Boolean =
- view === silentHeaderView ||
+ view === silentHeaderView ||
view === mediaControlsView ||
view === peopleHeaderView ||
view === alertingHeaderView ||
view === incomingHeaderView ||
getBucket(view) != getBucket(previous)
- private fun getBucket(view: View?): Int? = when {
- view === silentHeaderView -> BUCKET_SILENT
- view === incomingHeaderView -> BUCKET_HEADS_UP
- view === mediaControlsView -> BUCKET_MEDIA_CONTROLS
- view === peopleHeaderView -> BUCKET_PEOPLE
- view === alertingHeaderView -> BUCKET_ALERTING
- view is ExpandableNotificationRow -> view.entry.bucket
- else -> null
- }
+ private fun getBucket(view: View?): Int? =
+ when {
+ view === silentHeaderView -> BUCKET_SILENT
+ view === incomingHeaderView -> BUCKET_HEADS_UP
+ view === mediaControlsView -> BUCKET_MEDIA_CONTROLS
+ view === peopleHeaderView -> BUCKET_PEOPLE
+ view === alertingHeaderView -> BUCKET_ALERTING
+ view is ExpandableNotificationRow -> view.entry.bucket
+ else -> null
+ }
private sealed class SectionBounds {
- data class Many(
- val first: ExpandableView,
- val last: ExpandableView
- ) : SectionBounds()
+ data class Many(val first: ExpandableView, val last: ExpandableView) : SectionBounds()
data class One(val lone: ExpandableView) : SectionBounds()
object None : SectionBounds()
- fun addNotif(notif: ExpandableView): SectionBounds = when (this) {
- is None -> One(notif)
- is One -> Many(lone, notif)
- is Many -> copy(last = notif)
- }
+ fun addNotif(notif: ExpandableView): SectionBounds =
+ when (this) {
+ is None -> One(notif)
+ is One -> Many(lone, notif)
+ is Many -> copy(last = notif)
+ }
- fun updateSection(section: NotificationSection): Boolean = when (this) {
- is None -> section.setFirstAndLastVisibleChildren(null, null)
- is One -> section.setFirstAndLastVisibleChildren(lone, lone)
- is Many -> section.setFirstAndLastVisibleChildren(first, last)
- }
+ fun updateSection(section: NotificationSection): Boolean =
+ when (this) {
+ is None -> section.setFirstAndLastVisibleChildren(null, null)
+ is One -> section.setFirstAndLastVisibleChildren(lone, lone)
+ is Many -> section.setFirstAndLastVisibleChildren(first, last)
+ }
private fun NotificationSection.setFirstAndLastVisibleChildren(
first: ExpandableView?,
@@ -167,17 +169,19 @@ class NotificationSectionsManager @Inject internal constructor(
children: List<ExpandableView>
): Boolean {
// Create mapping of bucket to section
- val sectionBounds = children.asSequence()
+ val sectionBounds =
+ children
+ .asSequence()
// Group children by bucket
.groupingBy {
getBucket(it)
- ?: throw IllegalArgumentException("Cannot find section bucket for view")
+ ?: throw IllegalArgumentException("Cannot find section bucket for view")
}
// Combine each bucket into a SectionBoundary
.foldToSparseArray(
- SectionBounds.None,
- size = sections.size,
- operation = SectionBounds::addNotif
+ SectionBounds.None,
+ size = sections.size,
+ operation = SectionBounds::addNotif
)
// Build a set of the old first/last Views of the sections
@@ -185,11 +189,12 @@ class NotificationSectionsManager @Inject internal constructor(
val oldLastChildren = sections.mapNotNull { it.lastVisibleChild }.toSet().toMutableSet()
// Update each section with the associated boundary, tracking if there was a change
- val changed = sections.fold(false) { changed, section ->
- val bounds = sectionBounds[section.bucket] ?: SectionBounds.None
- val isSectionChanged = bounds.updateSection(section)
- isSectionChanged || changed
- }
+ val changed =
+ sections.fold(false) { changed, section ->
+ val bounds = sectionBounds[section.bucket] ?: SectionBounds.None
+ val isSectionChanged = bounds.updateSection(section)
+ isSectionChanged || changed
+ }
val newFirstChildren = sections.mapNotNull { it.firstVisibleChild }
val newLastChildren = sections.mapNotNull { it.lastVisibleChild }
@@ -229,16 +234,18 @@ class NotificationSectionsManager @Inject internal constructor(
private fun logSections(sections: Array<NotificationSection>) {
for (i in sections.indices) {
val s = sections[i]
- val fs = when (val first = s.firstVisibleChild) {
- null -> "(null)"
- is ExpandableNotificationRow -> first.entry.key
- else -> Integer.toHexString(System.identityHashCode(first))
- }
- val ls = when (val last = s.lastVisibleChild) {
- null -> "(null)"
- is ExpandableNotificationRow -> last.entry.key
- else -> Integer.toHexString(System.identityHashCode(last))
- }
+ val fs =
+ when (val first = s.firstVisibleChild) {
+ null -> "(null)"
+ is ExpandableNotificationRow -> first.entry.key
+ else -> Integer.toHexString(System.identityHashCode(first))
+ }
+ val ls =
+ when (val last = s.lastVisibleChild) {
+ null -> "(null)"
+ is ExpandableNotificationRow -> last.entry.key
+ else -> Integer.toHexString(System.identityHashCode(last))
+ }
Log.d(TAG, "updateSections: f=$fs s=$i")
Log.d(TAG, "updateSections: l=$ls s=$i")
}
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 17b54c8f3970..a9d7cc003b79 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
@@ -2974,7 +2974,7 @@ public class NotificationStackScrollLayout
private void updateFirstAndLastBackgroundViews() {
ExpandableView lastChild = getLastChildWithBackground();
- boolean sectionViewsChanged = mSectionsManager.updateFirstAndLastViewsForAllSections(
+ mSectionsManager.updateFirstAndLastViewsForAllSections(
mSections, getChildrenWithBackground());
mAmbientState.setLastVisibleBackgroundChild(lastChild);
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 c1c63cdec448..6a3055f4b4cd 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
@@ -23,6 +23,7 @@ import static com.android.app.animation.Interpolators.STANDARD;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
import static com.android.server.notification.Flags.screenshareNotificationHiding;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import static com.android.systemui.Flags.confineNotificationTouchToViewWidth;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnOverscrollTopChangedListener;
@@ -597,7 +598,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
ev.getY(),
true /* requireMinHeight */,
false /* ignoreDecors */,
- true /* ignoreWidth */);
+ !confineNotificationTouchToViewWidth() /* ignoreWidth */);
if (child instanceof ExpandableNotificationRow row) {
ExpandableNotificationRow parent = row.getNotificationParent();
if (parent != null && parent.areChildrenExpanded()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index c4e0f31c9c74..16e9c717935c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -219,6 +219,7 @@ public class KeyguardIndicationTextView extends TextView {
}
private void setNextIndication() {
+ boolean forceAssertiveAccessibilityLiveRegion = false;
if (mKeyguardIndicationInfo != null) {
// First, update the style.
// If a background is set on the text, we don't want shadow on the text
@@ -239,8 +240,16 @@ public class KeyguardIndicationTextView extends TextView {
}
}
setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
+ forceAssertiveAccessibilityLiveRegion =
+ mKeyguardIndicationInfo.getForceAssertiveAccessibilityLiveRegion();
+ }
+ if (!forceAssertiveAccessibilityLiveRegion) {
+ setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_NONE);
}
setText(mMessage);
+ if (forceAssertiveAccessibilityLiveRegion) {
+ setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_ASSERTIVE);
+ }
if (mAlwaysAnnounceText) {
announceForAccessibility(mMessage);
}
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 fa88be5b638b..d9f88c494649 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -695,11 +695,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void show(Bundle options) {
Trace.beginSection("StatusBarKeyguardViewManager#show");
mNotificationShadeWindowController.setKeyguardShowing(true);
- if (SceneContainerFlag.isEnabled()) {
- // TODO(b/336581871): add sceneState?
- mSceneInteractorLazy.get().changeScene(
- Scenes.Lockscreen, "StatusBarKeyguardViewManager.show");
- }
mKeyguardStateController.notifyKeyguardState(true, mKeyguardStateController.isOccluded());
reset(true /* hideBouncerWhenShowing */);
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
index d4b2dbff078b..2e54972c4950 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
@@ -53,6 +53,27 @@ constructor(
)
}
+ fun logTopLevelServiceStateBroadcastEmergencyOnly(subId: Int, serviceState: ServiceState) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ bool1 = serviceState.isEmergencyOnly
+ },
+ { "ACTION_SERVICE_STATE for subId=$int1. ServiceState.isEmergencyOnly=$bool1" }
+ )
+ }
+
+ fun logTopLevelServiceStateBroadcastMissingExtras(subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { int1 = subId },
+ { "ACTION_SERVICE_STATE for subId=$int1. Intent is missing extras. Ignoring" }
+ )
+ }
+
fun logOnSignalStrengthsChanged(signalStrength: SignalStrength, subId: Int) {
buffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ServiceStateModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ServiceStateModel.kt
new file mode 100644
index 000000000000..cce3eb02023b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ServiceStateModel.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.pipeline.mobile.data.model
+
+import android.telephony.ServiceState
+
+/**
+ * Simplified representation of a [ServiceState] for use in SystemUI. Add any fields that we need to
+ * extract from service state here for consumption downstream
+ */
+data class ServiceStateModel(val isEmergencyOnly: Boolean) {
+ companion object {
+ fun fromServiceState(serviceState: ServiceState): ServiceStateModel {
+ return ServiceStateModel(isEmergencyOnly = serviceState.isEmergencyOnly)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
index 9471574fc755..5ad8bf1652b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
@@ -21,6 +21,7 @@ import android.telephony.SubscriptionManager
import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.MobileMappings.Config
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@@ -92,6 +93,19 @@ interface MobileConnectionsRepository {
val defaultMobileIconGroup: Flow<MobileIconGroup>
/**
+ * [deviceServiceState] is equivalent to the last [Intent.ACTION_SERVICE_STATE] broadcast with a
+ * subscriptionId of -1 (aka [SubscriptionManager.INVALID_SUBSCRIPTION_ID]).
+ *
+ * While each [MobileConnectionsRepository] listens for the service state of each subscription,
+ * there is potentially a service state associated with the device itself. This value can be
+ * used to calculate e.g., the emergency calling capability of the device (as opposed to the
+ * emergency calling capability of an individual mobile connection)
+ *
+ * Note: this is a [StateFlow] using an eager sharing strategy.
+ */
+ val deviceServiceState: StateFlow<ServiceStateModel?>
+
+ /**
* If any active SIM on the device is in
* [android.telephony.TelephonyManager.SIM_STATE_PIN_REQUIRED] or
* [android.telephony.TelephonyManager.SIM_STATE_PUK_REQUIRED] or
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
index 8a8e33efbcef..b0681525a137 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
@@ -25,6 +25,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
@@ -151,6 +152,15 @@ constructor(
override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
activeRepo.flatMapLatest { it.defaultMobileIconGroup }
+ override val deviceServiceState: StateFlow<ServiceStateModel?> =
+ activeRepo
+ .flatMapLatest { it.deviceServiceState }
+ .stateIn(
+ scope,
+ SharingStarted.WhileSubscribed(),
+ realRepository.deviceServiceState.value
+ )
+
override val isAnySimSecure: Flow<Boolean> = activeRepo.flatMapLatest { it.isAnySimSecure }
override fun getIsAnySimSecure(): Boolean = activeRepo.value.getIsAnySimSecure()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
index 2b3c6326032c..a944e9133a31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
@@ -27,6 +27,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
@@ -136,6 +137,9 @@ constructor(
override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G)
+ // TODO(b/339023069): demo command for device-based connectivity state
+ override val deviceServiceState: StateFlow<ServiceStateModel?> = MutableStateFlow(null)
+
override val isAnySimSecure: Flow<Boolean> = flowOf(getIsAnySimSecure())
override fun getIsAnySimSecure(): Boolean = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 0073e9cd3dd8..c32f0e8090ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -18,8 +18,10 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
import android.annotation.SuppressLint
import android.content.Context
+import android.content.Intent
import android.content.IntentFilter
import android.telephony.CarrierConfigManager
+import android.telephony.ServiceState
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
@@ -35,7 +37,6 @@ import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.MobileMappings.Config
import com.android.systemui.Dumpable
import com.android.systemui.broadcast.BroadcastDispatcher
-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
@@ -47,6 +48,7 @@ import com.android.systemui.statusbar.pipeline.airplane.data.repository.Airplane
import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
@@ -55,6 +57,7 @@ import com.android.systemui.statusbar.pipeline.shared.data.repository.Connectivi
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.util.kotlin.pairwise
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import java.io.PrintWriter
import java.lang.ref.WeakReference
import javax.inject.Inject
@@ -68,6 +71,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.filterNotNull
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
@@ -169,6 +173,35 @@ constructor(
}
.flowOn(bgDispatcher)
+ /** Note that this flow is eager, so we don't miss any state */
+ override val deviceServiceState: StateFlow<ServiceStateModel?> =
+ broadcastDispatcher
+ .broadcastFlow(IntentFilter(Intent.ACTION_SERVICE_STATE)) { intent, _ ->
+ val subId =
+ intent.getIntExtra(
+ SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+ INVALID_SUBSCRIPTION_ID
+ )
+
+ val extras = intent.extras
+ if (extras == null) {
+ logger.logTopLevelServiceStateBroadcastMissingExtras(subId)
+ return@broadcastFlow null
+ }
+
+ val serviceState = ServiceState.newFromBundle(extras)
+ logger.logTopLevelServiceStateBroadcastEmergencyOnly(subId, serviceState)
+ if (subId == INVALID_SUBSCRIPTION_ID) {
+ // Assume that -1 here is the device's service state. We don't care about
+ // other ones.
+ ServiceStateModel.fromServiceState(serviceState)
+ } else {
+ null
+ }
+ }
+ .filterNotNull()
+ .stateIn(scope, SharingStarted.Eagerly, null)
+
/**
* State flow that emits the set of mobile data subscriptions, each represented by its own
* [SubscriptionModel].
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index 91d7ca65b30d..cc4d5689c3fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -111,6 +111,13 @@ interface MobileIconsInteractor {
val isForceHidden: Flow<Boolean>
/**
+ * True if the device-level service state (with -1 subscription id) reports emergency calls
+ * only. This value is only useful when there are no other subscriptions OR all existing
+ * subscriptions report that they are not in service.
+ */
+ val isDeviceInEmergencyCallsOnlyMode: Flow<Boolean>
+
+ /**
* Vends out a [MobileIconInteractor] tracking the [MobileConnectionRepository] for the given
* subId.
*/
@@ -377,6 +384,9 @@ constructor(
.map { it.contains(ConnectivitySlot.MOBILE) }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ override val isDeviceInEmergencyCallsOnlyMode: Flow<Boolean> =
+ mobileConnectionsRepo.deviceServiceState.map { it?.isEmergencyOnly ?: false }
+
/** Vends out new [MobileIconInteractor] for a particular subId */
override fun getMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor =
reuseCache[subId]?.get() ?: createMobileConnectionInteractorForSubId(subId)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
index 51c053ee284a..5b954b272044 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
@@ -19,6 +19,9 @@ package com.android.systemui.statusbar.pipeline.satellite.domain.interactor
import com.android.internal.telephony.flags.Flags
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.pipeline.dagger.OemSatelliteInputLog
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
@@ -45,6 +48,7 @@ constructor(
deviceProvisioningInteractor: DeviceProvisioningInteractor,
wifiInteractor: WifiInteractor,
@Application scope: CoroutineScope,
+ @OemSatelliteInputLog private val logBuffer: LogBuffer,
) {
/** Must be observed by any UI showing Satellite iconography */
val isSatelliteAllowed =
@@ -79,25 +83,52 @@ constructor(
val isWifiActive: Flow<Boolean> =
wifiInteractor.wifiNetwork.map { it is WifiNetworkModel.Active }
+ private val allConnectionsOos =
+ iconsInteractor.icons.aggregateOver(
+ selector = { intr ->
+ combine(intr.isInService, intr.isEmergencyOnly, intr.isNonTerrestrial) {
+ isInService,
+ isEmergencyOnly,
+ isNtn ->
+ !isInService && !isEmergencyOnly && !isNtn
+ }
+ },
+ defaultValue = true, // no connections == everything is OOS
+ ) { isOosAndNotEmergencyAndNotSatellite ->
+ isOosAndNotEmergencyAndNotSatellite.all { it }
+ }
+
/** When all connections are considered OOS, satellite connectivity is potentially valid */
val areAllConnectionsOutOfService =
if (Flags.oemEnabledSatelliteFlag()) {
- iconsInteractor.icons.aggregateOver(
- selector = { intr ->
- combine(intr.isInService, intr.isEmergencyOnly, intr.isNonTerrestrial) {
- isInService,
- isEmergencyOnly,
- isNtn ->
- !isInService && !(isEmergencyOnly || isNtn)
- }
- }
- ) { isOosAndNotEmergencyOnlyOrSatellite ->
- isOosAndNotEmergencyOnlyOrSatellite.all { it }
+ combine(
+ allConnectionsOos,
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode,
+ ) { connectionsOos, deviceEmergencyOnly ->
+ logBuffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ bool1 = connectionsOos
+ bool2 = deviceEmergencyOnly
+ },
+ {
+ "Updating OOS status. allConnectionsOOs=$bool1 " +
+ "deviceEmergencyOnly=$bool2"
+ },
+ )
+ // If no connections exist, or all are OOS, then we look to the device-based
+ // service state to detect if any calls are possible
+ connectionsOos && !deviceEmergencyOnly
}
} else {
flowOf(false)
}
.stateIn(scope, SharingStarted.WhileSubscribed(), true)
+
+ companion object {
+ const val TAG = "DeviceBasedSatelliteInteractor"
+ }
}
/**
@@ -106,12 +137,22 @@ constructor(
*
* Provides a way to connect the reactivity of the top-level flow with the reactivity of an
* arbitrarily-defined relationship ([selector]) from R to the flow that R exposes.
+ *
+ * [defaultValue] allows for a default value to be used if there are no leaf nodes after applying
+ * [selector]. E.g., if there are no mobile connections, assume that there is no service.
*/
@OptIn(ExperimentalCoroutinesApi::class)
private inline fun <R, reified S, T> Flow<List<R>>.aggregateOver(
crossinline selector: (R) -> Flow<S>,
- crossinline transform: (Array<S>) -> T
+ defaultValue: T,
+ crossinline transform: (Array<S>) -> T,
): Flow<T> {
return map { list -> list.map { selector(it) } }
- .flatMapLatest { newFlows -> combine(newFlows) { newVals -> transform(newVals) } }
+ .flatMapLatest { newFlows ->
+ if (newFlows.isEmpty()) {
+ flowOf(defaultValue)
+ } else {
+ combine(newFlows) { newVals -> transform(newVals) }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
index ca5ea3bc1caa..135edfcb6a42 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
@@ -32,6 +32,7 @@ import android.view.SurfaceControlViewHost
import android.view.SurfaceSession
import android.view.WindowManager
import android.view.WindowlessWindowManager
+import androidx.annotation.WorkerThread
import com.android.app.tracing.traceSection
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -235,8 +236,10 @@ constructor(
}
private inner class RotationWatcher : RotationChangeProvider.RotationListener {
+ @WorkerThread
override fun onRotationChanged(newRotation: Int) {
traceSection("$TAG#onRotationChanged") {
+ ensureInBackground()
if (currentRotation != newRotation) {
currentRotation = newRotation
scrimView?.revealEffect = lightRevealEffectFactory(currentRotation)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepository.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepository.kt
index 3117abc44111..e1787e8b0a9e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepository.kt
@@ -21,22 +21,15 @@ import android.net.Uri
import androidx.slice.Slice
import androidx.slice.SliceViewManager
import com.android.settingslib.bluetooth.BluetoothUtils
-import com.android.settingslib.media.BluetoothMediaDevice
-import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.slice.sliceForUri
-import com.android.systemui.volume.panel.component.mediaoutput.data.repository.LocalMediaRepositoryFactory
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.map
/** Provides ANC slice data */
interface AncSliceRepository {
@@ -49,35 +42,30 @@ interface AncSliceRepository {
* - there is no supported device connected;
* - there is no slice provider for the uri;
*/
- fun ancSlice(width: Int, isCollapsed: Boolean, hideLabel: Boolean): Flow<Slice?>
+ fun ancSlice(
+ device: BluetoothDevice,
+ width: Int,
+ isCollapsed: Boolean,
+ hideLabel: Boolean
+ ): Flow<Slice?>
}
-@OptIn(ExperimentalCoroutinesApi::class)
class AncSliceRepositoryImpl
@AssistedInject
constructor(
- mediaRepositoryFactory: LocalMediaRepositoryFactory,
- @Background private val backgroundCoroutineContext: CoroutineContext,
@Main private val mainCoroutineContext: CoroutineContext,
@Assisted private val sliceViewManager: SliceViewManager,
) : AncSliceRepository {
- private val localMediaRepository = mediaRepositoryFactory.create(null)
-
- override fun ancSlice(width: Int, isCollapsed: Boolean, hideLabel: Boolean): Flow<Slice?> {
- return localMediaRepository.currentConnectedDevice
- .map {
- (it as? BluetoothMediaDevice)
- ?.cachedDevice
- ?.device
- ?.getExtraControlUri(width, isCollapsed, hideLabel)
- }
- .distinctUntilChanged()
- .flatMapLatest { sliceUri ->
- sliceUri ?: return@flatMapLatest flowOf(null)
- sliceViewManager.sliceForUri(sliceUri).flowOn(mainCoroutineContext)
- }
- .flowOn(backgroundCoroutineContext)
+ override fun ancSlice(
+ device: BluetoothDevice,
+ width: Int,
+ isCollapsed: Boolean,
+ hideLabel: Boolean
+ ): Flow<Slice?> {
+ val sliceUri =
+ device.getExtraControlUri(width, isCollapsed, hideLabel) ?: return flowOf(null)
+ return sliceViewManager.sliceForUri(sliceUri).flowOn(mainCoroutineContext)
}
private fun BluetoothDevice.getExtraControlUri(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractor.kt
index cefa26907710..cfff45736159 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractor.kt
@@ -19,6 +19,8 @@ package com.android.systemui.volume.panel.component.anc.domain.interactor
import android.app.slice.Slice.HINT_ERROR
import android.app.slice.SliceItem.FORMAT_SLICE
import androidx.slice.Slice
+import com.android.systemui.volume.domain.interactor.AudioOutputInteractor
+import com.android.systemui.volume.domain.model.AudioOutputDevice
import com.android.systemui.volume.panel.component.anc.data.repository.AncSliceRepository
import com.android.systemui.volume.panel.component.anc.domain.model.AncSlices
import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
@@ -32,6 +34,7 @@ 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
import kotlinx.coroutines.flow.stateIn
/** Provides a valid slice from [AncSliceRepository]. */
@@ -40,6 +43,7 @@ import kotlinx.coroutines.flow.stateIn
class AncSliceInteractor
@Inject
constructor(
+ private val audioOutputInteractor: AudioOutputInteractor,
private val ancSliceRepository: AncSliceRepository,
scope: CoroutineScope,
) {
@@ -70,9 +74,20 @@ constructor(
* remove the labels from the [Slice].
*/
private fun ancSlice(width: Int, isCollapsed: Boolean, hideLabel: Boolean): Flow<Slice?> {
- return ancSliceRepository
- .ancSlice(width = width, isCollapsed = isCollapsed, hideLabel = hideLabel)
- .filter { it?.isValidSlice() != false }
+ return audioOutputInteractor.currentAudioDevice.flatMapLatest { outputDevice ->
+ if (outputDevice is AudioOutputDevice.Bluetooth) {
+ ancSliceRepository
+ .ancSlice(
+ device = outputDevice.cachedBluetoothDevice.device,
+ width = width,
+ isCollapsed = isCollapsed,
+ hideLabel = hideLabel,
+ )
+ .filter { it?.isValidSlice() != false }
+ } else {
+ flowOf(null)
+ }
+ }
}
private fun Slice.isValidSlice(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt
index 298ca67d92a8..9ca50d6f136b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt
@@ -18,11 +18,9 @@ package com.android.systemui.volume.panel.component.spatial.domain.interactor
import android.media.AudioDeviceAttributes
import android.media.AudioDeviceInfo
-import com.android.settingslib.media.BluetoothMediaDevice
-import com.android.settingslib.media.MediaDevice
-import com.android.settingslib.media.PhoneMediaDevice
import com.android.settingslib.media.domain.interactor.SpatializerInteractor
-import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
+import com.android.systemui.volume.domain.interactor.AudioOutputInteractor
+import com.android.systemui.volume.domain.model.AudioOutputDevice
import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioAvailabilityModel
import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioEnabledModel
import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
@@ -46,16 +44,20 @@ import kotlinx.coroutines.flow.stateIn
class SpatialAudioComponentInteractor
@Inject
constructor(
- mediaOutputInteractor: MediaOutputInteractor,
+ audioOutputInteractor: AudioOutputInteractor,
private val spatializerInteractor: SpatializerInteractor,
@VolumePanelScope private val coroutineScope: CoroutineScope,
) {
private val changes = MutableSharedFlow<Unit>()
private val currentAudioDeviceAttributes: StateFlow<AudioDeviceAttributes?> =
- mediaOutputInteractor.currentConnectedDevice
- .map { mediaDevice ->
- if (mediaDevice == null) builtinSpeaker else mediaDevice.getAudioDeviceAttributes()
+ audioOutputInteractor.currentAudioDevice
+ .map { audioDevice ->
+ if (audioDevice is AudioOutputDevice.Unknown) {
+ builtinSpeaker
+ } else {
+ audioDevice.getAudioDeviceAttributes()
+ }
}
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), builtinSpeaker)
@@ -135,36 +137,35 @@ constructor(
changes.emit(Unit)
}
- private suspend fun MediaDevice.getAudioDeviceAttributes(): AudioDeviceAttributes? {
+ private suspend fun AudioOutputDevice.getAudioDeviceAttributes(): AudioDeviceAttributes? {
when (this) {
- is PhoneMediaDevice -> return builtinSpeaker
- is BluetoothMediaDevice -> {
- val device = cachedDevice ?: return null
+ is AudioOutputDevice.BuiltIn -> return builtinSpeaker
+ is AudioOutputDevice.Bluetooth -> {
return listOf(
AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_BLE_HEADSET,
- device.address,
+ cachedBluetoothDevice.address,
),
AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_BLE_SPEAKER,
- device.address,
+ cachedBluetoothDevice.address,
),
AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_BLE_BROADCAST,
- device.address,
+ cachedBluetoothDevice.address,
),
AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
- device.address,
+ cachedBluetoothDevice.address,
),
AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_HEARING_AID,
- device.address,
+ cachedBluetoothDevice.address,
)
)
.firstOrNull { spatializerInteractor.isSpatialAudioAvailable(it) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
index 516b6658d24a..93c0eeaac488 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
@@ -39,9 +39,9 @@ import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class WindowMagnificationSizePrefsTest extends SysuiTestCase {
+public class WindowMagnificationFrameSizePrefsTest extends SysuiTestCase {
- WindowMagnificationSizePrefs mWindowMagnificationSizePrefs;
+ WindowMagnificationFrameSizePrefs mWindowMagnificationFrameSizePrefs;
FakeSharedPreferences mSharedPreferences;
@Before
@@ -51,24 +51,24 @@ public class WindowMagnificationSizePrefsTest extends SysuiTestCase {
when(mContext.getSharedPreferences(
eq("window_magnification_preferences"), anyInt()))
.thenReturn(mSharedPreferences);
- mWindowMagnificationSizePrefs = new WindowMagnificationSizePrefs(mContext);
+ mWindowMagnificationFrameSizePrefs = new WindowMagnificationFrameSizePrefs(mContext);
}
@Test
public void saveSizeForCurrentDensity_getExpectedSize() {
Size testSize = new Size(500, 500);
- mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(testSize);
+ mWindowMagnificationFrameSizePrefs.saveSizeForCurrentDensity(testSize);
- assertThat(mWindowMagnificationSizePrefs.getSizeForCurrentDensity())
+ assertThat(mWindowMagnificationFrameSizePrefs.getSizeForCurrentDensity())
.isEqualTo(testSize);
}
@Test
public void saveSizeForCurrentDensity_containsPreferenceForCurrentDensity() {
Size testSize = new Size(500, 500);
- mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(testSize);
+ mWindowMagnificationFrameSizePrefs.saveSizeForCurrentDensity(testSize);
- assertThat(mWindowMagnificationSizePrefs.isPreferenceSavedForCurrentDensity())
+ assertThat(mWindowMagnificationFrameSizePrefs.isPreferenceSavedForCurrentDensity())
.isTrue();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
index e0df1e0e5586..2d5e3a6788cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import android.graphics.PointF;
-import android.platform.test.annotations.EnableFlags;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
@@ -40,7 +39,6 @@ import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import androidx.test.filters.SmallTest;
-import com.android.systemui.Flags;
import com.android.systemui.Prefs;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.accessibility.utils.TestUtils;
@@ -230,7 +228,6 @@ public class MenuAnimationControllerTest extends SysuiTestCase {
}
@Test
- @EnableFlags(Flags.FLAG_FLOATING_MENU_ANIMATED_TUCK)
public void tuck_animates() {
mMenuAnimationController.cancelAnimations();
mMenuAnimationController.moveToEdgeAndHide();
@@ -239,7 +236,6 @@ public class MenuAnimationControllerTest extends SysuiTestCase {
}
@Test
- @EnableFlags(Flags.FLAG_FLOATING_MENU_ANIMATED_TUCK)
public void untuck_animates() {
mMenuAnimationController.cancelAnimations();
mMenuAnimationController.moveOutEdgeAndShow();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
index 5e4272f125d7..2682633f5dfd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
@@ -44,6 +44,8 @@ import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
private const val USER_ID = 9
+private const val REQUEST_ID = 9L
+private const val WRONG_REQUEST_ID = 10L
private const val CHALLENGE = 90L
private const val OP_PACKAGE_NAME = "biometric.testapp"
@@ -105,6 +107,7 @@ class PromptRepositoryImplTest : SysuiTestCase() {
repository.setPrompt(
PromptInfo().apply { isConfirmationRequested = case },
USER_ID,
+ REQUEST_ID,
CHALLENGE,
PromptKind.Biometric(),
OP_PACKAGE_NAME
@@ -124,6 +127,7 @@ class PromptRepositoryImplTest : SysuiTestCase() {
repository.setPrompt(
PromptInfo().apply { isConfirmationRequested = case },
USER_ID,
+ REQUEST_ID,
CHALLENGE,
PromptKind.Biometric(),
OP_PACKAGE_NAME
@@ -134,12 +138,12 @@ class PromptRepositoryImplTest : SysuiTestCase() {
}
@Test
- fun setsAndUnsetsPrompt() =
+ fun setsAndUnsetsPrompt_whenRequestIdMatches() =
testScope.runTest {
val kind = PromptKind.Pin
val promptInfo = PromptInfo()
- repository.setPrompt(promptInfo, USER_ID, CHALLENGE, kind, OP_PACKAGE_NAME)
+ repository.setPrompt(promptInfo, USER_ID, REQUEST_ID, CHALLENGE, kind, OP_PACKAGE_NAME)
assertThat(repository.promptKind.value).isEqualTo(kind)
assertThat(repository.userId.value).isEqualTo(USER_ID)
@@ -147,11 +151,33 @@ class PromptRepositoryImplTest : SysuiTestCase() {
assertThat(repository.promptInfo.value).isSameInstanceAs(promptInfo)
assertThat(repository.opPackageName.value).isEqualTo(OP_PACKAGE_NAME)
- repository.unsetPrompt()
+ repository.unsetPrompt(REQUEST_ID)
assertThat(repository.promptInfo.value).isNull()
assertThat(repository.userId.value).isNull()
assertThat(repository.challenge.value).isNull()
assertThat(repository.opPackageName.value).isNull()
}
+
+ @Test
+ fun setsAndUnsetsPrompt_whenRequestIdDoesNotMatch() =
+ testScope.runTest {
+ val kind = PromptKind.Pin
+ val promptInfo = PromptInfo()
+
+ repository.setPrompt(promptInfo, USER_ID, REQUEST_ID, CHALLENGE, kind, OP_PACKAGE_NAME)
+
+ assertThat(repository.promptKind.value).isEqualTo(kind)
+ assertThat(repository.userId.value).isEqualTo(USER_ID)
+ assertThat(repository.challenge.value).isEqualTo(CHALLENGE)
+ assertThat(repository.promptInfo.value).isSameInstanceAs(promptInfo)
+ assertThat(repository.opPackageName.value).isEqualTo(OP_PACKAGE_NAME)
+
+ repository.unsetPrompt(WRONG_REQUEST_ID)
+
+ assertThat(repository.promptInfo.value).isNotNull()
+ assertThat(repository.userId.value).isNotNull()
+ assertThat(repository.challenge.value).isNotNull()
+ assertThat(repository.opPackageName.value).isNotNull()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
index 8695c01e89d4..c4d0d23ce9f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
@@ -33,6 +33,7 @@ import org.junit.runners.JUnit4
import org.mockito.junit.MockitoJUnit
private const val USER_ID = 22
+private const val REQUEST_ID = 22L
private const val OPERATION_ID = 100L
private const val OP_PACKAGE_NAME = "biometric.testapp"
@@ -112,6 +113,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
},
kind = PromptKind.Pin,
userId = USER_ID,
+ requestId = REQUEST_ID,
challenge = OPERATION_ID,
opPackageName = OP_PACKAGE_NAME
)
@@ -137,6 +139,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
},
kind = PromptKind.Pin,
userId = USER_ID,
+ requestId = REQUEST_ID,
challenge = OPERATION_ID,
opPackageName = OP_PACKAGE_NAME
)
@@ -165,6 +168,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
},
kind = PromptKind.Pin,
userId = USER_ID,
+ requestId = REQUEST_ID,
challenge = OPERATION_ID,
opPackageName = OP_PACKAGE_NAME
)
@@ -198,6 +202,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
},
kind = kind,
userId = USER_ID,
+ requestId = REQUEST_ID,
challenge = OPERATION_ID,
opPackageName = OP_PACKAGE_NAME
)
@@ -223,7 +228,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
assertThat(pattern.stealthMode).isEqualTo(isStealth)
}
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
assertThat(prompt).isNull()
}
@@ -346,12 +351,14 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
promptInfo: PromptInfo,
kind: PromptKind,
userId: Int,
+ requestId: Long,
challenge: Long,
opPackageName: String,
) {
biometricPromptRepository.setPrompt(
promptInfo,
userId,
+ requestId,
challenge,
kind,
opPackageName,
@@ -359,8 +366,8 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
}
/** Unset the current authentication request. */
- private fun PromptCredentialInteractor.resetPrompt() {
- biometricPromptRepository.unsetPrompt()
+ private fun PromptCredentialInteractor.resetPrompt(requestId: Long) {
+ biometricPromptRepository.unsetPrompt(requestId)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
index 4068404da29f..3102a84b852a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
@@ -59,6 +59,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
private const val NEGATIVE_TEXT = "escape"
private const val USER_ID = 8
+ private const val REQUEST_ID = 8L
private const val CHALLENGE = 999L
private const val OP_PACKAGE_NAME = "biometric.testapp"
private val componentNameOverriddenForConfirmDeviceCredentialActivity =
@@ -150,6 +151,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
@@ -179,7 +181,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
}
assertThat(isConfirmationRequired).isEqualTo(confirmationRequired)
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
@@ -206,6 +208,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
@@ -214,7 +217,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
assertThat(promptKind?.isBiometric()).isTrue()
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
@@ -230,6 +233,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
@@ -238,7 +242,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
assertThat(promptKind).isEqualTo(PromptKind.Password)
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
@@ -258,6 +262,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
@@ -266,7 +271,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
assertThat(promptKind).isEqualTo(PromptKind.Password)
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
@@ -290,6 +295,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
@@ -298,7 +304,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
assertThat(promptKind).isEqualTo(PromptKind.Password)
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
@@ -319,6 +325,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
@@ -327,7 +334,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
assertThat(promptKind?.isBiometric()).isTrue()
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
@@ -355,6 +362,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
interactor.setPrompt(
info,
USER_ID,
+ REQUEST_ID,
BiometricModalities(),
CHALLENGE,
OP_PACKAGE_NAME,
@@ -365,7 +373,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
assertThat(currentPrompt).isNull()
assertThat(credentialKind).isEqualTo(PromptKind.None)
- interactor.resetPrompt()
+ interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
index 3245020ec584..9e804c123520 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
@@ -22,6 +22,7 @@ import org.junit.runner.RunWith
import org.junit.runners.JUnit4
private const val USER_ID = 9
+private const val REQUEST_ID = 9L
private const val OPERATION_ID = 10L
@OptIn(ExperimentalCoroutinesApi::class)
@@ -171,7 +172,7 @@ class CredentialViewModelTest : SysuiTestCase() {
) =
runTest(dispatcher) {
init()
- promptRepository.setPrompt(promptInfo(), USER_ID, OPERATION_ID, kind)
+ promptRepository.setPrompt(promptInfo(), USER_ID, REQUEST_ID, OPERATION_ID, kind)
block()
}
}
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 fa78f0c6ec1d..53ccb906c546 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
@@ -96,6 +96,7 @@ import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
private const val USER_ID = 4
+private const val REQUEST_ID = 4L
private const val CHALLENGE = 2L
private const val DELAY = 1000L
private const val OP_PACKAGE_NAME = "biometric.testapp"
@@ -1457,7 +1458,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
whenever(activityTaskManager.getTasks(1)).thenReturn(listOf(runningTaskInfo))
selector =
PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils)
- selector.resetPrompt()
+ selector.resetPrompt(REQUEST_ID)
viewModel =
PromptViewModel(
@@ -1688,6 +1689,7 @@ private fun PromptSelectorInteractor.initializePrompt(
setPrompt(
info,
USER_ID,
+ REQUEST_ID,
BiometricModalities(fingerprintProperties = fingerprint, faceProperties = face),
CHALLENGE,
packageName,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 53560d740575..48a5df91d47c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -25,16 +25,19 @@ import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.app.animation.Interpolators
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
+import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.util.KeyguardTransitionRunner
+import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -45,6 +48,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.dropWhile
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.After
@@ -372,6 +377,43 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() {
assertThat(wtfHandler.failed).isTrue()
}
+ @Test
+ fun simulateRaceConditionIsProcessedInOrder() =
+ testScope.runTest {
+ val ktr = KeyguardTransitionRepositoryImpl(kosmos.testDispatcher)
+ val steps by collectValues(ktr.transitions.dropWhile { step -> step.from == OFF })
+
+ // Add a delay to the first transition in order to attempt to have the second transition
+ // be processed first
+ val info1 = TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null)
+ launch {
+ ktr.forceDelayForRaceConditionTest = true
+ ktr.startTransition(info1)
+ }
+ val info2 = TransitionInfo(OWNER_NAME, LOCKSCREEN, OCCLUDED, animator = null)
+ launch {
+ ktr.forceDelayForRaceConditionTest = false
+ ktr.startTransition(info2)
+ }
+
+ runCurrent()
+ assertThat(steps.isEmpty()).isTrue()
+
+ advanceTimeBy(60L)
+ assertThat(steps[0])
+ .isEqualTo(
+ TransitionStep(info1.from, info1.to, 0f, TransitionState.STARTED, OWNER_NAME)
+ )
+ assertThat(steps[1])
+ .isEqualTo(
+ TransitionStep(info1.from, info1.to, 0f, TransitionState.CANCELED, OWNER_NAME)
+ )
+ assertThat(steps[2])
+ .isEqualTo(
+ TransitionStep(info2.from, info2.to, 0f, TransitionState.STARTED, OWNER_NAME)
+ )
+ }
+
private fun listWithStep(
step: BigDecimal,
start: BigDecimal = BigDecimal.ZERO,
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 00f94a57a2d1..fa3fe5c80adb 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
@@ -1669,7 +1669,9 @@ class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTest
// THEN a transition from DOZING => OCCLUDED should occur
assertThat(transitionRepository)
.startedTransition(
- ownerName = "FromDozingTransitionInteractor",
+ ownerName =
+ "FromDozingTransitionInteractor" +
+ "(keyguardInteractor.onCameraLaunchDetected)",
from = KeyguardState.DOZING,
to = KeyguardState.OCCLUDED,
animatorAssertion = { it.isNotNull() },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index a77169e74de5..2b8a644162c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -20,8 +20,11 @@ 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.authentication.data.repository.FakeAuthenticationRepository
+import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -30,6 +33,7 @@ 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.data.repository.sceneContainerRepository
+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.util.mockito.mock
@@ -38,6 +42,7 @@ import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertEquals
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -727,42 +732,48 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
@Test
@EnableSceneContainer
- fun sceneContainer_lockscreenVisibility_visibleWhenNotGone() =
+ fun lockscreenVisibility() =
testScope.runTest {
- val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility)
+ val isDeviceUnlocked by
+ collectLastValue(
+ kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+ )
+ assertThat(isDeviceUnlocked).isFalse()
- sceneTransitions.value = lsToGone
- assertThat(lockscreenVisibility).isTrue()
+ val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
- sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone)
- assertThat(lockscreenVisibility).isFalse()
-
- sceneTransitions.value = goneToLs
- assertThat(lockscreenVisibility).isFalse()
+ val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility)
+ assertThat(lockscreenVisibility).isTrue()
- sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
+ kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "")
+ assertThat(currentScene).isEqualTo(Scenes.Bouncer)
assertThat(lockscreenVisibility).isTrue()
- }
- @Test
- @EnableSceneContainer
- fun sceneContainer_lockscreenVisibility_notVisibleWhenReturningToGone() =
- testScope.runTest {
- val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility)
+ kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
+ assertThat(isDeviceUnlocked).isTrue()
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
+ assertThat(lockscreenVisibility).isFalse()
- sceneTransitions.value = goneToLs
+ kosmos.sceneInteractor.changeScene(Scenes.Shade, "")
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
assertThat(lockscreenVisibility).isFalse()
- sceneTransitions.value = lsToGone
+ kosmos.sceneInteractor.changeScene(Scenes.QuickSettings, "")
+ assertThat(currentScene).isEqualTo(Scenes.QuickSettings)
assertThat(lockscreenVisibility).isFalse()
- sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone)
+ kosmos.sceneInteractor.changeScene(Scenes.Shade, "")
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
assertThat(lockscreenVisibility).isFalse()
- sceneTransitions.value = goneToLs
+ kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
assertThat(lockscreenVisibility).isFalse()
- sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
assertThat(lockscreenVisibility).isTrue()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
index 9ec9b69d44c0..05d9495db091 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.ExpandHelper
import com.android.systemui.SysuiTestCase
@@ -39,7 +39,7 @@ import org.mockito.Mockito.`when` as whenever
@SmallTest
@TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class DragDownHelperTest : SysuiTestCase() {
private lateinit var dragDownHelper: DragDownHelper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 1504d4c1f033..995b5383c3c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -65,9 +65,9 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.os.BatteryManager;
import android.os.RemoteException;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
@@ -88,7 +88,7 @@ import java.util.List;
import java.util.Set;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class KeyguardIndicationControllerTest extends KeyguardIndicationControllerBaseTest {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt
index cdc752098aa7..4a14f8853904 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt
@@ -16,9 +16,9 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
import kotlinx.coroutines.Dispatchers
@@ -28,7 +28,7 @@ import org.junit.runner.RunWith
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class KeyguardIndicationControllerWithCoroutinesTest : KeyguardIndicationControllerBaseTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
index 8cb530c355bd..948a73208d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
@@ -1,7 +1,7 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
import android.util.DisplayMetrics
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.LogBuffer
@@ -16,7 +16,7 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class LSShadeTransitionLoggerTest : SysuiTestCase() {
lateinit var logger: LSShadeTransitionLogger
@@ -41,4 +41,4 @@ class LSShadeTransitionLoggerTest : SysuiTestCase() {
// log a non-null, non row, ensure no crash
logger.logDragDownStarted(view)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
index d3befb4ad4cd..fe2dd6d78a82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -28,7 +28,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import java.util.function.Consumer
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class LightRevealScrimTest : SysuiTestCase() {
@@ -85,4 +85,4 @@ class LightRevealScrimTest : SysuiTestCase() {
private const val DEFAULT_WIDTH = 42
private const val DEFAULT_HEIGHT = 24
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
index 402d9aab66bd..e48242a3e003 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
@@ -36,7 +36,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class LockscreenShadeQsTransitionControllerTest : SysuiTestCase() {
private val configurationController = FakeConfigurationController()
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 a92cf8c96339..69e8f4737a5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -1,9 +1,9 @@
package com.android.systemui.statusbar
import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
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
@@ -74,7 +74,7 @@ private fun <T> anyObject(): T {
@SmallTest
@RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index d3febf55117b..ef1c927f22d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -32,8 +32,8 @@ import android.os.UserHandle;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -52,7 +52,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class NotificationListenerTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
private static final int TEST_UID = 0;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index d3850be7c192..c9d910c530ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -27,9 +27,9 @@ import android.app.Notification;
import android.content.Context;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -52,7 +52,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class NotificationRemoteInputManagerTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index fc0c85e30d5a..9f94cff4ead4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -17,11 +17,11 @@
package com.android.systemui.statusbar
import android.os.IBinder
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.Choreographer
import android.view.View
import android.view.ViewRootImpl
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ShadeInterpolation
@@ -59,7 +59,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
@SmallTest
class NotificationShadeDepthControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
index 49e5c456e645..9907740672ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
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.dump.DumpManager
@@ -43,7 +43,7 @@ import org.mockito.Mockito.`when` as whenever
@SmallTest
@TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class PulseExpansionHandlerTest : SysuiTestCase() {
private lateinit var pulseExpansionHandler: PulseExpansionHandler
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java
index ce11d6a62a8c..58943ea3b4ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RemoteInputNotificationRebuilderTest.java
@@ -27,9 +27,9 @@ import android.app.RemoteInputHistoryItem;
import android.net.Uri;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -44,7 +44,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class RemoteInputNotificationRebuilderTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
index 2606be5fabad..6b9a19a92fc4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
@@ -1,7 +1,7 @@
package com.android.systemui.statusbar
import org.mockito.Mockito.`when` as whenever
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
@@ -14,7 +14,7 @@ import org.mockito.Mockito.intThat
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class SingleShadeLockScreenOverScrollerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 775dc3c95746..3346e19b4ce9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -29,9 +29,9 @@ import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -52,7 +52,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
@SmallTest
public class SmartReplyControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
index 700fb1ec332c..58473c4e07a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
@@ -1,7 +1,7 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
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.dump.DumpManager
@@ -23,7 +23,7 @@ import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
@TestableLooper.RunWithLooper
class SplitShadeLockScreenOverScrollerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
index 79a2008e7542..26692c908c5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertEquals
@@ -24,7 +24,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class StatusBarStateEventTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
index b90582575970..78c1887f7c0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
@@ -5,9 +5,9 @@ import android.os.UserHandle
import android.os.VibrationAttributes
import android.os.VibrationEffect
import android.os.Vibrator
-import android.testing.AndroidTestingRunner
import android.view.HapticFeedbackConstants
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.eq
@@ -26,7 +26,7 @@ import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import java.util.concurrent.Executor
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class VibratorHelperTest : SysuiTestCase() {
@@ -120,4 +120,4 @@ class VibratorHelperTest : SysuiTestCase() {
return verify(vibrator)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
index 7e88ae080178..643acdbb9277 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar.connectivity
import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.lifecycle.Lifecycle
import com.android.systemui.SysuiTestCase
@@ -42,7 +42,7 @@ import org.mockito.MockitoAnnotations
import java.util.concurrent.Executor
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
class AccessPointControllerImplTest : SysuiTestCase() {
@@ -244,4 +244,4 @@ class AccessPointControllerImplTest : SysuiTestCase() {
verify(wifiEntryOther).connect(any())
verify(callback, never()).onSettingsActivityTriggered(any())
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileStateTest.kt
index 7aed4f7e250b..40f81e2bae5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/MobileStateTest.kt
@@ -15,7 +15,7 @@
*/
package com.android.systemui.statusbar.connectivity
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.SysuiTestCase
@@ -26,7 +26,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class MobileStateTest : SysuiTestCase() {
private val state = MobileState()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
index 461d80412cb5..4241254e1fb9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
@@ -39,10 +39,10 @@ import android.os.Looper;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.SignalIcon.MobileIconGroup;
@@ -60,7 +60,7 @@ import org.junit.runner.RunWith;
import java.util.HashMap;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class NetworkControllerDataTest extends NetworkControllerBaseTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java
index 3bbf06dbc69c..521cb4f4c42d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerEthernetTest.java
@@ -19,9 +19,9 @@ package com.android.systemui.statusbar.connectivity;
import static junit.framework.Assert.assertEquals;
import android.net.NetworkCapabilities;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -30,7 +30,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class NetworkControllerEthernetTest extends NetworkControllerBaseTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
index 35609a5faf00..22f0e9d20c41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
@@ -33,10 +33,10 @@ import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.graph.SignalDrawable;
@@ -59,7 +59,7 @@ import java.util.Collections;
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
index 44a1c50e5a58..6c80a97625a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
@@ -34,9 +34,9 @@ import android.net.NetworkInfo;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.mobile.TelephonyIcons;
@@ -50,7 +50,7 @@ import org.mockito.Mockito;
import java.util.Collections;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
// These match the constants in WifiManager and need to be kept up to date.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt
index 5bf0a94935cf..3eeed73a539c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkTypeResIdCacheTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.connectivity
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.systemui.SysuiTestCase
@@ -26,7 +26,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NetworkTypeResIdCacheTest : SysuiTestCase() {
private lateinit var cache: NetworkTypeResIdCache
private var overrides = MobileIconCarrierIdOverridesFake()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
index 452302d4db8a..984bda1c0d21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
@@ -19,11 +19,11 @@ package com.android.systemui.statusbar.events
import android.content.Context
import android.graphics.Insets
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.AnimatorTestRule
@@ -46,7 +46,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class SystemEventChipAnimationControllerTest : SysuiTestCase() {
private lateinit var controller: SystemEventChipAnimationController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
index ae84df55e113..742494b769de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.events
-import android.testing.AndroidTestingRunner
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.display.domain.interactor.ConnectedDisplayInteractor
@@ -40,7 +40,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
index cacfa8dc0be4..376873d19624 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
@@ -19,10 +19,10 @@ package com.android.systemui.statusbar.events
import android.graphics.Insets
import android.graphics.Rect
import android.os.Process
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.View
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.AnimatorTestRule
@@ -54,7 +54,7 @@ import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
index d3f5adeb05bb..0f58990d4310 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
@@ -1,9 +1,9 @@
package com.android.systemui.statusbar.gesture
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.InputEvent
import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.FakeDisplayTracker
@@ -13,7 +13,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class GenericGestureDetectorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
index 6b2ee76a75ac..01a0fd020bda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
@@ -19,11 +19,11 @@ package com.android.systemui.statusbar.notification;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.widget.FrameLayout;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -36,7 +36,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class AboveShelfObserverTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
index fc4702c209e1..d66b010daefd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AssistantFeedbackControllerTest.java
@@ -42,9 +42,9 @@ import android.os.Handler;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -58,7 +58,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class AssistantFeedbackControllerTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
index 0103564088e0..77fd06757595 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java
@@ -25,12 +25,12 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -56,7 +56,7 @@ import java.util.List;
import java.util.Map;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class DynamicChildBindControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
index 5b72ca07edbe..d879fcecffab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
@@ -25,9 +25,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -38,9 +38,10 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
@SmallTest
-@org.junit.runner.RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class DynamicPrivacyControllerTest extends SysuiTestCase {
@@ -127,4 +128,4 @@ public class DynamicPrivacyControllerTest extends SysuiTestCase {
mDynamicPrivacyController.onUnlockedChanged();
verifyNoMoreInteractions(mListener);
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
index 1cce3b5b9e77..9e733be6665c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
@@ -16,15 +16,17 @@
package com.android.systemui.statusbar.notification
+import android.platform.test.annotations.DisableFlags
import android.provider.DeviceConfig
import android.provider.Settings
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
import com.android.systemui.util.DeviceConfigProxyFake
import com.android.systemui.util.Utils
import com.android.systemui.util.mockito.any
@@ -39,8 +41,9 @@ import org.mockito.Mockito.`when`
import org.mockito.MockitoSession
import org.mockito.quality.Strictness
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
+@DisableFlags(PriorityPeopleSection.FLAG_NAME) // this class has no logic with the flag enabled
class NotificationSectionsFeatureManagerTest : SysuiTestCase() {
var manager: NotificationSectionsFeatureManager? = null
val proxyFake = DeviceConfigProxyFake()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt
index 3b3f05d25c16..3abdf6212f22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorControllerTest.kt
@@ -1,9 +1,9 @@
package com.android.systemui.statusbar.notification
import android.app.Notification.GROUP_ALERT_SUMMARY
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
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.coroutines.collectLastValue
@@ -35,7 +35,7 @@ import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotificationTransitionAnimatorControllerTest : SysuiTestCase() {
@Mock lateinit var notificationListContainer: NotificationListContainer
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
index 1aac515f538b..a5206f52b6f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.notification
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.LogBuffer
@@ -28,7 +28,7 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class NotificationWakeUpCoordinatorLoggerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index 67b540cd762e..0906d8eadf44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
@@ -60,7 +60,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class NotificationWakeUpCoordinatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt
index 7d8cf3657ba1..382b307fb9de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt
@@ -2,6 +2,7 @@ package com.android.systemui.statusbar.notification
import android.platform.test.annotations.EnableFlags
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
@@ -10,13 +11,12 @@ import com.android.systemui.util.mockito.whenever
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class RoundableTest : SysuiTestCase() {
private val targetView: View = mock()
private val roundable = FakeRoundable(targetView = targetView)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
index 2d044fec1eb6..8e95ac599ce1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
@@ -30,8 +30,8 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -51,7 +51,7 @@ import java.util.Arrays;
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class HighPriorityProviderTest extends SysuiTestCase {
@Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
@Mock private GroupMembershipManager mGroupMembershipManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
index 892575ab6c71..2a587511eaec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
@@ -16,9 +16,9 @@
package com.android.systemui.statusbar.notification.collection
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.lifecycle.Observer
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
@@ -34,7 +34,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotifLiveDataImplTest : SysuiTestCase() {
@@ -164,4 +164,4 @@ class NotifLiveDataImplTest : SysuiTestCase() {
assertThat(executor.runAllReady()).isEqualTo(2)
verifyNoMoreInteractions(syncObserver, asyncObserver)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
index 9c8ac5cded9e..d87f827de776 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification.collection
-import android.testing.AndroidTestingRunner
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.util.concurrency.FakeExecutor
@@ -30,7 +30,7 @@ import org.junit.runner.RunWith
import java.lang.UnsupportedOperationException
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotifLiveDataStoreImplTest : SysuiTestCase() {
@@ -102,4 +102,4 @@ class NotifLiveDataStoreImplTest : SysuiTestCase() {
liveDataStoreImpl.setActiveNotifList(mutableListOf(entry1, entry2))
executor.runAllReady()
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
index 3b908b4175f9..f1da22f08e75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification.collection
-import android.testing.AndroidTestingRunner
import android.view.Choreographer
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dagger.SysUISingleton
@@ -36,7 +36,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotifPipelineChoreographerTest : SysuiTestCase() {
val viewChoreographer: Choreographer = mock()
@@ -118,4 +118,4 @@ interface NotifPipelineChoreographerTestComponent {
@BindsInstance @Main executor: DelayableExecutor
): NotifPipelineChoreographerTestComponent
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 8a48fe10d7fc..72d1db3affe8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -46,8 +46,8 @@ import android.os.UserHandle;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -64,7 +64,7 @@ import org.mockito.Mockito;
import java.util.ArrayList;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class NotificationEntryTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
private static final int TEST_UID = 0;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
index ab55a7d650c6..1fd6b042ad67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
@@ -20,7 +20,7 @@ import android.os.UserHandle
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
@@ -47,7 +47,7 @@ import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class SectionStyleProviderTest : SysuiTestCase() {
@Rule @JvmField public val setFlagsRule = SetFlagsRule()
@@ -118,4 +118,4 @@ class SectionStyleProviderTest : SysuiTestCase() {
override fun getSection(): NotifSection? = NotifSection(inputSectioner, 1)
}
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
index 4708350c1c0a..2ad3c9e1c21a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
@@ -25,7 +25,7 @@ import android.os.Bundle
import android.os.UserHandle
import android.service.notification.NotificationListenerService.Ranking
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -48,7 +48,7 @@ private const val PACKAGE = "pkg"
private const val USER_ID = -1
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class TargetSdkResolverTest : SysuiTestCase() {
private val packageManager: PackageManager = mock()
private val applicationInfo = ApplicationInfo().apply { targetSdkVersion = SDK_VERSION }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java
index b1180aebe9bd..f029a2ca6099 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerTest.java
@@ -30,8 +30,8 @@ import static java.util.Objects.requireNonNull;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -57,7 +57,7 @@ import java.util.Arrays;
import java.util.Collections;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class GroupCoalescerTest extends SysuiTestCase {
private GroupCoalescer mCoalescer;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
index f2207afeda10..1f2925528077 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
@@ -30,9 +30,9 @@ import android.app.Person;
import android.content.Intent;
import android.graphics.Color;
import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -47,7 +47,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class ColorizedFgsCoordinatorTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt
index 59fc591e4d06..e72109d4d8e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
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.statusbar.notification.collection.GroupEntryBuilder
@@ -39,7 +39,7 @@ import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class DataStoreCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: DataStoreCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
index f91e5a8cf626..543f0c72a8ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
@@ -38,7 +38,7 @@ import org.mockito.Mockito
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class DismissibilityCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: DismissibilityCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt
index a544cad03b77..4d5ea92aa0e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DreamCoordinatorTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -49,7 +49,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class DreamCoordinatorTest : SysuiTestCase() {
@Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
@Mock private lateinit var notifPipeline: NotifPipeline
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
index 929c3d4288d4..7b688d4f91fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
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.statusbar.notification.collection.GroupEntryBuilder
@@ -36,7 +36,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class GroupCountCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: GroupCountCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt
index eac0e296c51f..3f140265e5f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupWhenCoordinatorTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
-import android.testing.AndroidTestingRunner
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.SbnBuilder
@@ -45,7 +45,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class GroupWhenCoordinatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
index a652ad64ea8d..7fe97d27f273 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
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.dump.DumpManager
@@ -42,7 +42,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class GutsCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: GutsCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index cd75e0811fff..8e9323fead92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -17,8 +17,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification.GROUP_ALERT_ALL
import android.app.Notification.GROUP_ALERT_SUMMARY
-import android.testing.AndroidTestingRunner
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.log.logcatLogBuffer
@@ -70,7 +70,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class HeadsUpCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: HeadsUpCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
index 27542a462d36..5dcad4bb9e62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HideNotifsForOtherUsersCoordinatorTest.java
@@ -24,9 +24,9 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.util.SparseArray;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -47,7 +47,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class HideNotifsForOtherUsersCoordinatorTest extends SysuiTestCase {
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
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 5ff73538b359..25533d82608b 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
@@ -20,7 +20,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
import android.os.UserHandle
import android.provider.Settings
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
@@ -67,7 +67,7 @@ import kotlin.time.Duration.Companion.seconds
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardCoordinatorTest : SysuiTestCase() {
private val headsUpManager: HeadsUpManager = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java
index e90a3ac8bfdc..07c29a024a6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/MediaCoordinatorTest.java
@@ -33,8 +33,8 @@ import android.media.session.MediaSession;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.service.notification.NotificationListenerService;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
@@ -58,7 +58,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class MediaCoordinatorTest extends SysuiTestCase {
private MediaSession mMediaSession;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt
index c29ff416feb9..501bca248c76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/NotificationStatsLoggerCoordinatorTest.kt
@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.platform.test.annotations.EnableFlags
import android.service.notification.NotificationListenerService.REASON_CANCEL
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -36,7 +36,7 @@ import org.junit.runner.RunWith
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@EnableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
class NotificationStatsLoggerCoordinatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index cceaaea672c4..80127682be02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -39,10 +39,10 @@ import static java.util.Objects.requireNonNull;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.RemoteException;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
@@ -88,7 +88,7 @@ import java.util.List;
import java.util.Map;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class PreparationCoordinatorTest extends SysuiTestCase {
private NotifCollectionListener mCollectionListener;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
index 3d1253e2b05d..c05b13163d32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
@@ -35,9 +35,9 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
-import android.testing.AndroidTestingRunner;
import androidx.annotation.Nullable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -67,7 +67,7 @@ import java.util.ArrayList;
import java.util.Arrays;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RankingCoordinatorTest extends SysuiTestCase {
@Mock private StatusBarStateController mStatusBarStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
index d3df48e9ef02..deb3fc1224ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
@@ -23,8 +23,8 @@ import android.os.Handler
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
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.dump.DumpManager
@@ -54,7 +54,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class RemoteInputCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: RemoteInputCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt
index 7daadb07f89a..1b7ec5381713 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAlertTimeCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
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.statusbar.notification.collection.GroupEntryBuilder
@@ -37,7 +37,7 @@ import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class RowAlertTimeCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: RowAlertTimeCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
index a66f8ce1a92c..5b231e21e700 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
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.statusbar.notification.AssistantFeedbackController
@@ -41,7 +41,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class RowAppearanceCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: RowAppearanceCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt
index 56f16f32ec15..ccf7cdd70675 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt
@@ -17,8 +17,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.service.notification.NotificationListenerService.REASON_APP_CANCEL
import android.service.notification.NotificationListenerService.REASON_CANCEL
-import android.testing.AndroidTestingRunner
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.log.logcatLogBuffer
@@ -40,7 +40,7 @@ import java.util.concurrent.Executor
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class ShadeEventCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: ShadeEventCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
index ea4f692ef4f1..c7513de7a41a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
@@ -17,8 +17,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
import com.android.systemui.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX
@@ -51,7 +51,7 @@ import org.mockito.MockitoAnnotations.initMocks
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class StackCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: StackCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
index b1d2ea21f7fc..c8fbe61fa799 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.coordinator
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
@@ -40,7 +40,7 @@ import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class ViewConfigCoordinatorTest : SysuiTestCase() {
private lateinit var coordinator: ViewConfigCoordinator
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
index 8e6ceccbc14e..7943872558c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
@@ -20,8 +20,8 @@ import android.os.Handler
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
import com.android.systemui.SysuiTestCase
@@ -54,7 +54,7 @@ import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotifUiAdjustmentProviderTest : SysuiTestCase() {
private val lockscreenUserManager: NotificationLockscreenUserManager = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt
index 1cdd023dd01c..d2057703d560 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/SemiStableSortTest.kt
@@ -15,9 +15,9 @@
*/
package com.android.systemui.statusbar.notification.collection.listbuilder
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.util.Log
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertFalse
@@ -27,7 +27,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class SemiStableSortTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt
index 20369546d68a..49f836fe9f81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderHelperTest.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.statusbar.notification.collection.listbuilder
-import android.testing.AndroidTestingRunner
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.statusbar.notification.collection.listbuilder.ShadeListBuilderHelper.getContiguousSubLists
@@ -25,7 +25,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class ShadeListBuilderHelperTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
index 22f6bdc54b85..341a51e32a46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar.notification.collection.notifcollection
import android.service.notification.NotificationListenerService.RankingMap
-import android.testing.AndroidTestingRunner
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.log.logcatLogBuffer
@@ -34,7 +34,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotifCollectionInconsistencyTrackerTest : SysuiTestCase() {
private val logger = spy(NotifCollectionLogger(logcatLogBuffer()))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
index a09f3a35c308..99e55a85344a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification.collection.notifcollection
import android.os.Handler
-import android.testing.AndroidTestingRunner
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.statusbar.notification.collection.NotificationEntry
@@ -41,7 +41,7 @@ import java.util.function.Consumer
import java.util.function.Predicate
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class SelfTrackingLifetimeExtenderTest : SysuiTestCase() {
private lateinit var extender: TestableSelfTrackingLifetimeExtender
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
index b56f8e9364c4..586b947d5299 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
@@ -15,7 +15,7 @@
*/
package com.android.systemui.statusbar.notification.collection.provider
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.mock
@@ -29,7 +29,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class VisualStabilityProviderTest : SysuiTestCase() {
private val visualStabilityProvider = VisualStabilityProvider()
private val listener: OnReorderingAllowedListener = mock()
@@ -148,4 +148,4 @@ class VisualStabilityProviderTest : SysuiTestCase() {
visualStabilityProvider.isReorderingAllowed = true
verify(selfAddingListener, times(2)).onReorderingAllowed()
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt
index eeabc744987b..9d3e2e8dfcb4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.kt
@@ -16,10 +16,10 @@
package com.android.systemui.statusbar.notification.collection.render
import android.content.Context
-import android.testing.AndroidTestingRunner
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.logcatLogBuffer
@@ -34,7 +34,7 @@ import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ShadeViewDifferTest : SysuiTestCase() {
private lateinit var differ: ShadeViewDiffer
private val rootController = FakeController(mContext, "RootController")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt
index 2a3c1a53559e..39085295fbac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/SeenNotificationsInteractorTest.kt
@@ -15,7 +15,7 @@
package com.android.systemui.statusbar.notification.domain.interactor
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -25,7 +25,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class SeenNotificationsInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
index 4ac9dc2be161..bfa816e65eb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
@@ -30,8 +30,8 @@ import android.graphics.drawable.Icon
import android.os.Bundle
import android.os.SystemClock
import android.os.UserHandle
-import android.testing.AndroidTestingRunner
import androidx.test.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any
@@ -53,7 +53,7 @@ import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class IconManagerTest : SysuiTestCase() {
companion object {
private const val TEST_PACKAGE_NAME = "test"
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 b410b33b97d9..c9f2addfd39b 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
@@ -15,7 +15,7 @@
package com.android.systemui.statusbar.notification.icon.domain.interactor
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysUITestComponent
import com.android.systemui.SysUITestModule
@@ -52,7 +52,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotificationIconsInteractorTest : SysuiTestCase() {
private val bubbles: Bubbles = mock()
@@ -151,7 +151,7 @@ class NotificationIconsInteractorTest : SysuiTestCase() {
}
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
private val bubbles: Bubbles = mock()
@@ -256,7 +256,7 @@ class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
}
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
private val bubbles: Bubbles = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
index 60eea9beb2e0..af2789b8401a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
@@ -26,9 +26,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import androidx.core.os.CancellationSignal;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.util.NotificationMessagingUtil;
@@ -47,7 +47,7 @@ import org.mockito.MockitoAnnotations;
import java.util.concurrent.atomic.AtomicReference;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class HeadsUpViewBinderTest extends SysuiTestCase {
private HeadsUpViewBinder mViewBinder;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
index 86620480fa7b..19214fb831eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
@@ -42,9 +42,9 @@ import android.content.Context;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -86,7 +86,7 @@ import java.util.Map;
import java.util.function.Consumer;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase {
private static final int NOTIF_USER_ID = 0;
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 7ade053720e9..3e8461a225b2 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,8 +60,8 @@ import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.platform.test.annotations.DisableFlags;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.testing.UiEventLoggerFake;
@@ -96,7 +96,7 @@ import java.util.Set;
* Tests for the interruption state provider which understands whether the system & notification
* is in a state allowing a particular notification to hun, pulse, or bubble.
*/
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt
index 7ed33126a54f..a6177e8feb1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.statusbar.notification.interruption
import android.platform.test.annotations.DisableFlags
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision
@@ -34,7 +34,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@DisableFlags(VisualInterruptionRefactor.FLAG_NAME)
class NotificationInterruptStateProviderWrapperTest : VisualInterruptionDecisionProviderTestBase() {
override val provider by lazy {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
index edab9d9f7fdf..eeb51a684d42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
@@ -16,11 +16,13 @@
package com.android.systemui.statusbar.notification.interruption
+import android.Manifest.permission
import android.app.Notification.CATEGORY_EVENT
import android.app.Notification.CATEGORY_REMINDER
import android.app.NotificationManager
+import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE
@@ -28,9 +30,11 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.anyString
+import org.mockito.Mockito.`when`
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@EnableFlags(VisualInterruptionRefactor.FLAG_NAME)
class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionProviderTestBase() {
override val provider by lazy {
@@ -51,7 +55,8 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
uiEventLogger,
userTracker,
avalancheProvider,
- systemSettings
+ systemSettings,
+ packageManager
)
}
@@ -83,14 +88,18 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_HIGH
- isConversation = true
- isImportantConversation = false
- whenMs = whenAgo(5)
- })
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ isConversation = true
+ isImportantConversation = false
+ whenMs = whenAgo(5)
+ }
+ )
}
}
@@ -98,14 +107,18 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_suppressConversationFromBeforeEvent() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldNotHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_DEFAULT
- isConversation = true
- isImportantConversation = false
- whenMs = whenAgo(15)
- })
+ assertShouldNotHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_DEFAULT
+ isConversation = true
+ isImportantConversation = false
+ whenMs = whenAgo(15)
+ }
+ )
}
}
@@ -113,12 +126,16 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowHighPriorityConversation() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_HIGH
- isImportantConversation = true
- })
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ isImportantConversation = true
+ }
+ )
}
}
@@ -126,12 +143,16 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowCall() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_HIGH
- isCall = true
- })
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ isCall = true
+ }
+ )
}
}
@@ -139,12 +160,16 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowCategoryReminder() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_HIGH
- category = CATEGORY_REMINDER
- })
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ category = CATEGORY_REMINDER
+ }
+ )
}
}
@@ -152,12 +177,16 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowCategoryEvent() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_HIGH
- category = CATEGORY_EVENT
- })
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ category = CATEGORY_EVENT
+ }
+ )
}
}
@@ -165,7 +194,9 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowFsi() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
assertFsiNotSuppressed()
}
}
@@ -174,16 +205,44 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
fun testAvalancheFilter_duringAvalanche_allowColorized() {
avalancheProvider.startTime = whenAgo(10)
- withFilter(AvalancheSuppressor(avalancheProvider, systemClock, systemSettings)) {
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
ensurePeekState()
- assertShouldHeadsUp(buildEntry {
- importance = NotificationManager.IMPORTANCE_HIGH
- isColorized = true
- })
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ isColorized = true
+ }
+ )
}
}
@Test
+ fun testAvalancheFilter_duringAvalanche_allowEmergency() {
+ avalancheProvider.startTime = whenAgo(10)
+
+ `when`(
+ packageManager.checkPermission(
+ org.mockito.Mockito.eq(permission.RECEIVE_EMERGENCY_BROADCAST),
+ anyString()
+ )
+ ).thenReturn(PERMISSION_GRANTED)
+
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager)
+ ) {
+ ensurePeekState()
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ }
+ )
+ }
+ }
+
+
+ @Test
fun testPeekCondition_suppressesOnlyPeek() {
withCondition(TestCondition(types = setOf(PEEK)) { true }) {
assertPeekSuppressed()
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 3b979a7c1386..71e7dc522e20 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
@@ -42,6 +42,7 @@ import android.app.PendingIntent
import android.app.PendingIntent.FLAG_MUTABLE
import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
import android.content.pm.UserInfo
import android.graphics.drawable.Icon
import android.hardware.display.FakeAmbientDisplayConfiguration
@@ -129,6 +130,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
protected val userTracker = FakeUserTracker()
protected val avalancheProvider: AvalancheProvider = mock()
lateinit var systemSettings: SystemSettings
+ protected val packageManager: PackageManager = mock()
protected abstract val provider: VisualInterruptionDecisionProvider
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
index 60aaa646fced..61c008b55ad0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
@@ -15,11 +15,11 @@
*/
package com.android.systemui.statusbar.notification.interruption
+import android.content.pm.PackageManager
import android.hardware.display.AmbientDisplayConfiguration
import android.os.Handler
import android.os.PowerManager
import com.android.internal.logging.UiEventLogger
-import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.settings.UserTracker
@@ -53,7 +53,8 @@ object VisualInterruptionDecisionProviderTestUtil {
uiEventLogger: UiEventLogger,
userTracker: UserTracker,
avalancheProvider: AvalancheProvider,
- systemSettings: SystemSettings
+ systemSettings: SystemSettings,
+ packageManager: PackageManager,
): VisualInterruptionDecisionProvider {
return if (VisualInterruptionRefactor.isEnabled) {
VisualInterruptionDecisionProviderImpl(
@@ -73,7 +74,8 @@ object VisualInterruptionDecisionProviderTestUtil {
uiEventLogger,
userTracker,
avalancheProvider,
- systemSettings
+ systemSettings,
+ packageManager
)
} else {
NotificationInterruptStateProviderWrapper(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java
index 2662c80dce1d..59741718476f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/ExpansionStateLoggerTest.java
@@ -22,9 +22,9 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.os.RemoteException;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
@@ -44,7 +44,7 @@ import org.mockito.MockitoAnnotations;
import java.util.Collections;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class ExpansionStateLoggerTest extends SysuiTestCase {
private static final String NOTIFICATION_KEY = "notin_key";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index 111309112f61..a8929a63a812 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -35,9 +35,9 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.platform.test.annotations.DisableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.InstanceId;
@@ -87,7 +87,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
@DisableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
public class NotificationLoggerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
index 4b0b4b89fad4..3ea7732bdf15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
@@ -21,8 +21,8 @@ import android.app.StatsManager
import android.graphics.Bitmap
import android.graphics.drawable.Icon
import android.stats.sysui.NotificationEnums
-import android.testing.AndroidTestingRunner
import android.util.StatsEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.assertLogsWtf
@@ -46,7 +46,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotificationMemoryLoggerTest : SysuiTestCase() {
@Rule @JvmField val expect = Expect.create()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt
index 072a497f1a65..f10a52a73586 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMeterTest.kt
@@ -24,8 +24,8 @@ import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Icon
import android.stats.sysui.NotificationEnums
-import android.testing.AndroidTestingRunner
import android.widget.RemoteViews
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.NotificationUtils
@@ -36,7 +36,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotificationMemoryMeterTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt
index 4bb28ae46211..d7dde96baf32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalkerTest.kt
@@ -3,9 +3,9 @@ package com.android.systemui.statusbar.notification.logging
import android.app.Notification
import android.graphics.Bitmap
import android.graphics.drawable.Icon
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.widget.RemoteViews
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder
@@ -17,7 +17,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class NotificationMemoryViewWalkerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
index 9b9cb8213c91..9f98fd4c8508 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
@@ -17,9 +17,9 @@ package com.android.systemui.statusbar.notification.row
import android.annotation.ColorInt
import android.graphics.Color
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.Utils
import com.android.systemui.res.R
@@ -34,7 +34,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class ActivatableNotificationViewTest : SysuiTestCase() {
private val mContentView: View = mock()
@@ -98,4 +98,4 @@ class ActivatableNotificationViewTest : SysuiTestCase() {
assertThat(mView.topRoundness).isEqualTo(1f)
assertThat(mView.roundableState.hashCode()).isEqualTo(roundableState.hashCode())
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
index 0eae5fc209b4..fda5cd286074 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
@@ -20,8 +20,8 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.net.Uri
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.NotificationDrawableConsumer
import com.android.systemui.SysuiTestCase
@@ -50,7 +50,7 @@ private const val MAX_IMAGE_SIZE = 512 // size of the test drawables in pixels
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWithLooper
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class BigPictureIconManagerTest : SysuiTestCase() {
private val testDispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
index 7dcbd8084594..c5b19ab5862c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
@@ -25,8 +25,8 @@ import android.content.pm.ParceledListSlice
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
@@ -47,7 +47,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ChannelEditorDialogControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index 210b1a7f22f4..e738b616d227 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -21,8 +21,8 @@ import android.app.Notification
import android.net.Uri
import android.os.UserHandle
import android.os.UserHandle.USER_ALL
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.statusbar.IStatusBarService
@@ -71,7 +71,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ExpandableNotificationRowControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java
index 9d2f32d77028..1c5f37cc60c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragControllerTest.java
@@ -31,10 +31,10 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -48,7 +48,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class ExpandableNotificationRowDragControllerTest extends SysuiTestCase {
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 aa79c23bdf74..7304bd62293d 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
@@ -46,13 +46,13 @@ import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.ImageView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -87,7 +87,7 @@ import java.util.List;
import java.util.function.Consumer;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class ExpandableNotificationRowTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
index ffb8646942b5..d04d6fc5f593 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
@@ -45,13 +45,13 @@ import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
@@ -72,7 +72,7 @@ import org.mockito.MockitoAnnotations;
import java.util.Locale;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@UiThreadTest
public class FeedbackInfoTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt
index 5e50af39203f..c325791b1f05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/HeadsUpStyleProviderImplTest.kt
@@ -20,7 +20,7 @@ import android.app.Flags.FLAG_COMPACT_HEADS_UP_NOTIFICATION
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepository
@@ -31,7 +31,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class HeadsUpStyleProviderImplTest : SysuiTestCase() {
@Rule @JvmField val setFlagsRule = SetFlagsRule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
index 25172deb67a7..18fd42da78ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
@@ -22,11 +22,11 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.annotation.NonNull;
import androidx.core.os.CancellationSignal;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -48,7 +48,7 @@ import java.util.ArrayList;
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class NotifBindPipelineTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
index e38adeb0fcd9..29252b27f6d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification.row
-import android.testing.AndroidTestingRunner
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
@@ -33,7 +33,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class NotifInflationErrorManagerTest : SysuiTestCase() {
private lateinit var manager: NotifInflationErrorManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java
index 20cc01accbc3..8b1c95babe38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifRemoteViewCacheImplTest.java
@@ -26,9 +26,9 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.widget.RemoteViews;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -45,7 +45,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class NotifRemoteViewCacheImplTest extends SysuiTestCase {
private NotifRemoteViewCacheImpl mNotifRemoteViewCache;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 03a84036b4b5..a355cd16ee15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -40,7 +40,6 @@ import android.os.AsyncTask;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.TypedValue;
@@ -49,6 +48,7 @@ import android.view.ViewGroup;
import android.widget.RemoteViews;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.filters.Suppress;
@@ -79,7 +79,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
@Suppress
public class NotificationContentInflaterTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
index 7332bc34b030..2bb610ac4449 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
@@ -20,7 +20,6 @@ import android.annotation.DimenRes
import android.content.res.Resources
import android.os.UserHandle
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.NotificationHeaderView
@@ -29,6 +28,7 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.internal.widget.NotificationActionListLayout
@@ -60,7 +60,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class NotificationContentViewTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 97cb11e2f107..be89ab8c5cf8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -65,13 +65,13 @@ import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -103,7 +103,7 @@ import java.util.Optional;
import java.util.concurrent.CountDownLatch;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class NotificationConversationInfoTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 907649b90956..625963f5ec7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -57,12 +57,12 @@ import android.os.Handler;
import android.os.UserManager;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArraySet;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -115,7 +115,7 @@ import java.util.Optional;
* Tests for {@link NotificationGutsManager}.
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class NotificationGutsManagerTest extends SysuiTestCase {
private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 1b85dfa5a087..0b5f8d5e948c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -31,11 +31,11 @@ import android.os.fakeExecutorHandler
import android.os.userManager
import android.provider.Settings
import android.service.notification.NotificationListenerService.Ranking
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.util.ArraySet
import android.view.View
import android.view.accessibility.accessibilityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.internal.logging.MetricsLogger
@@ -91,7 +91,7 @@ import org.mockito.invocation.InvocationOnMock
/** Tests for [NotificationGutsManager] with the scene container enabled. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
@EnableSceneContainer
class NotificationGutsManagerWithScenesTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
index 7f9471e5271f..350f90dcbe91 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
@@ -16,11 +16,11 @@
package com.android.systemui.statusbar.notification.row
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.testing.ViewUtils
import android.view.LayoutInflater
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -34,7 +34,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotificationGutsTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 13ced928175e..245a6a0b130c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -55,13 +55,13 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.telecom.TelecomManager;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -85,7 +85,7 @@ import org.mockito.junit.MockitoRule;
import java.util.concurrent.CountDownLatch;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class NotificationInfoTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index e9290289f7f2..027e899e20df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -29,13 +29,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.ViewUtils;
import android.view.View;
import android.view.ViewGroup;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -49,7 +49,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
@SmallTest
public class NotificationMenuRowTest extends LeakCheckedTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt
index 8261c1c4b42e..352b79f50b90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSettingsControllerTest.kt
@@ -22,8 +22,8 @@ import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.provider.Settings.Secure
-import android.testing.AndroidTestingRunner
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.dump.DumpManager
@@ -54,7 +54,7 @@ import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class NotificationSettingsControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
index 4a91cd239d87..22f1e4604bbd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
@@ -23,11 +23,11 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableResources;
import android.testing.UiThreadTest;
import android.util.KeyValueListParser;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -41,7 +41,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@UiThreadTest
public class NotificationSnoozeTest extends SysuiTestCase {
private static final int RES_DEFAULT = 2;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
index 51665d987888..57b0f3f8d8c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
@@ -41,7 +41,6 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.SpannableString;
import android.view.LayoutInflater;
@@ -49,6 +48,7 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -69,7 +69,7 @@ import org.mockito.junit.MockitoRule;
import java.util.concurrent.CountDownLatch;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class PartialConversationInfoTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java
index 1534c84fd99a..841cb4a3669b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java
@@ -34,10 +34,10 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -52,7 +52,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class RowContentBindStageTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
index 1c959af6ec3f..53a11989cca0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
@@ -18,8 +18,8 @@ package com.android.systemui.statusbar.notification.row
import android.app.Notification
import android.app.Person
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
@@ -34,7 +34,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class SingleLineConversationViewBinderTest : SysuiTestCase() {
private lateinit var notificationBuilder: Notification.Builder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
index f0fc349777b2..ee819c4df0ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
@@ -17,8 +17,8 @@ package com.android.systemui.statusbar.notification.row
import android.app.Notification
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
@@ -33,7 +33,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class SingleLineViewBinderTest : SysuiTestCase() {
private lateinit var notificationBuilder: Notification.Builder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt
index b67153a842ac..e025d3d36ab1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflaterTest.kt
@@ -27,9 +27,9 @@ import android.graphics.PorterDuffXfermode
import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.core.graphics.drawable.toBitmap
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
@@ -48,7 +48,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
class SingleLineViewInflaterTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/TextPrecomputerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/TextPrecomputerTest.kt
index d46763df8a75..f8533a532d32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/TextPrecomputerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/TextPrecomputerTest.kt
@@ -16,11 +16,11 @@
package com.android.systemui.statusbar.notification.row
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.text.PrecomputedText
import android.text.TextPaint
import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -29,7 +29,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class TextPrecomputerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
index c9602307216d..0dc871a523ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
@@ -18,7 +18,7 @@
package com.android.systemui.statusbar.notification.row.ui.viewmodel
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.accessibility.data.repository.FakeAccessibilityRepository
@@ -31,7 +31,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class ActivatableNotificationViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
index a15b4cd37184..ec280a1d6d01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
@@ -24,10 +24,10 @@ import android.app.Notification;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
-import android.testing.AndroidTestingRunner;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -40,7 +40,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class NotificationBigPictureTemplateViewWrapperTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt
index fe2971c46c32..9d990b1d7edf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapperTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar.notification.row.wrapper
import android.graphics.drawable.AnimatedImageDrawable
-import android.testing.AndroidTestingRunner
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.internal.widget.CachingIconView
@@ -38,7 +38,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotificationConversationTemplateViewWrapperTest : SysuiTestCase() {
private lateinit var mRow: ExpandableNotificationRow
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
index 2d72c7e0b714..f9a9704334a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
@@ -16,10 +16,10 @@
package com.android.systemui.statusbar.notification.row.wrapper;
-import android.testing.AndroidTestingRunner;
import android.view.View;
import android.widget.RemoteViews;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -33,7 +33,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class NotificationCustomViewWrapperTest extends SysuiTestCase {
private ExpandableNotificationRow mRow;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt
index f26c18b1d197..fc829d53a6b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapperTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar.notification.row.wrapper
import android.graphics.drawable.AnimatedImageDrawable
-import android.testing.AndroidTestingRunner
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.MessagingGroup
import com.android.internal.widget.MessagingImageMessage
@@ -36,7 +36,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotificationMessagingTemplateViewWrapperTest : SysuiTestCase() {
private lateinit var mRow: ExpandableNotificationRow
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt
index 54eed26adaf3..1ce3bada4609 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.notification.row.wrapper
import android.app.PendingIntent
import android.app.PendingIntent.CancelListener
import android.content.Intent
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.testing.ViewUtils
@@ -27,6 +26,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
@@ -46,7 +46,7 @@ import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotificationTemplateViewWrapperTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
index fad85f53a091..d17c8dbcf38d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
@@ -20,11 +20,11 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.testing.AndroidTestingRunner;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class NotificationViewWrapperTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
index 59d98c233f99..4c6e25a530a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
@@ -19,7 +19,7 @@
package com.android.systemui.statusbar.notification.shelf.domain.interactor
import android.os.PowerManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -41,7 +41,7 @@ import org.junit.runner.RunWith
import org.mockito.Mockito.isNull
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class NotificationShelfInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
index 917569ca787b..e2fb3ba11a02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.statusbar.notification.shelf.ui.viewmodel
import android.os.PowerManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysUITestComponent
import com.android.systemui.SysUITestModule
@@ -44,7 +44,7 @@ import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class NotificationShelfViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
index fb1594898f24..2349c252369c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.notification.stack
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
@@ -33,7 +33,7 @@ import org.junit.runner.RunWith
private const val MAX_PULSE_HEIGHT = 100000f
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class AmbientStateTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
index f4e236e5bbf9..3a77d822eb7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
@@ -1,8 +1,8 @@
package com.android.systemui.statusbar.notification.stack
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
@@ -15,7 +15,7 @@ import org.junit.runner.RunWith
* Tests for {@link MediaContainView}.
*/
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class MediaContainerViewTest : SysuiTestCase() {
@@ -35,4 +35,4 @@ class MediaContainerViewTest : SysuiTestCase() {
mediaContainerView.updateClipping()
assertTrue(mediaContainerView.clipHeight == 10)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index 3b16f1416935..14bbd38ece2c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -21,13 +21,13 @@ import static org.junit.Assert.assertNull;
import android.app.Notification;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.NotificationHeaderView;
import android.view.View;
import android.widget.RemoteViews;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -45,7 +45,7 @@ import org.junit.runner.RunWith;
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
//@DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME)
public class NotificationChildrenContainerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 1eed4207541c..48e8f88a15c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -2,10 +2,10 @@ package com.android.systemui.statusbar.notification.stack
import android.platform.test.annotations.DisableFlags
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.LayoutInflater
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
import com.android.systemui.SysuiTestCase
@@ -35,7 +35,7 @@ import org.mockito.Mockito.`when` as whenever
/** Tests for {@link NotificationShelf}. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
open class NotificationShelfTest : SysuiTestCase() {
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 f262df1d875a..ce2491bb098e 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
@@ -42,12 +42,12 @@ import static org.mockito.Mockito.when;
import android.metrics.LogMaker;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -126,7 +126,7 @@ import javax.inject.Provider;
*/
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
protected KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
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 0c0a2a59d9bc..f461e2f67d20 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
@@ -54,7 +54,6 @@ import android.graphics.Rect;
import android.os.SystemClock;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.util.MathUtils;
@@ -65,6 +64,7 @@ import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.BouncerPanelExpansionCalculator;
@@ -114,7 +114,7 @@ import java.util.function.Consumer;
* Tests for {@link NotificationStackScrollLayout}.
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class NotificationStackScrollLayoutTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index 6fec9ad7bd66..dae5542123ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -18,8 +18,8 @@ package com.android.systemui.statusbar.notification.stack
import android.annotation.DimenRes
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
import android.view.View.VISIBLE
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -44,7 +44,7 @@ import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class NotificationStackSizeCalculatorTest : SysuiTestCase() {
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 85a2bdd21073..2d119174efff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -37,12 +37,12 @@ import android.animation.Animator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.os.Handler;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -70,7 +70,7 @@ import java.util.stream.Collectors;
* Tests for {@link NotificationSwipeHelper}.
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper()
public class NotificationSwipeHelperTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
index e30947ce84bd..660eb308fdf3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
@@ -1,8 +1,8 @@
package com.android.systemui.statusbar.notification.stack
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
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.flags.FakeFeatureFlags
@@ -15,7 +15,7 @@ import org.junit.runner.RunWith
/** Tests for {@link NotificationTargetsHelper}. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotificationTargetsHelperTest : SysuiTestCase() {
private val featureFlags = FakeFeatureFlags()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
index 926c35f32967..798465e7b165 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar.notification.stack
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
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.animation.AnimatorTestRule
@@ -48,7 +48,7 @@ private const val FULL_SHADE_APPEAR_TRANSLATION = 300
private const val HEADS_UP_ABOVE_SCREEN = 80
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class StackStateAnimatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
index cd6bb5f4966a..e493420b64a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ViewStateTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.notification.stack
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.assertDoesNotLogWtf
@@ -27,7 +27,7 @@ import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class ViewStateTest : SysuiTestCase() {
private val viewState = ViewState()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
index e2ac2038be32..e46906fb5192 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
@@ -17,10 +17,10 @@ package com.android.systemui.statusbar.notification.stack.domain.interactor
import android.content.res.Configuration
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.view.Surface
import android.view.Surface.ROTATION_0
import android.view.Surface.ROTATION_90
+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.ConfigurationRepositoryImpl
@@ -52,7 +52,7 @@ import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
open class HideNotificationsInteractorTest : SysuiTestCase() {
private val testScope = TestScope()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 84cd518cf85a..f0bc655a554d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -45,10 +45,10 @@ import android.hardware.display.ColorDisplayManager;
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -89,7 +89,7 @@ import java.util.List;
import javax.inject.Named;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
@SmallTest
public class AutoTileManagerTest extends SysuiTestCase {
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 dc7525c8e256..285949a41fcd 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
@@ -37,11 +37,11 @@ import android.hardware.biometrics.BiometricSourceType;
import android.os.Handler;
import android.os.PowerManager;
import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.TestableResources;
import android.view.ViewRootImpl;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -77,7 +77,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class BiometricsUnlockControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index fe6a88d00374..5675915506a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -30,9 +30,9 @@ import android.content.ComponentName;
import android.os.PowerManager;
import android.os.UserHandle;
import android.os.Vibrator;
-import android.testing.AndroidTestingRunner;
import android.view.HapticFeedbackConstants;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -71,7 +71,7 @@ import org.mockito.stubbing.Answer;
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
@Mock private CentralSurfaces mCentralSurfaces;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 4488799cfd7a..cde241bbe918 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -57,6 +57,7 @@ import android.app.WallpaperManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.devicestate.DeviceState;
@@ -75,7 +76,6 @@ import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.service.dreams.IDreamManager;
import android.support.test.metricshelper.MetricsAsserts;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.DisplayMetrics;
@@ -85,6 +85,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.WindowMetrics;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.compose.animation.scene.ObservableTransitionState;
@@ -223,7 +224,7 @@ import java.util.Optional;
import javax.inject.Provider;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
@EnableFlags(FLAG_LIGHT_REVEAL_MIGRATION)
public class CentralSurfacesImplTest extends SysuiTestCase {
@@ -339,6 +340,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
@Mock private KeyboardShortcuts mKeyboardShortcuts;
@Mock private KeyboardShortcutListSearch mKeyboardShortcutListSearch;
+ @Mock private PackageManager mPackageManager;
private ShadeController mShadeController;
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -392,7 +394,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mock(UiEventLogger.class),
mUserTracker,
mAvalancheProvider,
- mSystemSettings);
+ mSystemSettings,
+ mPackageManager);
mVisualInterruptionDecisionProvider.start();
mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
index 56d23978a5c7..942ea65ec49e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
@@ -21,7 +21,7 @@ import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import android.content.res.Configuration.UI_MODE_TYPE_CAR
import android.os.LocaleList
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
@@ -36,7 +36,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import java.util.Locale
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class ConfigurationControllerImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
index 34c43ef52a00..3b3ec263145a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
@@ -20,9 +20,9 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -36,7 +36,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
@SmallTest
public class DozeScrimControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
index 5d42d5167c27..a3e2d1949a29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.phone
import android.hardware.devicestate.DeviceState
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
@@ -30,7 +30,7 @@ import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class FoldStateListenerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 3e9006e5268c..0d06b6431e1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -26,12 +26,12 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.platform.test.annotations.DisableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -62,7 +62,7 @@ import org.junit.runner.RunWith;
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index e8346933f192..cf87afbbff34 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -28,8 +28,8 @@ import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -50,7 +50,7 @@ import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
private static final int SCREEN_HEIGHT = 2000;
private static final int EMPTY_HEIGHT = 0;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
index b0aa2d3934cc..d880becaa4bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
@@ -20,8 +20,8 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class KeyguardDismissUtilTest extends SysuiTestCase {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
index 5cea931e2070..109cd948b5b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
@@ -21,10 +21,10 @@ import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class KeyguardIndicationTextViewTest extends SysuiTestCase {
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 5b2526e22679..71f09a5d3f04 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
@@ -42,11 +42,11 @@ import android.os.UserManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.CarrierTextController;
@@ -99,7 +99,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
index c44f979fa971..0932a0c9307c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
@@ -18,11 +18,11 @@ package com.android.systemui.statusbar.phone;
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -33,7 +33,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class KeyguardStatusBarViewTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java
index f91064b49e95..782ca91bc8fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyLightsOutNotifControllerTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.platform.test.annotations.DisableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.Display;
import android.view.View;
@@ -35,6 +34,7 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import androidx.lifecycle.Observer;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -54,7 +54,7 @@ import org.mockito.MockitoAnnotations;
import java.util.Objects;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
@DisableFlags(NotificationsLiveDataStoreRefactor.FLAG_NAME)
public class LegacyLightsOutNotifControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java
index 9d53b9c66b33..fea0e72fe577 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImplTest.java
@@ -21,9 +21,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.platform.test.annotations.DisableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -49,7 +49,7 @@ import org.mockito.MockitoAnnotations;
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
@DisableFlags(NotificationIconContainerRefactor.FLAG_NAME)
public class LegacyNotificationIconAreaControllerImplTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
index e7b287c5bdc8..518b327036cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
@@ -18,9 +18,9 @@ package com.android.systemui.statusbar.phone
import android.graphics.Color
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.view.WindowInsetsController
import android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.statusbar.LetterboxDetails
import com.android.internal.view.AppearanceRegion
@@ -36,7 +36,7 @@ import org.mockito.Mock
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class LetterboxAppearanceCalculatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
index 1cc0bd3cb36c..788c2cb2a485 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
@@ -21,8 +21,8 @@ import android.app.WallpaperManager.OnColorsChangedListener
import android.graphics.Color
import android.os.Handler
import android.os.Looper
-import android.testing.AndroidTestingRunner
import android.view.IWindowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
@@ -40,7 +40,7 @@ import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class LetterboxBackgroundProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index 7271a5efc377..a27073c77eb4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
@@ -35,10 +35,10 @@ import static org.mockito.Mockito.when;
import android.graphics.Color;
import android.graphics.Rect;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.annotation.ColorInt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
@@ -67,7 +67,7 @@ import java.util.Arrays;
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class LightBarControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java
index f71114d92aa3..43c19b833646 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java
@@ -28,9 +28,9 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.policy.GestureNavigationSettingsObserver;
@@ -48,7 +48,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class LightBarTransitionsControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
index 9f4e1dd8cc4d..9d97e5a5686e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.phone
import android.service.notification.StatusBarNotification
-import android.testing.AndroidTestingRunner
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.statusbar.StatusBarIconView
@@ -34,7 +34,7 @@ import org.mockito.Mockito.`when` as whenever
/** Tests for {@link NotificationIconContainer}. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class NotificationIconContainerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
index ccd1a8c7a9b2..9522e1f65a4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java
@@ -22,11 +22,11 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -42,7 +42,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class NotificationTapHelperTest extends SysuiTestCase {
private NotificationTapHelper mNotificationTapHelper;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
index 8d2c1588fb62..f2f336c45d7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
@@ -22,9 +22,9 @@ import android.app.admin.DevicePolicyResourcesManager
import android.content.SharedPreferences
import android.os.UserManager
import android.telecom.TelecomManager
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
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.broadcast.BroadcastDispatcher
@@ -79,7 +79,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
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 1000329cb276..416a869bf2f0 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,12 +49,12 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.ViewUtils;
import android.util.MathUtils;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
@@ -107,7 +107,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class ScrimControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt
index 61da701ce971..b9cfe21dcad3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarBoundsProviderTest.kt
@@ -17,10 +17,10 @@
package com.android.systemui.statusbar.phone
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.View
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider.BoundsChangeListener
@@ -37,7 +37,7 @@ import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
class StatusBarBoundsProviderTest : SysuiTestCase() {
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 6b3c0053e738..3ca4c594cede 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
@@ -41,7 +41,6 @@ import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.service.trust.TrustAgentService;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import android.view.View;
@@ -55,6 +54,7 @@ import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.WindowOnBackInvokedDispatcher;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.util.LatencyTracker;
@@ -119,7 +119,7 @@ import org.mockito.MockitoAnnotations;
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 269510e0b4b2..9fa392f3a337 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -51,9 +51,9 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.jank.InteractionJankMonitor;
@@ -119,7 +119,7 @@ import java.util.List;
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index a8c5fc357c7c..95472cad4b90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -34,10 +34,10 @@ import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.InitController;
@@ -85,7 +85,7 @@ import java.util.List;
import java.util.Set;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper()
public class StatusBarNotificationPresenterTest extends SysuiTestCase {
private StatusBarNotificationPresenter mStatusBarNotificationPresenter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index 929099a8f1f7..35888a5fa734 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -24,10 +24,10 @@ import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import android.content.Intent;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -52,7 +52,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@@ -103,4 +103,4 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
verify(mStatusBarKeyguardViewManager).showBouncer(true);
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
index 1455693fc54b..11dd587a04ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
@@ -21,7 +21,6 @@ import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.PaintDrawable
import android.os.SystemClock
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.testing.ViewUtils
@@ -30,6 +29,7 @@ import android.view.View
import android.view.ViewGroupOverlay
import android.widget.LinearLayout
import androidx.annotation.ColorInt
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -45,7 +45,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
class StatusOverlayHoverListenerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
index dedd0afb6127..b560c591af1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
@@ -15,9 +15,9 @@ package com.android.systemui.statusbar.phone
import android.app.Dialog
import android.content.res.Configuration
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.WindowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
@@ -39,7 +39,7 @@ import org.mockito.Mockito.verify
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
class SystemUIBottomSheetDialogTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index c8ff20b31aae..624c070e95e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -18,9 +18,9 @@ package com.android.systemui.statusbar.phone
import android.os.Handler
import android.os.PowerManager
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.SysuiTestCase
@@ -51,7 +51,7 @@ import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 598b12ccdc38..eb2538ec032e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -20,6 +20,7 @@ import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
import android.telephony.TelephonyManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.demomode.DemoMode
@@ -60,7 +61,6 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -73,7 +73,7 @@ import org.mockito.MockitoAnnotations
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class MobileRepositorySwitcherTest : SysuiTestCase() {
private lateinit var underTest: MobileRepositorySwitcher
private lateinit var realRepo: MobileConnectionsRepositoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
index 265440154d77..237aabccfbd9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
import android.telephony.TelephonyManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -44,7 +44,7 @@ import org.mockito.MockitoAnnotations
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
private lateinit var underTest: CarrierMergedConnectionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 36df61d287a1..96e599f8f4d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
+import android.annotation.SuppressLint
import android.content.Intent
import android.net.ConnectivityManager
import android.net.Network
@@ -27,8 +28,10 @@ import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.vcn.VcnTransportInfo
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
+import android.os.Bundle
import android.os.ParcelUuid
import android.telephony.CarrierConfigManager
+import android.telephony.ServiceState
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
@@ -53,6 +56,7 @@ import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
@@ -595,6 +599,51 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
}
+ @SuppressLint("UnspecifiedRegisterReceiverFlag")
+ @Test
+ fun testDeviceServiceStateFromBroadcast_eagerlyWatchesBroadcast() =
+ testScope.runTest {
+ // Value starts out empty (null)
+ assertThat(underTest.deviceServiceState.value).isNull()
+
+ // WHEN an appropriate intent gets sent out
+ val intent = serviceStateIntent(subId = -1, emergencyOnly = false)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ intent,
+ )
+ runCurrent()
+
+ // THEN the repo's state is updated
+ val expected = ServiceStateModel(isEmergencyOnly = false)
+ assertThat(underTest.deviceServiceState.value).isEqualTo(expected)
+ }
+
+ @Test
+ fun testDeviceServiceStateFromBroadcast_followsSubIdNegativeOne() =
+ testScope.runTest {
+ // device based state tracks -1
+ val intent = serviceStateIntent(subId = -1, emergencyOnly = false)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ intent,
+ )
+ runCurrent()
+
+ val deviceBasedState = ServiceStateModel(isEmergencyOnly = false)
+ assertThat(underTest.deviceServiceState.value).isEqualTo(deviceBasedState)
+
+ // ... and ignores any other subId
+ val intent2 = serviceStateIntent(subId = 1, emergencyOnly = true)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ intent2,
+ )
+ runCurrent()
+
+ assertThat(underTest.deviceServiceState.value).isEqualTo(deviceBasedState)
+ }
+
@Test
@Ignore("b/333912012")
fun testConnectionCache_clearsInvalidSubscriptions() =
@@ -1491,5 +1540,24 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
whenever(it.transportInfo).thenReturn(WIFI_INFO_ACTIVE)
whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(true)
}
+
+ /**
+ * To properly mimic telephony manager, create a service state, and then turn it into an
+ * intent
+ */
+ private fun serviceStateIntent(
+ subId: Int,
+ emergencyOnly: Boolean = false,
+ ): Intent {
+ val serviceState = ServiceState().apply { isEmergencyOnly = emergencyOnly }
+
+ val bundle = Bundle()
+ serviceState.fillInNotifierBundle(bundle)
+
+ return Intent(Intent.ACTION_SERVICE_STATE).apply {
+ putExtras(bundle)
+ putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId)
+ }
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 0f9cbfa66b5b..58d9ee3935fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -28,6 +28,7 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlagsClassic
import com.android.systemui.flags.Flags
import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
@@ -888,6 +889,22 @@ class MobileIconsInteractorTest : SysuiTestCase() {
assertThat(interactor1).isSameInstanceAs(interactor2)
}
+ @Test
+ fun deviceBasedEmergencyMode_emergencyCallsOnly_followsDeviceServiceStateFromRepo() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isDeviceInEmergencyCallsOnlyMode)
+
+ connectionsRepository.deviceServiceState.value =
+ ServiceStateModel(isEmergencyOnly = true)
+
+ assertThat(latest).isTrue()
+
+ connectionsRepository.deviceServiceState.value =
+ ServiceStateModel(isEmergencyOnly = false)
+
+ assertThat(latest).isFalse()
+ }
+
/**
* Convenience method for creating a pair of subscriptions to test the filteredSubscriptions
* flow.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index 405e3ed807d5..d303976612c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -22,6 +22,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.telephony.flags.Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.log.core.FakeLogBuffer
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.satellite.data.prod.FakeDeviceBasedSatelliteRepository
@@ -71,6 +72,7 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
+ FakeLogBuffer.Factory.create(),
)
}
@@ -114,6 +116,7 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
+ FakeLogBuffer.Factory.create(),
)
val latest by collectLastValue(underTest.isSatelliteAllowed)
@@ -162,6 +165,7 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
+ FakeLogBuffer.Factory.create(),
)
val latest by collectLastValue(underTest.connectionState)
@@ -218,6 +222,7 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
+ FakeLogBuffer.Factory.create(),
)
val latest by collectLastValue(underTest.signalStrength)
@@ -238,25 +243,97 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
- fun areAllConnectionsOutOfService_noConnections_yes() =
+ fun areAllConnectionsOutOfService_noConnections_noDeviceEmergencyCalls_yes() =
testScope.runTest {
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
// GIVEN, 0 connections
+ // GIVEN, device is not in emergency calls only mode
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = false
+
// THEN the value is propagated to this interactor
assertThat(latest).isTrue()
}
@Test
@EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
- fun areAllConnectionsOutOfService_twoConnectionsOos_nonNtn_yes() =
+ fun areAllConnectionsOutOfService_noConnections_deviceEmergencyCalls_yes() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
+
+ // GIVEN, 0 connections
+
+ // GIVEN, device is in emergency calls only mode
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = true
+
+ // THEN the value is propagated to this interactor
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun areAllConnectionsOutOfService_oneConnectionInService_thenLost_noDeviceEmergencyCalls_yes() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
+
+ // GIVEN, 1 connections
+ val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ // GIVEN, no device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = false
+
+ // WHEN connection is in service
+ i1.isInService.value = true
+ i1.isEmergencyOnly.value = false
+ i1.isNonTerrestrial.value = false
+
+ // THEN we are considered NOT to be OOS
+ assertThat(latest).isFalse()
+
+ // WHEN the connection disappears
+ iconsInteractor.icons.value = listOf()
+
+ // THEN we are back to OOS
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun areAllConnectionsOutOfService_oneConnectionInService_thenLost_deviceEmergencyCalls_no() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
+
+ // GIVEN, 1 connections
+ val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ // GIVEN, device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = true
+
+ // WHEN one connection is in service
+ i1.isInService.value = true
+ i1.isEmergencyOnly.value = false
+ i1.isNonTerrestrial.value = false
+
+ // THEN we are considered NOT to be OOS
+ assertThat(latest).isFalse()
+
+ // WHEN the connection disappears
+ iconsInteractor.icons.value = listOf()
+
+ // THEN we are still NOT in OOS, due to device-based emergency calls
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun areAllConnectionsOutOfService_twoConnectionsOos_nonNtn_noDeviceEmergencyCalls_yes() =
testScope.runTest {
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
// GIVEN, 2 connections
val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+ // GIVEN, no device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = false
// WHEN all of the connections are OOS and none are NTN
i1.isInService.value = false
@@ -272,13 +349,39 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
- fun areAllConnectionsOutOfService_twoConnectionsOos_oneNtn_no() =
+ fun areAllConnectionsOutOfService_twoConnectionsOos_nonNtn_deviceEmergencyCalls_no() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
+
+ // GIVEN, 2 connections
+ val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+ // GIVEN, device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = true
+
+ // WHEN all of the connections are OOS and none are NTN
+ i1.isInService.value = false
+ i1.isEmergencyOnly.value = false
+ i1.isNonTerrestrial.value = false
+ i2.isInService.value = false
+ i2.isEmergencyOnly.value = false
+ i2.isNonTerrestrial.value = false
+
+ // THEN we are not considered OOS due to device based emergency calling
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun areAllConnectionsOutOfService_twoConnectionsOos_noDeviceEmergencyCalls_oneNtn_no() =
testScope.runTest {
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
// GIVEN, 2 connections
val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+ // GIVEN, no device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = false
// WHEN all of the connections are OOS and one is NTN
i1.isInService.value = false
@@ -296,12 +399,14 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
- fun areAllConnectionsOutOfService_oneConnectionOos_nonNtn_yes() =
+ fun areAllConnectionsOutOfService_oneConnectionOos_noDeviceEmergencyCalls_nonNtn_yes() =
testScope.runTest {
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
// GIVEN, 1 connection
val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ // GIVEN, no device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = false
// WHEN all of the connections are OOS
i1.isInService.value = false
@@ -314,7 +419,27 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
@Test
@EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
- fun areAllConnectionsOutOfService_oneConnectionOos_ntn_yes() =
+ fun areAllConnectionsOutOfService_oneConnectionOos_nonNtn_no() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
+
+ // GIVEN, 1 connection
+ val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ // GIVEN, device-based emergency calls
+ iconsInteractor.isDeviceInEmergencyCallsOnlyMode.value = true
+
+ // WHEN all of the connections are OOS
+ i1.isInService.value = false
+ i1.isEmergencyOnly.value = false
+ i1.isNonTerrestrial.value = false
+
+ // THEN the value is propagated to this interactor
+ assertThat(latest).isFalse()
+ }
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun areAllConnectionsOutOfService_oneConnectionOos_ntn_no() =
testScope.runTest {
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
@@ -416,6 +541,7 @@ class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
+ FakeLogBuffer.Factory.create(),
)
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index ceaae9e02e87..43b95688729c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -75,6 +75,7 @@ class DeviceBasedSatelliteViewModelTest : SysuiTestCase() {
deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
+ FakeLogBuffer.Factory.create(),
)
underTest =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt
index d1c38f6cbea7..0a5e63085b9b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BaseUserSwitcherAdapterTest.kt
@@ -22,6 +22,7 @@ import android.graphics.Bitmap
import android.os.UserHandle
import android.view.View
import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.qs.user.UserSwitchDialogController
@@ -33,14 +34,13 @@ import java.lang.ref.WeakReference
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BaseUserSwitcherAdapterTest : SysuiTestCase() {
@Mock private lateinit var controller: UserSwitcherController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
index fb4ccb52929a..c22c62825d04 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
@@ -20,8 +20,8 @@ import android.content.ComponentName
import android.content.Context
import android.content.pm.ServiceInfo
import android.provider.Settings
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
@@ -60,7 +60,7 @@ import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyObject
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class DeviceControlsControllerImplTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
index 2955162f80c2..f6e07d3d621e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
@@ -29,10 +29,10 @@ import android.hardware.devicestate.DeviceState;
import android.hardware.devicestate.DeviceStateManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableContentResolver;
import android.testing.TestableResources;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -51,7 +51,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class DeviceStateRotationLockSettingControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
index 1c54263cb0ce..80cc6eca8405 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
@@ -20,8 +20,8 @@ import android.content.pm.PackageManager
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.hardware.camera2.impl.CameraMetadataNative
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dump.DumpManager
@@ -46,7 +46,7 @@ import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class FlashlightControllerImplTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
index 0bd6a685708b..9f74915b4d1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
@@ -19,10 +19,10 @@ package com.android.systemui.statusbar.policy
import android.content.Context
import android.content.pm.UserInfo
import android.graphics.Bitmap
-import android.testing.AndroidTestingRunner
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.util.UserIcons
import com.android.systemui.res.R
@@ -44,7 +44,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class KeyguardUserSwitcherAdapterTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
index b03edaf8ebd5..4b14e642063a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
@@ -23,7 +23,7 @@ import android.content.pm.PackageManager
import android.net.Uri
import android.os.Handler
import android.safetycenter.SafetyCenterManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
@@ -44,7 +44,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class SafetyControllerTest : SysuiTestCase() {
private val TEST_PC_PKG = "testPermissionControllerPackageName"
@@ -188,4 +188,4 @@ class SafetyControllerTest : SysuiTestCase() {
assertThat(called).isTrue()
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
index 3e20f689569e..81f095041fbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
@@ -22,7 +22,7 @@ import android.media.projection.MediaProjectionManager
import android.os.Handler
import android.platform.test.annotations.DisableFlags
import android.telephony.TelephonyManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.server.notification.Flags
import com.android.systemui.SysuiTestCase
@@ -38,7 +38,7 @@ import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@DisableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING)
class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase() {
private val logger = SensitiveNotificationProtectionControllerLogger(logcatLogBuffer())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
index dbc2e3471c28..0249ab8fc9eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.statusbar.policy
import android.service.quickaccesswallet.QuickAccessWalletClient
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -35,7 +35,7 @@ import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when`
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class WalletControllerImplTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
index fd368eb07b5b..eaef0073b6fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
@@ -18,8 +18,11 @@ package com.android.systemui.unfold.updates
import android.content.Context
import android.hardware.display.DisplayManager
+import android.os.HandlerThread
import android.os.Looper
+import android.os.Process
import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
import android.view.Display
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -40,6 +43,7 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@SmallTest
+@RunWithLooper
class RotationChangeProviderTest : SysuiTestCase() {
private lateinit var rotationChangeProvider: RotationChangeProvider
@@ -48,7 +52,10 @@ class RotationChangeProviderTest : SysuiTestCase() {
@Mock lateinit var listener: RotationListener
@Mock lateinit var display: Display
@Captor lateinit var displayListener: ArgumentCaptor<DisplayManager.DisplayListener>
- private val fakeHandler = FakeHandler(Looper.getMainLooper())
+ private val bgThread =
+ HandlerThread("UnfoldBgTest", Process.THREAD_PRIORITY_FOREGROUND).apply { start() }
+ private val bgHandler = FakeHandler(bgThread.looper)
+ private val callbackHandler = FakeHandler(Looper.getMainLooper())
private lateinit var spyContext: Context
@@ -57,9 +64,10 @@ class RotationChangeProviderTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
spyContext = spy(context)
whenever(spyContext.display).thenReturn(display)
- rotationChangeProvider = RotationChangeProvider(displayManager, spyContext, fakeHandler)
+ rotationChangeProvider =
+ RotationChangeProvider(displayManager, spyContext, bgHandler, callbackHandler)
rotationChangeProvider.addCallback(listener)
- fakeHandler.dispatchQueuedMessages()
+ bgHandler.dispatchQueuedMessages()
verify(displayManager).registerDisplayListener(displayListener.capture(), any())
}
@@ -76,7 +84,7 @@ class RotationChangeProviderTest : SysuiTestCase() {
verify(listener).onRotationChanged(42)
rotationChangeProvider.removeCallback(listener)
- fakeHandler.dispatchQueuedMessages()
+ bgHandler.dispatchQueuedMessages()
sendRotationUpdate(43)
verify(displayManager).unregisterDisplayListener(any())
@@ -86,6 +94,6 @@ class RotationChangeProviderTest : SysuiTestCase() {
private fun sendRotationUpdate(newRotation: Int) {
whenever(display.rotation).thenReturn(newRotation)
displayListener.allValues.forEach { it.onDisplayChanged(display.displayId) }
- fakeHandler.dispatchQueuedMessages()
+ callbackHandler.dispatchQueuedMessages()
}
}
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 df781108cf79..7b0a55608970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -467,7 +467,8 @@ public class BubblesTest extends SysuiTestCase {
mock(UiEventLogger.class),
mock(UserTracker.class),
mock(AvalancheProvider.class),
- mock(SystemSettings.class)
+ mock(SystemSettings.class),
+ mock(PackageManager.class)
);
interruptionDecisionProvider.start();
@@ -2132,8 +2133,7 @@ public class BubblesTest extends SysuiTestCase {
FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
mBubbleController.registerBubbleStateListener(bubbleStateListener);
- mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(),
- new Rect(500, 1000, 600, 1100));
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), 1000);
assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
@@ -2157,7 +2157,7 @@ public class BubblesTest extends SysuiTestCase {
mBubbleController.updateBubble(mBubbleEntry2);
// Select first bubble
- mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), new Rect());
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), 0);
assertThat(mBubbleData.getSelectedBubbleKey()).isEqualTo(mBubbleEntry.getKey());
assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
@@ -2166,7 +2166,7 @@ public class BubblesTest extends SysuiTestCase {
assertThat(mBubbleController.getLayerView().isExpanded()).isFalse();
// Stop dragging, first bubble should be expanded
- mBubbleController.stopBubbleDrag(BubbleBarLocation.LEFT);
+ mBubbleController.stopBubbleDrag(BubbleBarLocation.LEFT, 0);
assertThat(mBubbleData.getSelectedBubbleKey()).isEqualTo(mBubbleEntry.getKey());
assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
}
@@ -2186,7 +2186,7 @@ public class BubblesTest extends SysuiTestCase {
mBubbleController.updateBubble(mBubbleEntry2);
// Select first bubble
- mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), new Rect());
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), 0);
assertThat(mBubbleData.getSelectedBubbleKey()).isEqualTo(mBubbleEntry.getKey());
assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
@@ -2195,7 +2195,7 @@ public class BubblesTest extends SysuiTestCase {
assertThat(mBubbleController.getLayerView().isExpanded()).isFalse();
// Stop dragging, first bubble should be expanded
- mBubbleController.stopBubbleDrag(BubbleBarLocation.LEFT);
+ mBubbleController.stopBubbleDrag(BubbleBarLocation.LEFT, 0);
assertThat(mBubbleData.getSelectedBubbleKey()).isEqualTo(mBubbleEntry.getKey());
assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
}
@@ -2215,7 +2215,7 @@ public class BubblesTest extends SysuiTestCase {
mBubbleController.updateBubble(mBubbleEntry2);
// Select first bubble
- mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), new Rect());
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), 0);
// Drag first bubble to dismiss
mBubbleController.startBubbleDrag(mBubbleEntry.getKey());
mBubbleController.dragBubbleToDismiss(mBubbleEntry.getKey());
@@ -2239,7 +2239,7 @@ public class BubblesTest extends SysuiTestCase {
mBubbleController.updateBubble(mBubbleEntry2);
// Select first bubble
- mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), new Rect());
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), 0);
// Drag second bubble to dismiss
mBubbleController.startBubbleDrag(mBubbleEntry2.getKey());
mBubbleController.dragBubbleToDismiss(mBubbleEntry2.getKey());
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
index e37bdc15c0ac..280996719e02 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
@@ -17,6 +17,9 @@ class FakePromptRepository : PromptRepository {
private val _userId = MutableStateFlow<Int?>(null)
override val userId = _userId.asStateFlow()
+ private val _requestId = MutableStateFlow<Long?>(null)
+ override val requestId = _requestId.asStateFlow()
+
private var _challenge = MutableStateFlow<Long?>(null)
override val challenge = _challenge.asStateFlow()
@@ -32,6 +35,7 @@ class FakePromptRepository : PromptRepository {
override fun setPrompt(
promptInfo: PromptInfo,
userId: Int,
+ requestId: Long,
gatekeeperChallenge: Long?,
kind: PromptKind,
opPackageName: String,
@@ -39,6 +43,7 @@ class FakePromptRepository : PromptRepository {
setPrompt(
promptInfo,
userId,
+ requestId,
gatekeeperChallenge,
kind,
forceConfirmation = false,
@@ -48,6 +53,7 @@ class FakePromptRepository : PromptRepository {
fun setPrompt(
promptInfo: PromptInfo,
userId: Int,
+ requestId: Long,
gatekeeperChallenge: Long?,
kind: PromptKind,
forceConfirmation: Boolean = false,
@@ -55,15 +61,17 @@ class FakePromptRepository : PromptRepository {
) {
_promptInfo.value = promptInfo
_userId.value = userId
+ _requestId.value = requestId
_challenge.value = gatekeeperChallenge
_promptKind.value = kind
_isConfirmationRequired.value = promptInfo.isConfirmationRequested || forceConfirmation
_opPackageName.value = opPackageName
}
- override fun unsetPrompt() {
+ override fun unsetPrompt(requestId: Long) {
_promptInfo.value = null
_userId.value = null
+ _requestId.value = null
_challenge.value = null
_promptKind.value = PromptKind.None
_opPackageName.value = null
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 b38acc8a46dc..bd9c0be6b0b7 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor
@@ -30,6 +31,7 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by
fromBouncerInteractor = fromPrimaryBouncerTransitionInteractor,
fromAlternateBouncerInteractor = fromAlternateBouncerTransitionInteractor,
notificationLaunchAnimationInteractor = notificationLaunchAnimationInteractor,
- sceneInteractor = sceneInteractor,
+ sceneInteractor = { sceneInteractor },
+ deviceEntryInteractor = { deviceEntryInteractor },
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
index cce038f4ffc1..8229575a128f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
@@ -23,6 +23,7 @@ import com.android.settingslib.SignalIcon
import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
@@ -93,6 +94,8 @@ class FakeMobileConnectionsRepository(
private val _defaultMobileIconGroup = MutableStateFlow(DEFAULT_ICON)
override val defaultMobileIconGroup = _defaultMobileIconGroup
+ override val deviceServiceState = MutableStateFlow<ServiceStateModel?>(null)
+
override val isAnySimSecure = MutableStateFlow(false)
override fun getIsAnySimSecure(): Boolean = isAnySimSecure.value
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index de6c87c2b515..3a4bf8e48d33 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
@@ -81,6 +81,8 @@ class FakeMobileIconsInteractor(
override val isForceHidden = MutableStateFlow(false)
+ override val isDeviceInEmergencyCallsOnlyMode = MutableStateFlow(false)
+
/** Always returns a new fake interactor */
override fun getMobileConnectionInteractorForSubId(subId: Int): FakeMobileIconInteractor {
return FakeMobileIconInteractor(tableLogBuffer).also {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/VolumePanelAncKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/VolumePanelAncKosmos.kt
index f9b7e69eea7d..2b5d1b9757bc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/VolumePanelAncKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/VolumePanelAncKosmos.kt
@@ -20,10 +20,13 @@ import androidx.slice.SliceViewManager
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.util.mockito.mock
+import com.android.systemui.volume.domain.interactor.audioOutputInteractor
import com.android.systemui.volume.panel.component.anc.data.repository.FakeAncSliceRepository
import com.android.systemui.volume.panel.component.anc.domain.interactor.AncSliceInteractor
var Kosmos.sliceViewManager: SliceViewManager by Kosmos.Fixture { mock {} }
val Kosmos.ancSliceRepository by Kosmos.Fixture { FakeAncSliceRepository() }
val Kosmos.ancSliceInteractor by
- Kosmos.Fixture { AncSliceInteractor(ancSliceRepository, testScope.backgroundScope) }
+ Kosmos.Fixture {
+ AncSliceInteractor(audioOutputInteractor, ancSliceRepository, testScope.backgroundScope)
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/data/repository/FakeAncSliceRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/data/repository/FakeAncSliceRepository.kt
index d4a72b437fd8..ebe68505e343 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/data/repository/FakeAncSliceRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/anc/data/repository/FakeAncSliceRepository.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.panel.component.anc.data.repository
+import android.bluetooth.BluetoothDevice
import androidx.slice.Slice
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -24,7 +25,12 @@ class FakeAncSliceRepository : AncSliceRepository {
private val sliceByWidth = mutableMapOf<Int, MutableStateFlow<Slice?>>()
- override fun ancSlice(width: Int, isCollapsed: Boolean, hideLabel: Boolean): Flow<Slice?> {
+ override fun ancSlice(
+ device: BluetoothDevice,
+ width: Int,
+ isCollapsed: Boolean,
+ hideLabel: Boolean
+ ): Flow<Slice?> {
return sliceByWidth.getOrPut(width) { MutableStateFlow(null) }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt
new file mode 100644
index 000000000000..40296099bfe0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.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.volume.panel.component.mediaoutput.domain.interactor
+
+import android.annotation.SuppressLint
+import android.bluetooth.BluetoothDevice
+import android.graphics.drawable.TestStubDrawable
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.media.BluetoothMediaDevice
+import com.android.settingslib.media.MediaDevice
+import com.android.settingslib.media.PhoneMediaDevice
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+
+@SuppressLint("StaticFieldLeak") // These are mocks
+object TestMediaDevicesFactory {
+
+ fun builtInMediaDevice(): MediaDevice = mock {
+ whenever(name).thenReturn("built_in_media")
+ whenever(icon).thenReturn(TestStubDrawable())
+ }
+
+ fun wiredMediaDevice(): MediaDevice =
+ mock<PhoneMediaDevice> {
+ whenever(deviceType)
+ .thenReturn(MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE)
+ whenever(name).thenReturn("wired_media")
+ whenever(icon).thenReturn(TestStubDrawable())
+ }
+
+ fun bluetoothMediaDevice(): MediaDevice {
+ val bluetoothDevice = mock<BluetoothDevice>()
+ val cachedBluetoothDevice: CachedBluetoothDevice = mock {
+ whenever(isHearingAidDevice).thenReturn(true)
+ whenever(address).thenReturn("bt_media_device")
+ whenever(device).thenReturn(bluetoothDevice)
+ }
+ return mock<BluetoothMediaDevice> {
+ whenever(name).thenReturn("bt_media")
+ whenever(icon).thenReturn(TestStubDrawable())
+ whenever(cachedDevice).thenReturn(cachedBluetoothDevice)
+ }
+ }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
index 2bc2db3ba629..fe102448a6cb 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
@@ -53,8 +53,8 @@ class UnfoldRemoteModule {
@UnfoldMain
fun provideMainRotationChangeProvider(
rotationChangeProviderFactory: RotationChangeProvider.Factory,
- @UnfoldMain mainHandler: Handler,
+ @UnfoldMain callbackHandler: Handler,
): RotationChangeProvider {
- return rotationChangeProviderFactory.create(mainHandler)
+ return rotationChangeProviderFactory.create(callbackHandler)
}
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index 31b7ccca49ac..f382070f8fa7 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -87,6 +87,7 @@ interface RemoteUnfoldSharedComponent {
@BindsInstance @UnfoldMain executor: Executor,
@BindsInstance @UnfoldMain handler: Handler,
@BindsInstance @UnfoldSingleThreadBg singleThreadBgExecutor: Executor,
+ @BindsInstance @UnfoldBg bgHandler: Handler,
@BindsInstance displayManager: DisplayManager,
@BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
): RemoteUnfoldSharedComponent
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 1b7e71a42c22..f83ea845809c 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -270,9 +270,9 @@ internal class UnfoldRotationProviderInternalModule {
@UnfoldMain
fun provideRotationChangeProvider(
rotationChangeProviderFactory: RotationChangeProvider.Factory,
- @UnfoldMain mainHandler: Handler,
+ @UnfoldMain callbackHandler: Handler,
): RotationChangeProvider {
- return rotationChangeProviderFactory.create(mainHandler)
+ return rotationChangeProviderFactory.create(callbackHandler)
}
@Provides
@@ -280,8 +280,9 @@ internal class UnfoldRotationProviderInternalModule {
@UnfoldBg
fun provideBgRotationChangeProvider(
rotationChangeProviderFactory: RotationChangeProvider.Factory,
- @UnfoldBg bgHandler: Handler,
+ @UnfoldBg callbackHandler: Handler,
): RotationChangeProvider {
- return rotationChangeProviderFactory.create(bgHandler)
+ // For UnfoldBg RotationChangeProvider we use bgHandler as callbackHandler
+ return rotationChangeProviderFactory.create(callbackHandler)
}
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index 1cbaf3135c4d..8a4f9857603a 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -77,6 +77,7 @@ fun createRemoteUnfoldSharedComponent(
mainExecutor: Executor,
mainHandler: Handler,
singleThreadBgExecutor: Executor,
+ bgHandler: Handler,
tracingTagPrefix: String,
displayManager: DisplayManager,
): RemoteUnfoldSharedComponent =
@@ -87,6 +88,7 @@ fun createRemoteUnfoldSharedComponent(
mainExecutor,
mainHandler,
singleThreadBgExecutor,
+ bgHandler,
displayManager,
tracingTagPrefix,
)
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 77f637bb8ba1..a10097427ae5 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -20,6 +20,7 @@ import android.os.Handler
import android.util.Log
import androidx.annotation.FloatRange
import androidx.annotation.VisibleForTesting
+import androidx.annotation.WorkerThread
import androidx.core.util.Consumer
import com.android.systemui.unfold.compat.INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
import com.android.systemui.unfold.config.UnfoldTransitionConfig
@@ -215,6 +216,7 @@ constructor(
}
private inner class FoldRotationListener : RotationChangeProvider.RotationListener {
+ @WorkerThread
override fun onRotationChanged(newRotation: Int) {
assertInProgressThread()
if (isTransitionInProgress) cancelAnimation()
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
index bb91f9b8cf0b..4f3aee99c206 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
@@ -21,6 +21,8 @@ import android.hardware.display.DisplayManager
import android.os.Handler
import android.os.RemoteException
import android.os.Trace
+import androidx.annotation.AnyThread
+import com.android.systemui.unfold.dagger.UnfoldBg
import com.android.systemui.unfold.util.CallbackController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -35,7 +37,8 @@ class RotationChangeProvider
constructor(
private val displayManager: DisplayManager,
private val context: Context,
- @Assisted private val handler: Handler,
+ @UnfoldBg private val bgHandler: Handler,
+ @Assisted private val callbackHandler: Handler,
) : CallbackController<RotationChangeProvider.RotationListener> {
private val listeners = mutableListOf<RotationListener>()
@@ -44,7 +47,7 @@ constructor(
private var lastRotation: Int? = null
override fun addCallback(listener: RotationListener) {
- handler.post {
+ bgHandler.post {
if (listeners.isEmpty()) {
subscribeToRotation()
}
@@ -53,7 +56,7 @@ constructor(
}
override fun removeCallback(listener: RotationListener) {
- handler.post {
+ bgHandler.post {
listeners -= listener
if (listeners.isEmpty()) {
unsubscribeToRotation()
@@ -64,7 +67,7 @@ constructor(
private fun subscribeToRotation() {
try {
- displayManager.registerDisplayListener(displayListener, handler)
+ displayManager.registerDisplayListener(displayListener, callbackHandler)
} catch (e: RemoteException) {
throw e.rethrowFromSystemServer()
}
@@ -80,8 +83,11 @@ constructor(
/** Gets notified of rotation changes. */
fun interface RotationListener {
- /** Called once rotation changes. */
- fun onRotationChanged(newRotation: Int)
+ /**
+ * Called once rotation changes. This callback is called on the handler provided to
+ * [RotationChangeProvider.Factory.create].
+ */
+ @AnyThread fun onRotationChanged(newRotation: Int)
}
private inner class RotationDisplayListener : DisplayManager.DisplayListener {
@@ -110,7 +116,7 @@ constructor(
@AssistedFactory
interface Factory {
- /** Creates a new [RotationChangeProvider] that provides updated using [handler]. */
- fun create(handler: Handler): RotationChangeProvider
+ /** Creates a new [RotationChangeProvider] that provides updated using [callbackHandler]. */
+ fun create(callbackHandler: Handler): RotationChangeProvider
}
}
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 3f30b0a5b059..a50fb9a4c318 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -138,6 +138,16 @@ flag {
}
flag {
+ name: "manager_package_monitor_logic_fix"
+ namespace: "accessibility"
+ description: "Corrects the return values of the HandleForceStop function"
+ bug: "337392123"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "pinch_zoom_zero_min_span"
namespace: "accessibility"
description: "Whether to set min span of ScaleGestureDetector to zero."
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index c70b6419e3b8..d7ed867c2ae5 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -697,7 +697,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
/**
* Returns the lock object for any synchronized test blocks.
- * Should not be used outside of testing.
+ * External classes should only use for testing.
* @return lock object.
*/
@VisibleForTesting
@@ -801,7 +801,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
*
* @param packages list of packages that have stopped.
* @param userState user state to be read & modified.
- * @return {@code true} if a service was enabled or a button target was removed,
+ * @return {@code true} if the lists of enabled services or buttons were changed,
* {@code false} otherwise.
*/
@VisibleForTesting
@@ -824,6 +824,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
userState.getBindingServicesLocked().remove(comp);
userState.getCrashedServicesLocked().remove(comp);
enabledServicesChanged = true;
+ break;
}
}
}
@@ -851,132 +852,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return mPackageMonitor;
}
- private void registerBroadcastReceivers() {
- mPackageMonitor = new PackageMonitor(true) {
- @Override
- public void onSomePackagesChanged() {
- if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
- mTraceManager.logTrace(LOG_TAG + ".PM.onSomePackagesChanged",
- FLAGS_PACKAGE_BROADCAST_RECEIVER);
- }
-
- final int userId = getChangingUserId();
- List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = null;
- List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = null;
- parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId);
- parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId);
- synchronized (mLock) {
- // Only the profile parent can install accessibility services.
- // Therefore we ignore packages from linked profiles.
- if (userId != mCurrentUserId) {
- return;
- }
- onSomePackagesChangedLocked(parsedAccessibilityServiceInfos,
- parsedAccessibilityShortcutInfos);
- }
- }
-
- @Override
- public void onPackageUpdateFinished(String packageName, int uid) {
- // The package should already be removed from mBoundServices, and added into
- // mBindingServices in binderDied() during updating. Remove services from this
- // package from mBindingServices, and then update the user state to re-bind new
- // versions of them.
- if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
- mTraceManager.logTrace(LOG_TAG + ".PM.onPackageUpdateFinished",
- FLAGS_PACKAGE_BROADCAST_RECEIVER,
- "packageName=" + packageName + ";uid=" + uid);
- }
- final int userId = getChangingUserId();
- List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = null;
- List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = null;
- parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId);
- parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId);
- synchronized (mLock) {
- if (userId != mCurrentUserId) {
- return;
- }
- final AccessibilityUserState userState = getUserStateLocked(userId);
- final boolean reboundAService = userState.getBindingServicesLocked().removeIf(
- component -> component != null
- && component.getPackageName().equals(packageName))
- || userState.mCrashedServices.removeIf(component -> component != null
- && component.getPackageName().equals(packageName));
- // Reloads the installed services info to make sure the rebound service could
- // get a new one.
- userState.mInstalledServices.clear();
- final boolean configurationChanged;
- configurationChanged = readConfigurationForUserStateLocked(userState,
- parsedAccessibilityServiceInfos, parsedAccessibilityShortcutInfos);
- if (reboundAService || configurationChanged) {
- onUserStateChangedLocked(userState);
- }
- // Passing 0 for restoreFromSdkInt to have this migration check execute each
- // time. It can make sure a11y button settings are correctly if there's an a11y
- // service updated and modifies the a11y button configuration.
- migrateAccessibilityButtonSettingsIfNecessaryLocked(userState, packageName,
- /* restoreFromSdkInt = */0);
- }
- }
-
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
- mTraceManager.logTrace(LOG_TAG + ".PM.onPackageRemoved",
- FLAGS_PACKAGE_BROADCAST_RECEIVER,
- "packageName=" + packageName + ";uid=" + uid);
- }
-
- synchronized (mLock) {
- final int userId = getChangingUserId();
- // Only the profile parent can install accessibility services.
- // Therefore we ignore packages from linked profiles.
- if (userId != mCurrentUserId) {
- return;
- }
- onPackageRemovedLocked(packageName);
- }
- }
-
- /**
- * Handles instances in which a package or packages have forcibly stopped.
- *
- * @param intent intent containing package event information.
- * @param uid linux process user id (different from Android user id).
- * @param packages array of package names that have stopped.
- * @param doit whether to try and handle the stop or just log the trace.
- *
- * @return {@code true} if package should be restarted, {@code false} otherwise.
- */
- @Override
- public boolean onHandleForceStop(Intent intent, String[] packages,
- int uid, boolean doit) {
- if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
- mTraceManager.logTrace(LOG_TAG + ".PM.onHandleForceStop",
- FLAGS_PACKAGE_BROADCAST_RECEIVER,
- "intent=" + intent + ";packages=" + Arrays.toString(packages)
- + ";uid=" + uid + ";doit=" + doit);
- }
- synchronized (mLock) {
- final int userId = getChangingUserId();
- // Only the profile parent can install accessibility services.
- // Therefore we ignore packages from linked profiles.
- if (userId != mCurrentUserId) {
- return false;
- }
- final AccessibilityUserState userState = getUserStateLocked(userId);
-
- if (doit && onPackagesForceStoppedLocked(packages, userState)) {
- onUserStateChangedLocked(userState);
- return false;
- } else {
- return true;
- }
- }
- }
- };
+ @VisibleForTesting
+ void setPackageMonitor(PackageMonitor monitor) {
+ mPackageMonitor = monitor;
+ }
+ private void registerBroadcastReceivers() {
// package changes
+ mPackageMonitor = new ManagerPackageMonitor(this);
mPackageMonitor.register(mContext, null, UserHandle.ALL, true);
// user change and unlock
@@ -992,7 +875,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
@Override
public void onReceive(Context context, Intent intent) {
if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_USER_BROADCAST_RECEIVER)) {
- mTraceManager.logTrace(LOG_TAG + ".BR.onReceive", FLAGS_USER_BROADCAST_RECEIVER,
+ mTraceManager.logTrace(
+ LOG_TAG + ".BR.onReceive",
+ FLAGS_USER_BROADCAST_RECEIVER,
"context=" + context + ";intent=" + intent);
}
@@ -1045,7 +930,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
setNonA11yToolNotificationToMatchSafetyCenter();
}
};
- mContext.registerReceiverAsUser(receiver, UserHandle.ALL, filter, null, mMainHandler,
+ mContext.registerReceiverAsUser(
+ receiver, UserHandle.ALL, filter, null, mMainHandler,
Context.RECEIVER_EXPORTED);
if (!android.companion.virtual.flags.Flags.vdmPublicApis()) {
@@ -4371,7 +4257,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
);
if (!targetWithNoTile.isEmpty()) {
- throw new IllegalArgumentException(
+ Slog.e(LOG_TAG,
"Unable to add/remove Tiles for a11y features: " + targetWithNoTile
+ "as the Tiles aren't provided");
}
@@ -6223,6 +6109,169 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
+ @VisibleForTesting
+ public static class ManagerPackageMonitor extends PackageMonitor {
+ private final AccessibilityManagerService mManagerService;
+ public ManagerPackageMonitor(AccessibilityManagerService managerService) {
+ super(/* supportsPackageRestartQuery = */ true);
+ mManagerService = managerService;
+ }
+
+ @Override
+ public void onSomePackagesChanged() {
+ if (mManagerService.mTraceManager.isA11yTracingEnabledForTypes(
+ FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
+ mManagerService.mTraceManager.logTrace(LOG_TAG + ".PM.onSomePackagesChanged",
+ FLAGS_PACKAGE_BROADCAST_RECEIVER);
+ }
+
+ final int userId = getChangingUserId();
+ List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = mManagerService
+ .parseAccessibilityServiceInfos(userId);
+ List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = mManagerService
+ .parseAccessibilityShortcutInfos(userId);
+ synchronized (mManagerService.getLock()) {
+ // Only the profile parent can install accessibility services.
+ // Therefore we ignore packages from linked profiles.
+ if (userId != mManagerService.getCurrentUserIdLocked()) {
+ return;
+ }
+ mManagerService.onSomePackagesChangedLocked(parsedAccessibilityServiceInfos,
+ parsedAccessibilityShortcutInfos);
+ }
+ }
+
+ @Override
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ // The package should already be removed from mBoundServices, and added into
+ // mBindingServices in binderDied() during updating. Remove services from this
+ // package from mBindingServices, and then update the user state to re-bind new
+ // versions of them.
+ if (mManagerService.mTraceManager.isA11yTracingEnabledForTypes(
+ FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
+ mManagerService.mTraceManager.logTrace(
+ LOG_TAG + ".PM.onPackageUpdateFinished",
+ FLAGS_PACKAGE_BROADCAST_RECEIVER,
+ "packageName=" + packageName + ";uid=" + uid);
+ }
+ final int userId = getChangingUserId();
+ List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = mManagerService
+ .parseAccessibilityServiceInfos(userId);
+ List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos =
+ mManagerService.parseAccessibilityShortcutInfos(userId);
+ synchronized (mManagerService.getLock()) {
+ if (userId != mManagerService.getCurrentUserIdLocked()) {
+ return;
+ }
+ final AccessibilityUserState userState = mManagerService.getUserStateLocked(userId);
+ final boolean reboundAService = userState.getBindingServicesLocked().removeIf(
+ component -> component != null
+ && component.getPackageName().equals(packageName))
+ || userState.mCrashedServices.removeIf(component -> component != null
+ && component.getPackageName().equals(packageName));
+ // Reloads the installed services info to make sure the rebound service could
+ // get a new one.
+ userState.mInstalledServices.clear();
+ final boolean configurationChanged;
+ configurationChanged = mManagerService.readConfigurationForUserStateLocked(
+ userState, parsedAccessibilityServiceInfos,
+ parsedAccessibilityShortcutInfos);
+ if (reboundAService || configurationChanged) {
+ mManagerService.onUserStateChangedLocked(userState);
+ }
+ // Passing 0 for restoreFromSdkInt to have this migration check execute each
+ // time. It can make sure a11y button settings are correctly if there's an a11y
+ // service updated and modifies the a11y button configuration.
+ mManagerService.migrateAccessibilityButtonSettingsIfNecessaryLocked(
+ userState, packageName, /* restoreFromSdkInt = */0);
+ }
+ }
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ if (mManagerService.mTraceManager.isA11yTracingEnabledForTypes(
+ FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
+ mManagerService.mTraceManager.logTrace(LOG_TAG + ".PM.onPackageRemoved",
+ FLAGS_PACKAGE_BROADCAST_RECEIVER,
+ "packageName=" + packageName + ";uid=" + uid);
+ }
+
+ synchronized (mManagerService.getLock()) {
+ final int userId = getChangingUserId();
+ // Only the profile parent can install accessibility services.
+ // Therefore we ignore packages from linked profiles.
+ if (userId != mManagerService.getCurrentUserIdLocked()) {
+ return;
+ }
+ mManagerService.onPackageRemovedLocked(packageName);
+ }
+ }
+
+ /**
+ * Handles instances in which a package or packages have forcibly stopped.
+ *
+ * @param intent intent containing package event information.
+ * @param uid linux process user id (different from Android user id).
+ * @param packages array of package names that have stopped.
+ * @param doit whether to try and handle the stop or just log the trace.
+ *
+ * @return {@code true} if doit == {@code false}
+ * and at least one of the provided packages is enabled.
+ * In any other case, returns {@code false}.
+ * This is to indicate whether further action is necessary.
+ */
+ @Override
+ public boolean onHandleForceStop(Intent intent, String[] packages,
+ int uid, boolean doit) {
+ if (mManagerService.mTraceManager.isA11yTracingEnabledForTypes(
+ FLAGS_PACKAGE_BROADCAST_RECEIVER)) {
+ mManagerService.mTraceManager.logTrace(LOG_TAG + ".PM.onHandleForceStop",
+ FLAGS_PACKAGE_BROADCAST_RECEIVER,
+ "intent=" + intent + ";packages=" + Arrays.toString(packages)
+ + ";uid=" + uid + ";doit=" + doit);
+ }
+ synchronized (mManagerService.getLock()) {
+ final int userId = getChangingUserId();
+ // Only the profile parent can install accessibility services.
+ // Therefore we ignore packages from linked profiles.
+ if (userId != mManagerService.getCurrentUserIdLocked()) {
+ return false;
+ }
+ final AccessibilityUserState userState = mManagerService.getUserStateLocked(userId);
+
+ if (Flags.managerPackageMonitorLogicFix()) {
+ if (!doit) {
+ // if we're not handling the stop here, then we only need to know
+ // if any of the force-stopped packages are currently enabled.
+ return userState.mEnabledServices.stream().anyMatch(
+ (comp) -> Arrays.stream(packages).anyMatch(
+ (pkg) -> pkg.equals(comp.getPackageName()))
+ );
+ } else if (mManagerService.onPackagesForceStoppedLocked(packages, userState)) {
+ mManagerService.onUserStateChangedLocked(userState);
+ }
+ return false;
+ } else {
+ // this old logic did not properly indicate when base packageMonitor's routine
+ // should handle stopping the package.
+ if (doit && mManagerService.onPackagesForceStoppedLocked(packages, userState)) {
+ mManagerService.onUserStateChangedLocked(userState);
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
+ // We care about all package changes, not just the whole package itself which is
+ // default behavior.
+ return true;
+ }
+ }
+
void sendPendingWindowStateChangedEventsForAvailableWindowLocked(int windowId) {
final int eventSize = mSendWindowStateChangedEventRunnables.size();
for (int i = eventSize - 1; i >= 0; i--) {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 71b16c3a18b6..55677078f939 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -521,9 +521,13 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
false);
final boolean packageRemovedPermanently =
(extras == null || !isReplacing || (isReplacing && isArchival));
-
if (packageRemovedPermanently) {
for (String pkgName : pkgList) {
+ if (DEBUG) {
+ Slog.i(TAG, "calling removeHostsAndProvidersForPackageLocked() "
+ + "because package removed permanently. extras=" + extras
+ + " isReplacing=" + isReplacing + " isArchival=" + isArchival);
+ }
componentsModified |= removeHostsAndProvidersForPackageLocked(
pkgName, userId);
}
@@ -2053,6 +2057,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
private void deleteHostLocked(Host host) {
+ if (DEBUG) {
+ Slog.i(TAG, "deleteHostLocked() " + host);
+ }
final int N = host.widgets.size();
for (int i = N - 1; i >= 0; i--) {
Widget widget = host.widgets.remove(i);
@@ -2065,6 +2072,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
private void deleteAppWidgetLocked(Widget widget) {
+ if (DEBUG) {
+ Slog.i(TAG, "deleteAppWidgetLocked() " + widget);
+ }
// We first unbind all services that are bound to this id
// Check if we need to destroy any services (if no other app widgets are
// referencing the same service)
@@ -2532,6 +2542,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
return widget;
}
}
+ if (DEBUG) {
+ Slog.i(TAG, "cannot find widget for appWidgetId=" + appWidgetId + " uid=" + uid
+ + " packageName=" + packageName);
+ }
return null;
}
@@ -2649,6 +2663,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
// Remove widgets for provider that are hosted in userId.
private void deleteWidgetsLocked(Provider provider, int userId) {
+ if (DEBUG) {
+ Slog.i(TAG, "deleteWidgetsLocked() provider=" + provider + " userId=" + userId);
+ }
final int N = provider.widgets.size();
for (int i = N - 1; i >= 0; i--) {
Widget widget = provider.widgets.get(i);
@@ -3326,6 +3343,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
* Adds the widget to mWidgets and tracks the package name in mWidgetPackages.
*/
void addWidgetLocked(Widget widget) {
+ if (DEBUG) {
+ Slog.i(TAG, "addWidgetLocked() " + widget);
+ }
mWidgets.add(widget);
onWidgetProviderAddedOrChangedLocked(widget);
@@ -3362,6 +3382,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
* removes the associated package from the cache.
*/
void removeWidgetLocked(Widget widget) {
+ if (DEBUG) {
+ Slog.i(TAG, "removeWidgetLocked() " + widget);
+ }
mWidgets.remove(widget);
onWidgetRemovedLocked(widget);
scheduleNotifyAppWidgetRemovedLocked(widget);
@@ -3396,6 +3419,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
* Clears all widgets and associated cache of packages with bound widgets.
*/
void clearWidgetsLocked() {
+ if (DEBUG) {
+ Slog.i(TAG, "clearWidgetsLocked()");
+ }
mWidgets.clear();
onWidgetsClearedLocked();
@@ -3757,6 +3783,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
void onUserStopped(int userId) {
+ if (DEBUG) {
+ Slog.i(TAG, "onUserStopped() " + userId);
+ }
synchronized (mLock) {
boolean crossProfileWidgetsChanged = false;
@@ -3994,6 +4023,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
private boolean removeHostsAndProvidersForPackageLocked(String pkgName, int userId) {
+ if (DEBUG) {
+ Slog.i(TAG, "removeHostsAndProvidersForPackageLocked() pkg=" + pkgName
+ + " userId=" + userId);
+ }
boolean removed = removeProvidersForPackageLocked(pkgName, userId);
// Delete the hosts for this package too
@@ -4552,6 +4585,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
// have the bind widget permission have access to the widget.
return true;
}
+ if (DEBUG) {
+ Slog.i(TAG, "canAccessAppWidget() failed. packageName=" + packageName
+ + " uid=" + uid + " userId=" + userId + " widget=" + widget);
+ }
return false;
}
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 9f279b1ba3fe..f69a521130ab 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -34,6 +34,7 @@ import android.os.TombstoneWithHeadersProto;
import android.provider.Downloads;
import android.system.ErrnoException;
import android.system.Os;
+import android.system.OsConstants;
import android.text.TextUtils;
import android.util.AtomicFile;
import android.util.EventLog;
@@ -230,16 +231,23 @@ public class BootReceiver extends BroadcastReceiver {
}
private static String getCurrentBootHeaders() throws IOException {
- return new StringBuilder(512)
- .append("Build: ").append(Build.FINGERPRINT).append("\n")
- .append("Hardware: ").append(Build.BOARD).append("\n")
- .append("Revision: ")
- .append(SystemProperties.get("ro.revision", "")).append("\n")
- .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
- .append("Radio: ").append(Build.getRadioVersion()).append("\n")
- .append("Kernel: ")
- .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
- .append("\n").toString();
+ StringBuilder builder = new StringBuilder(512)
+ .append("Build: ").append(Build.FINGERPRINT).append("\n")
+ .append("Hardware: ").append(Build.BOARD).append("\n")
+ .append("Revision: ")
+ .append(SystemProperties.get("ro.revision", "")).append("\n")
+ .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
+ .append("Radio: ").append(Build.getRadioVersion()).append("\n")
+ .append("Kernel: ")
+ .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"));
+
+ // If device is not using 4KB pages, add the PageSize
+ long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+ if (pageSize != 4096) {
+ builder.append("PageSize: ").append(pageSize).append("\n");
+ }
+ builder.append("\n");
+ return builder.toString();
}
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index d9e6186639ce..ef03888d6620 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -21,6 +21,7 @@ import static android.app.ActivityManager.UID_OBSERVER_GONE;
import static android.os.Process.SYSTEM_UID;
import static com.android.server.flags.Flags.pinWebview;
+import static com.android.server.flags.Flags.skipHomeArtPins;
import android.annotation.EnforcePermission;
import android.annotation.IntDef;
@@ -851,6 +852,9 @@ public final class PinnerService extends SystemService {
}
int apkPinSizeLimit = pinSizeLimit;
+
+ boolean shouldSkipArtPins = key == KEY_HOME && skipHomeArtPins();
+
for (String apk: apks) {
if (apkPinSizeLimit <= 0) {
Slog.w(TAG, "Reached to the pin size limit. Skipping: " + apk);
@@ -874,8 +878,8 @@ public final class PinnerService extends SystemService {
}
apkPinSizeLimit -= pf.bytesPinned;
- if (apk.equals(appInfo.sourceDir)) {
- pinOptimizedDexDependencies(pf, apkPinSizeLimit, appInfo);
+ if (apk.equals(appInfo.sourceDir) && !shouldSkipArtPins) {
+ pinOptimizedDexDependencies(pf, Integer.MAX_VALUE, appInfo);
}
}
}
@@ -921,8 +925,8 @@ public final class PinnerService extends SystemService {
}
pf.groupName = groupName != null ? groupName : "";
- maxBytesToPin -= bytesPinned;
bytesPinned += pf.bytesPinned;
+ maxBytesToPin -= bytesPinned;
synchronized (this) {
mPinnedFiles.put(pf.fileName, pf);
@@ -970,7 +974,7 @@ public final class PinnerService extends SystemService {
// Unpin if it was already pinned prior to re-pinning.
unpinFile(file);
- PinnedFile df = mInjector.pinFileInternal(file, Integer.MAX_VALUE,
+ PinnedFile df = mInjector.pinFileInternal(file, maxBytesToPin,
/*attemptPinIntrospection=*/false);
if (df == null) {
Slog.i(TAG, "Failed to pin ART file = " + file);
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 04e85c7f117a..a3b6d806c6ce 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -134,6 +134,13 @@
},
{
"name": "CtsSuspendAppsTestCases"
+ },
+ {
+ "name": "CtsWindowManagerBackgroundActivityTestCases",
+ "file_patterns": [
+ "Background.*\\.java",
+ "Activity.*\\.java"
+ ]
}
],
"presubmit-large": [
@@ -189,18 +196,16 @@
"name": "SelinuxFrameworksTests"
},
{
- "name": "CtsWindowManagerBackgroundActivityTestCases",
- "file_patterns": [
- "Background.*\\.java",
- "Activity.*\\.java"
- ]
- },
- {
"name": "WmTests",
"file_patterns": [
"Background.*\\.java",
"Activity.*\\.java"
+ ],
+ "options": [
+ {
+ "include-filter": "com.android.server.wm.BackgroundActivityStart*"
+ }
]
}
- ]
+ ]
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 00d8efa764ce..4c8f41608f46 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -372,6 +372,8 @@ import android.provider.DeviceConfig;
import android.provider.Settings;
import android.server.ServerProtoEnums;
import android.sysprop.InitProperties;
+import android.system.Os;
+import android.system.OsConstants;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
@@ -5588,32 +5590,30 @@ public class ActivityManagerService extends IActivityManager.Stub
// security checking for it above.
userId = UserHandle.USER_CURRENT;
}
- try {
- if (owningUid != 0 && owningUid != SYSTEM_UID) {
- final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
- MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(owningUid));
- if (!UserHandle.isSameApp(owningUid, uid)) {
- String msg = "Permission Denial: getIntentSender() from pid="
- + Binder.getCallingPid()
- + ", uid=" + owningUid
- + ", (need uid=" + uid + ")"
- + " is not allowed to send as package " + packageName;
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
- }
- if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
- return mAtmInternal.getIntentSender(type, packageName, featureId, owningUid,
- userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
- bOptions);
+ if (owningUid != 0 && owningUid != SYSTEM_UID) {
+ if (!getPackageManagerInternal().isSameApp(
+ packageName,
+ MATCH_DEBUG_TRIAGED_MISSING,
+ owningUid,
+ UserHandle.getUserId(owningUid))) {
+ String msg = "Permission Denial: getIntentSender() from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + owningUid
+ + " is not allowed to send as package " + packageName;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
}
- return mPendingIntentController.getIntentSender(type, packageName, featureId,
- owningUid, userId, token, resultWho, requestCode, intents, resolvedTypes,
- flags, bOptions);
- } catch (RemoteException e) {
- throw new SecurityException(e);
}
+
+ if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
+ return mAtmInternal.getIntentSender(type, packageName, featureId, owningUid,
+ userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
+ bOptions);
+ }
+ return mPendingIntentController.getIntentSender(type, packageName, featureId,
+ owningUid, userId, token, resultWho, requestCode, intents, resolvedTypes,
+ flags, bOptions);
}
@Override
@@ -9911,6 +9911,13 @@ public class ActivityManagerService extends IActivityManager.Stub
sb.append("ErrorId: ").append(errorId.toString()).append("\n");
}
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+
+ // If device is not using 4KB pages, add the PageSize
+ long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+ if (pageSize != 4096) {
+ sb.append("PageSize: ").append(pageSize).append("\n");
+ }
+
if (Debug.isDebuggerConnected()) {
sb.append("Debugger: Connected\n");
}
@@ -19975,6 +19982,26 @@ public class ActivityManagerService extends IActivityManager.Stub
addStartInfoTimestampInternal(key, timestampNs, userId, uid);
}
+
+ @Override
+ public void killApplicationSync(String pkgName, int appId, int userId,
+ String reason, int exitInfoReason) {
+ if (pkgName == null) {
+ return;
+ }
+ // Make sure the uid is valid.
+ if (appId < 0) {
+ Slog.w(TAG, "Invalid appid specified for pkg : " + pkgName);
+ return;
+ }
+ synchronized (ActivityManagerService.this) {
+ ActivityManagerService.this.forceStopPackageLocked(pkgName, appId,
+ /* callerWillRestart= */ false, /*purgeCache= */ false,
+ /* doit= */ true, /* evenPersistent= */ false,
+ /* uninstalling= */ false, /* packageStateStopped= */ false,
+ userId, reason, exitInfoReason);
+ }
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, TimeoutRecord timeoutRecord) {
diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java
index 9600317faca1..a67af89ad39d 100644
--- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java
+++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java
@@ -84,6 +84,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.function.ToIntFunction;
/**
* A modern implementation of the oom adjuster.
@@ -271,11 +272,31 @@ public class OomAdjusterModernImpl extends OomAdjuster {
// The last node besides the tail.
private final ProcessRecordNode[] mLastNode;
+ private final ToIntFunction<ProcessRecord> mSlotFunction;
+ // Cache of the most important slot with a node in it.
+ private int mFirstPopulatedSlot = 0;
+
ProcessRecordNodes(@ProcessRecordNode.NodeType int type, int size) {
mType = type;
+ final ToIntFunction<ProcessRecord> valueFunction;
+ switch (mType) {
+ case ProcessRecordNode.NODE_TYPE_PROC_STATE:
+ valueFunction = (proc) -> proc.mState.getCurProcState();
+ mSlotFunction = (proc) -> processStateToSlot(proc.mState.getCurProcState());
+ break;
+ case ProcessRecordNode.NODE_TYPE_ADJ:
+ valueFunction = (proc) -> proc.mState.getCurRawAdj();
+ mSlotFunction = (proc) -> adjToSlot(proc.mState.getCurRawAdj());
+ break;
+ default:
+ valueFunction = (proc) -> 0;
+ mSlotFunction = (proc) -> 0;
+ break;
+ }
+
mProcessRecordNodes = new LinkedProcessRecordList[size];
for (int i = 0; i < size; i++) {
- mProcessRecordNodes[i] = new LinkedProcessRecordList(type);
+ mProcessRecordNodes[i] = new LinkedProcessRecordList(valueFunction);
}
mLastNode = new ProcessRecordNode[size];
resetLastNodes();
@@ -294,6 +315,11 @@ public class OomAdjusterModernImpl extends OomAdjuster {
}
void resetLastNodes() {
+ if (Flags.simplifyProcessTraversal()) {
+ // Last nodes are no longer used. Just reset instead.
+ reset();
+ return;
+ }
for (int i = 0; i < mProcessRecordNodes.length; i++) {
mLastNode[i] = mProcessRecordNodes[i].getLastNodeBeforeTail();
}
@@ -308,6 +334,36 @@ public class OomAdjusterModernImpl extends OomAdjuster {
final ProcessRecordNode tail = mProcessRecordNodes[slot].TAIL;
while (node != tail) {
mTmpOomAdjusterArgs.mApp = node.mApp;
+ if (node.mApp == null) {
+ // TODO(b/336178916) - Temporary logging for root causing b/336178916.
+ StringBuilder sb = new StringBuilder();
+ sb.append("Iterating null process during OomAdjuster traversal!!!\n");
+ sb.append("Type:");
+ switch (mType) {
+ case ProcessRecordNode.NODE_TYPE_PROC_STATE -> sb.append(
+ "NODE_TYPE_PROC_STATE");
+ case ProcessRecordNode.NODE_TYPE_ADJ -> sb.append("NODE_TYPE_ADJ");
+ default -> sb.append("UNKNOWN");
+ }
+ sb.append(", Slot:");
+ sb.append(slot);
+ sb.append("\nLAST:");
+ ProcessRecordNode last = mLastNode[slot];
+ if (last.mApp == null) {
+ sb.append("null");
+ } else {
+ sb.append(last);
+ sb.append("\nSetProcState:");
+ sb.append(last.mApp.getSetProcState());
+ sb.append(", CurProcState:");
+ sb.append(last.mApp.mState.getCurProcState());
+ sb.append(", SetAdj:");
+ sb.append(last.mApp.getSetAdj());
+ sb.append(", CurRawAdj:");
+ sb.append(last.mApp.mState.getCurRawAdj());
+ }
+ Slog.wtfStack(TAG, sb.toString());
+ }
// Save the next before calling callback, since that may change the node.mNext.
final ProcessRecordNode next = node.mNext;
callback.accept(mTmpOomAdjusterArgs);
@@ -325,6 +381,33 @@ public class OomAdjusterModernImpl extends OomAdjuster {
}
}
+ ProcessRecord poll() {
+ ProcessRecordNode node = null;
+ final int size = mProcessRecordNodes.length;
+ // Find the next node.
+ while (node == null && mFirstPopulatedSlot < size) {
+ node = mProcessRecordNodes[mFirstPopulatedSlot].poll();
+ if (node == null) {
+ // This slot is now empty, move on to the next.
+ mFirstPopulatedSlot++;
+ }
+ }
+ if (node == null) return null;
+ return node.mApp;
+ }
+
+ void offer(ProcessRecord proc) {
+ ProcessRecordNode node = proc.mLinkedNodes[mType];
+ // Find which slot to add the node to.
+ final int newSlot = mSlotFunction.applyAsInt(proc);
+ if (newSlot < mFirstPopulatedSlot) {
+ // node is being added to a more important slot.
+ mFirstPopulatedSlot = newSlot;
+ }
+ node.unlink();
+ mProcessRecordNodes[newSlot].offer(node);
+ }
+
int getNumberOfSlots() {
return mProcessRecordNodes.length;
}
@@ -423,12 +506,35 @@ public class OomAdjusterModernImpl extends OomAdjuster {
// Sentinel head/tail, to make bookkeeping work easier.
final ProcessRecordNode HEAD = new ProcessRecordNode(null);
final ProcessRecordNode TAIL = new ProcessRecordNode(null);
- final @ProcessRecordNode.NodeType int mNodeType;
+ final ToIntFunction<ProcessRecord> mValueFunction;
- LinkedProcessRecordList(@ProcessRecordNode.NodeType int nodeType) {
+ LinkedProcessRecordList(ToIntFunction<ProcessRecord> valueFunction) {
HEAD.mNext = TAIL;
TAIL.mPrev = HEAD;
- mNodeType = nodeType;
+ mValueFunction = valueFunction;
+ }
+
+ ProcessRecordNode poll() {
+ final ProcessRecordNode next = HEAD.mNext;
+ if (next == TAIL) return null;
+ next.unlink();
+ return next;
+ }
+
+ void offer(@NonNull ProcessRecordNode node) {
+ final int newValue = mValueFunction.applyAsInt(node.mApp);
+
+ // Find the last node with less than or equal value to the new node.
+ ProcessRecordNode curNode = TAIL.mPrev;
+ while (curNode != HEAD && mValueFunction.applyAsInt(curNode.mApp) > newValue) {
+ curNode = curNode.mPrev;
+ }
+
+ // Insert the new node after the found node.
+ node.mPrev = curNode;
+ node.mNext = curNode.mNext;
+ curNode.mNext.mPrev = node;
+ curNode.mNext = node;
}
void append(@NonNull ProcessRecordNode node) {
@@ -727,34 +833,50 @@ public class OomAdjusterModernImpl extends OomAdjuster {
private void updateAdjSlotIfNecessary(ProcessRecord app, int prevRawAdj) {
if (app.mState.getCurRawAdj() != prevRawAdj) {
- final int slot = adjToSlot(app.mState.getCurRawAdj());
- final int prevSlot = adjToSlot(prevRawAdj);
- if (slot != prevSlot && slot != ADJ_SLOT_INVALID) {
- mProcessRecordAdjNodes.moveAppTo(app, prevSlot, slot);
+ if (Flags.simplifyProcessTraversal()) {
+ mProcessRecordAdjNodes.offer(app);
+ } else {
+ final int slot = adjToSlot(app.mState.getCurRawAdj());
+ final int prevSlot = adjToSlot(prevRawAdj);
+ if (slot != prevSlot && slot != ADJ_SLOT_INVALID) {
+ mProcessRecordAdjNodes.moveAppTo(app, prevSlot, slot);
+ }
}
}
}
private void updateAdjSlot(ProcessRecord app, int prevRawAdj) {
- final int slot = adjToSlot(app.mState.getCurRawAdj());
- final int prevSlot = adjToSlot(prevRawAdj);
- mProcessRecordAdjNodes.moveAppTo(app, prevSlot, slot);
+ if (Flags.simplifyProcessTraversal()) {
+ mProcessRecordAdjNodes.offer(app);
+ } else {
+ final int slot = adjToSlot(app.mState.getCurRawAdj());
+ final int prevSlot = adjToSlot(prevRawAdj);
+ mProcessRecordAdjNodes.moveAppTo(app, prevSlot, slot);
+ }
}
private void updateProcStateSlotIfNecessary(ProcessRecord app, int prevProcState) {
if (app.mState.getCurProcState() != prevProcState) {
- final int slot = processStateToSlot(app.mState.getCurProcState());
- final int prevSlot = processStateToSlot(prevProcState);
- if (slot != prevSlot) {
- mProcessRecordProcStateNodes.moveAppTo(app, prevSlot, slot);
+ if (Flags.simplifyProcessTraversal()) {
+ mProcessRecordProcStateNodes.offer(app);
+ } else {
+ final int slot = processStateToSlot(app.mState.getCurProcState());
+ final int prevSlot = processStateToSlot(prevProcState);
+ if (slot != prevSlot) {
+ mProcessRecordProcStateNodes.moveAppTo(app, prevSlot, slot);
+ }
}
}
}
private void updateProcStateSlot(ProcessRecord app, int prevProcState) {
- final int slot = processStateToSlot(app.mState.getCurProcState());
- final int prevSlot = processStateToSlot(prevProcState);
- mProcessRecordProcStateNodes.moveAppTo(app, prevSlot, slot);
+ if (Flags.simplifyProcessTraversal()) {
+ mProcessRecordProcStateNodes.offer(app);
+ } else {
+ final int slot = processStateToSlot(app.mState.getCurProcState());
+ final int prevSlot = processStateToSlot(prevProcState);
+ mProcessRecordProcStateNodes.moveAppTo(app, prevSlot, slot);
+ }
}
@Override
@@ -832,8 +954,15 @@ public class OomAdjusterModernImpl extends OomAdjuster {
// Compute initial values, the procState and adj priority queues will be populated here.
computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, true, now, false, false, oomAdjReason,
false);
- updateProcStateSlot(app, prevProcState);
- updateAdjSlot(app, prevAdj);
+
+ if (Flags.simplifyProcessTraversal()) {
+ // Just add to the procState priority queue. The adj priority queue should be
+ // empty going into the traversal step.
+ mProcessRecordProcStateNodes.offer(app);
+ } else {
+ updateProcStateSlot(app, prevProcState);
+ updateAdjSlot(app, prevAdj);
+ }
}
// Set adj last nodes now, this way a process will only be reevaluated during the adj node
@@ -851,14 +980,32 @@ public class OomAdjusterModernImpl extends OomAdjuster {
*/
@GuardedBy({"mService", "mProcLock"})
private void computeConnectionsLSP() {
- // 1st pass, scan each slot in the procstate node list.
- for (int i = 0, end = mProcessRecordProcStateNodes.size() - 1; i < end; i++) {
- mProcessRecordProcStateNodes.forEachNewNode(i, mComputeConnectionsConsumer);
- }
+ if (Flags.simplifyProcessTraversal()) {
+ // 1st pass, iterate all nodes in order of procState importance.
+ ProcessRecord proc = mProcessRecordProcStateNodes.poll();
+ while (proc != null) {
+ mTmpOomAdjusterArgs.mApp = proc;
+ mComputeConnectionsConsumer.accept(mTmpOomAdjusterArgs);
+ proc = mProcessRecordProcStateNodes.poll();
+ }
+
+ // 2st pass, iterate all nodes in order of procState importance.
+ proc = mProcessRecordAdjNodes.poll();
+ while (proc != null) {
+ mTmpOomAdjusterArgs.mApp = proc;
+ mComputeConnectionsConsumer.accept(mTmpOomAdjusterArgs);
+ proc = mProcessRecordAdjNodes.poll();
+ }
+ } else {
+ // 1st pass, scan each slot in the procstate node list.
+ for (int i = 0, end = mProcessRecordProcStateNodes.size() - 1; i < end; i++) {
+ mProcessRecordProcStateNodes.forEachNewNode(i, mComputeConnectionsConsumer);
+ }
- // 2nd pass, scan each slot in the adj node list.
- for (int i = 0, end = mProcessRecordAdjNodes.size() - 1; i < end; i++) {
- mProcessRecordAdjNodes.forEachNewNode(i, mComputeConnectionsConsumer);
+ // 2nd pass, scan each slot in the adj node list.
+ for (int i = 0, end = mProcessRecordAdjNodes.size() - 1; i < end; i++) {
+ mProcessRecordAdjNodes.forEachNewNode(i, mComputeConnectionsConsumer);
+ }
}
}
@@ -987,8 +1134,14 @@ public class OomAdjusterModernImpl extends OomAdjuster {
args.mApp = reachable;
computeOomAdjIgnoringReachablesLSP(args);
- updateProcStateSlot(reachable, prevProcState);
- updateAdjSlot(reachable, prevAdj);
+ if (Flags.simplifyProcessTraversal()) {
+ // Just add to the procState priority queue. The adj priority queue should be
+ // empty going into the traversal step.
+ mProcessRecordProcStateNodes.offer(reachable);
+ } else {
+ updateProcStateSlot(reachable, prevProcState);
+ updateAdjSlot(reachable, prevAdj);
+ }
}
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a5449a0f0431..6779f7a37f20 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -37,7 +37,6 @@ import static android.os.Process.startWebView;
import static android.system.OsConstants.EAGAIN;
import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxAudit;
-import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxInputSelector;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
@@ -2066,15 +2065,11 @@ public final class ProcessList {
}
}
- if (selinuxSdkSandboxInputSelector()) {
- return app.info.seInfo + extraInfo + TextUtils.emptyIfNull(app.info.seInfoUser);
- } else {
- return app.info.seInfo
- + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser)
- + extraInfo;
- }
+ return app.info.seInfo
+ + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) + extraInfo;
}
+
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 5793758d7a6e..9bf5c2174d2c 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -157,6 +157,7 @@ public class SettingsToPropertiesMapper {
"car_telemetry",
"codec_fwk",
"companion",
+ "com_android_adbd",
"content_protection",
"context_hub",
"core_experiments_team_internal",
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index b7108dfcbac3..afde4f71a95f 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -123,3 +123,14 @@ flag {
description: "Avoid OomAdjuster calculations for connections that won't change importance"
bug: "323376416"
}
+
+flag {
+ name: "simplify_process_traversal"
+ namespace: "backstage_power"
+ description: "Simplify the OomAdjuster's process traversal mechanism."
+ bug: "336178916"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index ad93f6fc8d9f..147c8d7853d4 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1110,12 +1110,12 @@ public class AppOpsService extends IAppOpsService.Stub {
final String changedPkg = changedPkgs[i];
// We trust packagemanager to insert matching uid and packageNames in the
// extras
- Set<String> devices;
+ Set<String> devices = new ArraySet<>();
+ devices.add(PERSISTENT_DEVICE_ID_DEFAULT);
+
if (mVirtualDeviceManagerInternal != null) {
- devices = mVirtualDeviceManagerInternal.getAllPersistentDeviceIds();
- } else {
- devices = new ArraySet<>();
- devices.add(PERSISTENT_DEVICE_ID_DEFAULT);
+ devices.addAll(
+ mVirtualDeviceManagerInternal.getAllPersistentDeviceIds());
}
for (String device: devices) {
notifyOpChanged(onModeChangedListeners, code, changedUid, changedPkg,
@@ -2609,12 +2609,10 @@ public class AppOpsService extends IAppOpsService.Stub {
ArrayList<ChangeRec> reports = ent.getValue();
for (int i=0; i<reports.size(); i++) {
ChangeRec rep = reports.get(i);
- Set<String> devices;
+ Set<String> devices = new ArraySet<>();
+ devices.add(PERSISTENT_DEVICE_ID_DEFAULT);
if (mVirtualDeviceManagerInternal != null) {
- devices = mVirtualDeviceManagerInternal.getAllPersistentDeviceIds();
- } else {
- devices = new ArraySet<>();
- devices.add(PERSISTENT_DEVICE_ID_DEFAULT);
+ devices.addAll(mVirtualDeviceManagerInternal.getAllPersistentDeviceIds());
}
for (String device: devices) {
mHandler.sendMessage(PooledLambda.obtainMessage(
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java b/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java
index eaa5e2a6befb..53e6bdb2ab5f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java
@@ -238,7 +238,7 @@ public class BiometricNotificationUtils {
showNotificationHelper(context, name, title, content, setupPendingIntent, setupAction,
notNowAction, Notification.CATEGORY_SYSTEM, channel, tag,
- Notification.VISIBILITY_SECRET, false);
+ Notification.VISIBILITY_SECRET, false, Notification.FLAG_NO_CLEAR);
}
private static String getFingerprintDanglingContentString(Context context,
@@ -296,13 +296,13 @@ public class BiometricNotificationUtils {
String notificationTag, int visibility, boolean listenToDismissEvent) {
showNotificationHelper(context, name, title, content, pendingIntent,
null /* positiveAction */, null /* negativeAction */, category, channelName,
- notificationTag, visibility, listenToDismissEvent);
+ notificationTag, visibility, listenToDismissEvent, 0);
}
private static void showNotificationHelper(Context context, String name, String title,
String content, PendingIntent pendingIntent, Notification.Action positiveAction,
Notification.Action negativeAction, String category, String channelName,
- String notificationTag, int visibility, boolean listenToDismissEvent) {
+ String notificationTag, int visibility, boolean listenToDismissEvent, int flags) {
Slog.v(TAG," listenToDismissEvent = " + listenToDismissEvent);
final PendingIntent dismissIntent = PendingIntent.getActivityAsUser(context,
0 /* requestCode */, DISMISS_FRR_INTENT, PendingIntent.FLAG_IMMUTABLE /* flags */,
@@ -324,6 +324,9 @@ public class BiometricNotificationUtils {
.setContentIntent(pendingIntent)
.setVisibility(visibility);
+ if (flags > 0) {
+ builder.setFlag(flags, true);
+ }
if (positiveAction != null) {
builder.addAction(positiveAction);
}
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 f809a49fd3d3..37b693190f7f 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
@@ -165,9 +165,8 @@ public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2
public boolean isAutoBrightnessValid() {
boolean isValid = false;
if (isAutoBrightnessEnabled()) {
- float brightness = (mAutomaticBrightnessController != null)
- ? mAutomaticBrightnessController.getAutomaticScreenBrightness(null)
- : PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ float brightness = getAutomaticScreenBrightness(null,
+ /* isAutomaticBrightnessAdjusted = */ false);
if (BrightnessUtils.isValidBrightnessValue(brightness)
|| brightness == PowerManager.BRIGHTNESS_OFF_FLOAT) {
isValid = true;
@@ -274,7 +273,12 @@ public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2
BrightnessReason brightnessReason = new BrightnessReason();
brightnessReason.setReason(BrightnessReason.REASON_AUTOMATIC);
BrightnessEvent brightnessEvent = mInjector.getBrightnessEvent(mDisplayId);
- float brightness = getAutomaticScreenBrightness(brightnessEvent);
+
+ // AutoBrightness adjustments were already applied while checking the validity of this
+ // strategy. Reapplying them again will result in incorrect adjustment reason flags as we
+ // might end up assuming no adjustments are applied
+ float brightness = getAutomaticScreenBrightness(brightnessEvent,
+ /* isAutomaticBrightnessAdjusted = */ true);
return new DisplayBrightnessState.Builder()
.setBrightness(brightness)
.setSdrBrightness(brightness)
@@ -355,11 +359,14 @@ public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2
* @param brightnessEvent Event object to populate with details about why the specific
* brightness was chosen.
*/
- public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
+ public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent,
+ boolean isAutomaticBrightnessAdjusted) {
float brightness = (mAutomaticBrightnessController != null)
? mAutomaticBrightnessController.getAutomaticScreenBrightness(brightnessEvent)
: PowerManager.BRIGHTNESS_INVALID_FLOAT;
- adjustAutomaticBrightnessStateIfValid(brightness);
+ if (!isAutomaticBrightnessAdjusted) {
+ adjustAutomaticBrightnessStateIfValid(brightness);
+ }
return brightness;
}
diff --git a/services/core/java/com/android/server/flags/pinner.aconfig b/services/core/java/com/android/server/flags/pinner.aconfig
index 16a45cd87fd7..2f817dbb9a7f 100644
--- a/services/core/java/com/android/server/flags/pinner.aconfig
+++ b/services/core/java/com/android/server/flags/pinner.aconfig
@@ -6,4 +6,11 @@ flag {
namespace: "system_performance"
description: "This flag controls if webview should be pinned in memory."
bug: "307594624"
+}
+
+flag {
+ name: "skip_home_art_pins"
+ namespace: "system_performance"
+ description: "Ablation study flag that controls if home app odex/vdex files should be pinned in memory."
+ bug: "340935152"
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8e85b81d9bd2..48cccd5b5b39 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -960,12 +960,6 @@ public class InputManagerService extends IInputManager.Stub
// Binder call
@Override
- public boolean isInputDeviceEnabled(int deviceId) {
- return mNative.isInputDeviceEnabled(deviceId);
- }
-
- // Binder call
- @Override
public void enableInputDevice(int deviceId) {
if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE,
"enableInputDevice()")) {
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 0208a325a1d5..a9d40bb54f96 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -183,8 +183,6 @@ interface NativeInputManagerService {
void monitor();
- boolean isInputDeviceEnabled(int deviceId);
-
void enableInputDevice(int deviceId);
void disableInputDevice(int deviceId);
@@ -463,9 +461,6 @@ interface NativeInputManagerService {
public native void monitor();
@Override
- public native boolean isInputDeviceEnabled(int deviceId);
-
- @Override
public native void enableInputDevice(int deviceId);
@Override
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index e862c7e96200..ad9995097639 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -39,6 +39,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Slog;
+import android.view.Display;
import android.view.WindowManager;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodInfo;
@@ -78,6 +79,7 @@ final class InputMethodBindingController {
@GuardedBy("ImfLock.class") @Nullable private IInputMethodInvoker mCurMethod;
@GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
@GuardedBy("ImfLock.class") @Nullable private IBinder mCurToken;
+ @GuardedBy("ImfLock.class") private int mCurTokenDisplayId = Display.INVALID_DISPLAY;
@GuardedBy("ImfLock.class") private int mCurSeq;
@GuardedBy("ImfLock.class") private boolean mVisibleBound;
@GuardedBy("ImfLock.class") private boolean mSupportsStylusHw;
@@ -193,6 +195,17 @@ final class InputMethodBindingController {
}
/**
+ * Returns the displayId associated with {@link #getCurToken()}.
+ *
+ * @return the displayId associated with {@link #getCurToken()}. {@link Display#INVALID_DISPLAY}
+ * while {@link #getCurToken()} returns {@code null}
+ */
+ @GuardedBy("ImfLock.class")
+ int getCurTokenDisplayId() {
+ return mCurTokenDisplayId;
+ }
+
+ /**
* The Intent used to connect to the current input method.
*/
@GuardedBy("ImfLock.class")
@@ -412,15 +425,14 @@ final class InputMethodBindingController {
@GuardedBy("ImfLock.class")
private void removeCurrentToken() {
- int curTokenDisplayId = mService.getCurTokenDisplayIdLocked();
-
if (DEBUG) {
Slog.v(TAG,
- "Removing window token: " + mCurToken + " for display: " + curTokenDisplayId);
+ "Removing window token: " + mCurToken + " for display: " + mCurTokenDisplayId);
}
mWindowManagerInternal.removeWindowToken(mCurToken, true /* removeWindows */,
- false /* animateExit */, curTokenDisplayId);
+ false /* animateExit */, mCurTokenDisplayId);
mCurToken = null;
+ mCurTokenDisplayId = Display.INVALID_DISPLAY;
}
@GuardedBy("ImfLock.class")
@@ -445,7 +457,7 @@ final class InputMethodBindingController {
final int displayIdToShowIme = mService.getDisplayIdToShowImeLocked();
mCurToken = new Binder();
- mService.setCurTokenDisplayIdLocked(displayIdToShowIme);
+ mCurTokenDisplayId = displayIdToShowIme;
if (DEBUG) {
Slog.v(TAG, "Adding window token: " + mCurToken + " for display: "
+ displayIdToShowIme);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index f8dda6073b0b..a43d6af136f7 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -603,18 +603,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
*/
@GuardedBy("ImfLock.class")
int getCurTokenDisplayIdLocked() {
- return mCurTokenDisplayId;
- }
-
- @GuardedBy("ImfLock.class")
- void setCurTokenDisplayIdLocked(int curTokenDisplayId) {
- mCurTokenDisplayId = curTokenDisplayId;
+ final var userData = mUserDataRepository.getOrCreate(mCurrentUserId);
+ return userData.mBindingController.getCurTokenDisplayId();
}
- @GuardedBy("ImfLock.class")
- @MultiUserUnawareField
- private int mCurTokenDisplayId = INVALID_DISPLAY;
-
/**
* The display ID of the input method indicates the fallback display which returned by
* {@link #computeImeDisplayIdForTarget}.
@@ -862,37 +854,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final class MyPackageMonitor extends PackageMonitor {
/**
- * Package names that are known to contain {@link InputMethodService}.
- *
- * <p>No need to include packages because of direct-boot unaware IMEs since we always rescan
- * all the packages when the user is unlocked, and direct-boot awareness will not be changed
- * dynamically unless the entire package is updated, which also always triggers package
- * rescanning.</p>
- */
- @GuardedBy("ImfLock.class")
- private final ArraySet<String> mKnownImePackageNames = new ArraySet<>();
-
- /**
- * Packages that are appeared, disappeared, or modified for whatever reason.
- *
- * <p>Note: For now we intentionally use {@link ArrayList} instead of {@link ArraySet}
- * because 1) the number of elements is almost always 1 or so, and 2) we do not care
- * duplicate elements for our use case.</p>
- *
- * <p>This object must be accessed only from callback methods in {@link PackageMonitor},
- * which should be bound to {@link #getRegisteredHandler()}.</p>
- */
- private final ArrayList<String> mChangedPackages = new ArrayList<>();
-
- /**
- * {@code true} if one or more packages that contain {@link InputMethodService} appeared.
- *
- * <p>This field must be accessed only from callback methods in {@link PackageMonitor},
- * which should be bound to {@link #getRegisteredHandler()}.</p>
- */
- private boolean mImePackageAppeared = false;
-
- /**
* Remembers package names passed to {@link #onPackageDataCleared(String, int)}.
*
* <p>This field must be accessed only from callback methods in {@link PackageMonitor},
@@ -905,16 +866,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- void clearKnownImePackageNamesLocked() {
- mKnownImePackageNames.clear();
- }
-
- @GuardedBy("ImfLock.class")
- void addKnownImePackageNameLocked(@NonNull String packageName) {
- mKnownImePackageNames.add(packageName);
- }
-
- @GuardedBy("ImfLock.class")
private boolean isChangingPackagesOfCurrentUserLocked() {
final int userId = getChangingUserId();
final boolean retval = userId == mCurrentUserId;
@@ -964,52 +915,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@Override
- public void onPackageAppeared(String packageName, int reason) {
- if (!mImePackageAppeared) {
- final PackageManager pm = mContext.getPackageManager();
- final List<ResolveInfo> services = pm.queryIntentServicesAsUser(
- new Intent(InputMethod.SERVICE_INTERFACE).setPackage(packageName),
- PackageManager.MATCH_DISABLED_COMPONENTS, getChangingUserId());
- // No need to lock this because we access it only on getRegisteredHandler().
- if (!services.isEmpty()) {
- mImePackageAppeared = true;
- }
- }
- // No need to lock this because we access it only on getRegisteredHandler().
- mChangedPackages.add(packageName);
- }
-
- @Override
- public void onPackageDisappeared(String packageName, int reason) {
- // No need to lock this because we access it only on getRegisteredHandler().
- mChangedPackages.add(packageName);
- }
-
- @Override
- public void onPackageModified(String packageName) {
- // No need to lock this because we access it only on getRegisteredHandler().
- mChangedPackages.add(packageName);
- }
-
- @Override
- public void onPackagesSuspended(String[] packages) {
- // No need to lock this because we access it only on getRegisteredHandler().
- for (String packageName : packages) {
- mChangedPackages.add(packageName);
- }
- }
-
- @Override
- public void onPackagesUnsuspended(String[] packages) {
- // No need to lock this because we access it only on getRegisteredHandler().
- for (String packageName : packages) {
- mChangedPackages.add(packageName);
- }
- }
-
- @Override
public void onPackageDataCleared(String packageName, int uid) {
- mChangedPackages.add(packageName);
mDataClearedPackages.add(packageName);
}
@@ -1021,32 +927,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private void clearPackageChangeState() {
// No need to lock them because we access these fields only on getRegisteredHandler().
- mChangedPackages.clear();
mDataClearedPackages.clear();
- mImePackageAppeared = false;
- }
-
- @GuardedBy("ImfLock.class")
- private boolean shouldRebuildInputMethodListLocked() {
- // This method is guaranteed to be called only by getRegisteredHandler().
-
- // If there is any new package that contains at least one IME, then rebuilt the list
- // of IMEs.
- if (mImePackageAppeared) {
- return true;
- }
-
- // Otherwise, check if mKnownImePackageNames and mChangedPackages have any intersection.
- // TODO: Consider to create a utility method to do the following test. List.retainAll()
- // is an option, but it may still do some extra operations that we do not need here.
- final int numPackages = mChangedPackages.size();
- for (int i = 0; i < numPackages; ++i) {
- final String packageName = mChangedPackages.get(i);
- if (mKnownImePackageNames.contains(packageName)) {
- return true;
- }
- }
- return false;
}
private void onFinishPackageChangesInternal() {
@@ -1107,12 +988,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
AdditionalSubtypeMapRepository.putAndSave(userId, newAdditionalSubtypeMap,
settings.getMethodMap());
}
- if (isCurrentUser
- && !(additionalSubtypeChanged || shouldRebuildInputMethodListLocked())) {
- return;
- }
+
final var newMethodMap = newMethodMapWithoutAdditionalSubtypes
.applyAdditionalSubtypes(newAdditionalSubtypeMap);
+
+ if (InputMethodMap.areSame(settings.getMethodMap(), newMethodMap)) {
+ // No update in the actual IME map.
+ return;
+ }
+
final InputMethodSettings newSettings =
InputMethodSettings.create(newMethodMap, userId);
InputMethodSettingsRepository.put(userId, newSettings);
@@ -1243,6 +1127,11 @@ 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) {
+ // In concurrent multi-user mode, we in general do not rely on the concept of
+ // current user.
+ return;
+ }
mService.scheduleSwitchUserTaskLocked(to.getUserIdentifier(),
/* clientToBeReset= */ null);
}
@@ -1268,9 +1157,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@Override
public void onUserStarting(TargetUser user) {
// Called on ActivityManager thread.
- SecureSettingsWrapper.onUserStarting(user.getUserIdentifier());
+ final int userId = user.getUserIdentifier();
+ SecureSettingsWrapper.onUserStarting(userId);
synchronized (ImfLock.class) {
- mService.mUserDataRepository.getOrCreate(user.getUserIdentifier());
+ mService.mUserDataRepository.getOrCreate(userId);
+ if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
+ if (mService.mCurrentUserId != userId) {
+ mService.experimentalInitializeVisibleBackgroundUserLocked(userId);
+ }
+ }
}
}
@@ -1291,6 +1186,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// We need to rebuild IMEs.
postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
updateInputMethodsFromSettingsLocked(true /* enabledChanged */);
+ } else if (mExperimentalConcurrentMultiUserModeEnabled) {
+ experimentalInitializeVisibleBackgroundUserLocked(userId);
}
}
}
@@ -2140,7 +2037,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@StartInputReason int startInputReason,
int unverifiedTargetSdkVersion,
@NonNull ImeOnBackInvokedDispatcher imeDispatcher,
- @NonNull UserDataRepository.UserData userData) {
+ @NonNull InputMethodBindingController bindingController) {
// Compute the final shown display ID with validated cs.selfReportedDisplayId for this
// session & other conditions.
@@ -2181,7 +2078,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final boolean connectionWasActive = mCurInputConnection != null;
// Bump up the sequence for this client and attach it.
- final var bindingController = userData.mBindingController;
bindingController.advanceSequenceNumber();
mCurClient = cs;
@@ -2241,7 +2137,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
(startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0);
}
- InputBindResult bindResult = tryReuseConnectionLocked(userData, cs);
+ InputBindResult bindResult = tryReuseConnectionLocked(bindingController, cs);
if (bindResult != null) {
return bindResult;
}
@@ -2355,9 +2251,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
@Nullable
- private InputBindResult tryReuseConnectionLocked(@NonNull UserDataRepository.UserData userData,
- @NonNull ClientState cs) {
- final var bindingController = userData.mBindingController;
+ private InputBindResult tryReuseConnectionLocked(
+ @NonNull InputMethodBindingController bindingController, @NonNull ClientState cs) {
if (bindingController.hasMainConnection()) {
if (getCurMethodLocked() != null) {
// Return to client, and we will get back with it when
@@ -2505,7 +2400,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mImeWindowVis = 0;
mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
updateSystemUiLocked(mImeWindowVis, mBackDisposition);
- mCurTokenDisplayId = INVALID_DISPLAY;
mAutofillController.onResetSystemUi();
}
@@ -2927,6 +2821,49 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mMenuController.updateKeyboardFromSettingsLocked();
}
+ /**
+ * This is an experimental implementation used when and only when
+ * {@link #mExperimentalConcurrentMultiUserModeEnabled}.
+ *
+ * <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
+ * {@link #updateInputMethodsFromSettingsLocked(boolean)}.</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 #mDeviceIdToShowIme} is ignored.</li>
+ * <li>{@link #mSwitchingController} is ignored.</li>
+ * <li>{@link #mHardwareKeyboardShortcutController} is ignored.</li>
+ * <li>{@link #mPreventImeStartupUnlessTextEditor} is ignored.</li>
+ * <li>and so on.</li>
+ * </ul>
+ */
+ @GuardedBy("ImfLock.class")
+ void experimentalInitializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
+ if (!mUserManagerInternal.isUserVisible(userId)) {
+ return;
+ }
+ final var settings = InputMethodSettingsRepository.get(userId);
+ String id = settings.getSelectedInputMethod();
+ if (TextUtils.isEmpty(id)) {
+ final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
+ settings.getEnabledInputMethodList());
+ if (imi == null) {
+ return;
+ }
+ id = imi.getId();
+ settings.putSelectedInputMethod(id);
+ }
+ final var userData = mUserDataRepository.getOrCreate(userId);
+ final var bindingController = userData.mBindingController;
+ bindingController.setSelectedMethodId(id);
+ }
+
@GuardedBy("ImfLock.class")
void updateInputMethodsFromSettingsLocked(boolean enabledMayChange) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
@@ -3619,7 +3556,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final long ident = Binder.clearCallingIdentity();
try {
// Verify if IMMS is in the process of switching user.
- if (mUserSwitchHandlerTask != null) {
+ if (!mExperimentalConcurrentMultiUserModeEnabled
+ && mUserSwitchHandlerTask != null) {
// There is already an on-going pending user switch task.
final int nextUserId = mUserSwitchHandlerTask.mToUserId;
if (userId == nextUserId) {
@@ -3673,7 +3611,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
// Verify if caller is a background user.
- if (userId != mCurrentUserId) {
+ if (!mExperimentalConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
if (ArrayUtils.contains(
mUserManagerInternal.getProfileIds(mCurrentUserId, false),
userId)) {
@@ -3701,7 +3639,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
result = startInputOrWindowGainedFocusInternalLocked(startInputReason,
client, windowToken, startInputFlags, softInputMode, windowFlags,
editorInfo, inputConnection, remoteAccessibilityInputConnection,
- unverifiedTargetSdkVersion, userData, imeDispatcher, cs);
+ unverifiedTargetSdkVersion, bindingController, imeDispatcher, cs);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3729,7 +3667,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SoftInputModeFlags int softInputMode, int windowFlags, EditorInfo editorInfo,
IRemoteInputConnection inputContext,
@Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion, @NonNull UserDataRepository.UserData userData,
+ int unverifiedTargetSdkVersion, @NonNull InputMethodBindingController bindingController,
@NonNull ImeOnBackInvokedDispatcher imeDispatcher, @NonNull ClientState cs) {
if (DEBUG) {
Slog.v(TAG, "startInputOrWindowGainedFocusInternalLocked: reason="
@@ -3742,7 +3680,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
+ " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
+ " windowFlags=#" + Integer.toHexString(windowFlags)
+ " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion
- + " userData=" + userData
+ + " bindingController=" + bindingController
+ " imeDispatcher=" + imeDispatcher
+ " cs=" + cs);
}
@@ -3771,15 +3709,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (editorInfo != null) {
return startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, editorInfo, startInputFlags,
- startInputReason, unverifiedTargetSdkVersion, imeDispatcher, userData);
+ startInputReason, unverifiedTargetSdkVersion, imeDispatcher,
+ bindingController);
}
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
null, null, null, null, -1, false);
}
- mImeBindingState = new ImeBindingState(userData.mUserId, windowToken, softInputMode, cs,
- editorInfo);
+ mImeBindingState = new ImeBindingState(bindingController.mUserId, windowToken,
+ softInputMode, cs, editorInfo);
mFocusedWindowPerceptible.put(windowToken, true);
// We want to start input before showing the IME, but after closing
@@ -3804,7 +3743,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, editorInfo, startInputFlags,
startInputReason, unverifiedTargetSdkVersion,
- imeDispatcher, userData);
+ imeDispatcher, bindingController);
didStart = true;
}
break;
@@ -3819,7 +3758,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// Note that we can trust client's display ID as long as it matches
// to the display ID obtained from the window.
if (cs.mSelfReportedDisplayId != getCurTokenDisplayIdLocked()) {
- userData.mBindingController.unbindCurrentMethod();
+ bindingController.unbindCurrentMethod();
}
}
}
@@ -3828,7 +3767,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, editorInfo, startInputFlags,
startInputReason, unverifiedTargetSdkVersion,
- imeDispatcher, userData);
+ imeDispatcher, bindingController);
} else {
res = InputBindResult.NULL_EDITOR_INFO;
}
@@ -4372,11 +4311,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private static IntArray getStylusInputDeviceIds(InputManager im) {
IntArray stylusIds = new IntArray();
for (int id : im.getInputDeviceIds()) {
- if (!im.isInputDeviceEnabled(id)) {
- continue;
- }
InputDevice device = im.getInputDevice(id);
- if (device != null && isStylusDevice(device)) {
+ if (device != null && device.isEnabled() && isStylusDevice(device)) {
stylusIds.add(id);
}
}
@@ -5077,30 +5013,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
return;
}
mMethodMapUpdateCount++;
- mMyPackageMonitor.clearKnownImePackageNamesLocked();
final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
- // Construct the set of possible IME packages for onPackageChanged() to avoid false
- // negatives when the package state remains to be the same but only the component state is
- // changed.
- {
- // Here we intentionally use PackageManager.MATCH_DISABLED_COMPONENTS since the purpose
- // of this query is to avoid false negatives. PackageManager.MATCH_ALL could be more
- // conservative, but it seems we cannot use it for now (Issue 35176630).
- final List<ResolveInfo> allInputMethodServices =
- mContext.getPackageManager().queryIntentServicesAsUser(
- new Intent(InputMethod.SERVICE_INTERFACE),
- PackageManager.MATCH_DISABLED_COMPONENTS, settings.getUserId());
- final int numImes = allInputMethodServices.size();
- for (int i = 0; i < numImes; ++i) {
- final ServiceInfo si = allInputMethodServices.get(i).serviceInfo;
- if (android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
- mMyPackageMonitor.addKnownImePackageNameLocked(si.packageName);
- }
- }
- }
-
boolean reenableMinimumNonAuxSystemImes = false;
// TODO: The following code should find better place to live.
if (!resetDefaultEnabledIme) {
@@ -6456,8 +6371,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
continue;
}
// Skip on headless user
- if (USER_TYPE_SYSTEM_HEADLESS.equals(
- mUserManagerInternal.getUserInfo(userId).userType)) {
+ final var userInfo = mUserManagerInternal.getUserInfo(userId);
+ if (userInfo != null && USER_TYPE_SYSTEM_HEADLESS.equals(userInfo.userType)) {
continue;
}
final String nextIme;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMap.java b/services/core/java/com/android/server/inputmethod/InputMethodMap.java
index f06643df7491..bab21e8b7b06 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMap.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMap.java
@@ -110,7 +110,7 @@ final class InputMethodMap {
* @return {@code true} if both {@link InputMethodMap} instances contain exactly the same data
*/
@AnyThread
- static boolean equals(@NonNull InputMethodMap map1, @NonNull InputMethodMap map2) {
+ static boolean areSame(@NonNull InputMethodMap map1, @NonNull InputMethodMap map2) {
if (map1 == map2) {
return true;
}
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 17f8abe14ea0..b3fb147a318b 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -317,9 +317,6 @@ public class ContextHubService extends IContextHubService.Stub {
*/
private static final int MAX_PROBABILITY_PERCENT = 100;
- /**
- * Random number generator.
- */
private Random mRandom = new Random();
/**
@@ -998,50 +995,75 @@ public class ContextHubService extends IContextHubService.Stub {
return;
}
- if (message.isReliable()) {
- byte errorCode = ErrorCode.OK;
- synchronized (mReliableMessageRecordQueue) {
- Optional<ReliableMessageRecord> record = Optional.empty();
- for (ReliableMessageRecord r: mReliableMessageRecordQueue) {
- if (r.getContextHubId() == contextHubId
- && r.getMessageSequenceNumber() == message.getMessageSequenceNumber()) {
- record = Optional.of(r);
- break;
- }
- }
+ if (!message.isReliable()) {
+ mClientManager.onMessageFromNanoApp(
+ contextHubId, hostEndpointId, message,
+ nanoappPermissions, messagePermissions);
+ cleanupReliableMessageRecordQueue();
+ return;
+ }
- if (record.isPresent()) {
- errorCode = record.get().getErrorCode();
- if (errorCode == ErrorCode.TRANSIENT_ERROR) {
- Log.w(TAG, "Found duplicate reliable message with message sequence number: "
- + record.get().getMessageSequenceNumber() + ": retrying");
- errorCode = mClientManager.onMessageFromNanoApp(
- contextHubId, hostEndpointId, message,
- nanoappPermissions, messagePermissions);
- record.get().setErrorCode(errorCode);
- } else {
- Log.w(TAG, "Found duplicate reliable message with message sequence number: "
- + record.get().getMessageSequenceNumber());
- }
- } else {
+ byte errorCode = ErrorCode.OK;
+ synchronized (mReliableMessageRecordQueue) {
+ Optional<ReliableMessageRecord> record =
+ findReliableMessageRecord(contextHubId,
+ message.getMessageSequenceNumber());
+
+ if (record.isPresent()) {
+ errorCode = record.get().getErrorCode();
+ if (errorCode == ErrorCode.TRANSIENT_ERROR) {
+ Log.w(TAG, "Found duplicate reliable message with message sequence number: "
+ + record.get().getMessageSequenceNumber() + ": retrying");
errorCode = mClientManager.onMessageFromNanoApp(
contextHubId, hostEndpointId, message,
nanoappPermissions, messagePermissions);
- mReliableMessageRecordQueue.add(
- new ReliableMessageRecord(contextHubId,
- SystemClock.elapsedRealtimeNanos(),
- message.getMessageSequenceNumber(),
- errorCode));
+ record.get().setErrorCode(errorCode);
+ } else {
+ Log.w(TAG, "Found duplicate reliable message with message sequence number: "
+ + record.get().getMessageSequenceNumber());
}
+ } else {
+ errorCode = mClientManager.onMessageFromNanoApp(
+ contextHubId, hostEndpointId, message,
+ nanoappPermissions, messagePermissions);
+ mReliableMessageRecordQueue.add(
+ new ReliableMessageRecord(contextHubId,
+ SystemClock.elapsedRealtimeNanos(),
+ message.getMessageSequenceNumber(),
+ errorCode));
+ }
+ }
+
+ sendMessageDeliveryStatusToContextHub(contextHubId,
+ message.getMessageSequenceNumber(), errorCode);
+ cleanupReliableMessageRecordQueue();
+ }
+
+ /**
+ * Finds a reliable message record in the queue that matches the given
+ * context hub ID and message sequence number. This function assumes
+ * the caller is synchronized on mReliableMessageRecordQueue.
+ *
+ * @param contextHubId the ID of the hub
+ * @param messageSequenceNumber the message sequence number
+ *
+ * @return the record if found, or empty if not found
+ */
+ private Optional<ReliableMessageRecord> findReliableMessageRecord(
+ int contextHubId, int messageSequenceNumber) {
+ for (ReliableMessageRecord record: mReliableMessageRecordQueue) {
+ if (record.getContextHubId() == contextHubId
+ && record.getMessageSequenceNumber() == messageSequenceNumber) {
+ return Optional.of(record);
}
- sendMessageDeliveryStatusToContextHub(contextHubId,
- message.getMessageSequenceNumber(), errorCode);
- } else {
- mClientManager.onMessageFromNanoApp(
- contextHubId, hostEndpointId, message,
- nanoappPermissions, messagePermissions);
}
+ return Optional.empty();
+ }
+ /**
+ * Removes old entries from the reliable message record queue.
+ */
+ private void cleanupReliableMessageRecordQueue() {
synchronized (mReliableMessageRecordQueue) {
while (mReliableMessageRecordQueue.peek() != null
&& mReliableMessageRecordQueue.peek().isExpired()) {
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index a7fd750e4037..386657e99e36 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -81,6 +81,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
MediaRoute2ProviderServiceProxy(
@NonNull Context context,
+ @NonNull Looper looper,
@NonNull ComponentName componentName,
boolean isSelfScanOnlyProvider,
int userId) {
@@ -88,7 +89,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
mContext = Objects.requireNonNull(context, "Context must not be null.");
mIsSelfScanOnlyProvider = isSelfScanOnlyProvider;
mUserId = userId;
- mHandler = new Handler(Looper.myLooper());
+ mHandler = new Handler(looper);
}
public void setManagerScanning(boolean managerScanning) {
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
index 178eb717f271..7c1a5e113a5e 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -142,6 +142,7 @@ final class MediaRoute2ProviderWatcher {
MediaRoute2ProviderServiceProxy proxy =
new MediaRoute2ProviderServiceProxy(
mContext,
+ mHandler.getLooper(),
new ComponentName(serviceInfo.packageName, serviceInfo.name),
isSelfScanOnlyProvider,
mUserId);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index e1f893953d66..c03497e629f0 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -404,37 +404,17 @@ class MediaRouter2ServiceImpl {
long managerRequestId,
@NonNull RoutingSessionInfo oldSession,
@NonNull MediaRoute2Info route,
- Bundle sessionHints,
- @Nullable UserHandle transferInitiatorUserHandle,
- @Nullable String transferInitiatorPackageName) {
+ Bundle sessionHints) {
Objects.requireNonNull(router, "router must not be null");
Objects.requireNonNull(oldSession, "oldSession must not be null");
Objects.requireNonNull(route, "route must not be null");
- synchronized (mLock) {
- if (managerRequestId == MediaRoute2ProviderService.REQUEST_ID_NONE
- || transferInitiatorUserHandle == null
- || transferInitiatorPackageName == null) {
- final IBinder binder = router.asBinder();
- final RouterRecord routerRecord = mAllRouterRecords.get(binder);
-
- transferInitiatorUserHandle = Binder.getCallingUserHandle();
- if (routerRecord != null) {
- transferInitiatorPackageName = routerRecord.mPackageName;
- } else {
- transferInitiatorPackageName = mContext.getPackageName();
- }
- }
- }
-
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
requestCreateSessionWithRouter2Locked(
requestId,
managerRequestId,
- transferInitiatorUserHandle,
- transferInitiatorPackageName,
router,
oldSession,
route,
@@ -1281,8 +1261,6 @@ class MediaRouter2ServiceImpl {
private void requestCreateSessionWithRouter2Locked(
int requestId,
long managerRequestId,
- @NonNull UserHandle transferInitiatorUserHandle,
- @NonNull String transferInitiatorPackageName,
@NonNull IMediaRouter2 router,
@NonNull RoutingSessionInfo oldSession,
@NonNull MediaRoute2Info route,
@@ -1355,8 +1333,6 @@ class MediaRouter2ServiceImpl {
userHandler,
uniqueRequestId,
managerRequestId,
- transferInitiatorUserHandle,
- transferInitiatorPackageName,
routerRecord,
oldSession,
route,
@@ -2695,11 +2671,7 @@ class MediaRouter2ServiceImpl {
route = mSystemProvider.getDefaultRoute();
}
routerRecord.mRouter.requestCreateSessionByManager(
- uniqueRequestId,
- oldSession,
- route,
- transferInitiatorUserHandle,
- transferInitiatorPackageName);
+ uniqueRequestId, oldSession, route);
} catch (RemoteException ex) {
Slog.w(TAG, "getSessionHintsForCreatingSessionOnHandler: "
+ "Failed to request. Router probably died.", ex);
@@ -2711,8 +2683,6 @@ class MediaRouter2ServiceImpl {
private void requestCreateSessionWithRouter2OnHandler(
long uniqueRequestId,
long managerRequestId,
- @NonNull UserHandle transferInitiatorUserHandle,
- @NonNull String transferInitiatorPackageName,
@NonNull RouterRecord routerRecord,
@NonNull RoutingSessionInfo oldSession,
@NonNull MediaRoute2Info route,
@@ -2732,10 +2702,10 @@ class MediaRouter2ServiceImpl {
managerRequestId, oldSession, route);
mSessionCreationRequests.add(request);
- int transferReason = RoutingSessionInfo.TRANSFER_REASON_APP;
- if (managerRequestId != MediaRoute2ProviderService.REQUEST_ID_NONE) {
- transferReason = RoutingSessionInfo.TRANSFER_REASON_SYSTEM_REQUEST;
- }
+ int transferReason =
+ managerRequestId != MediaRoute2ProviderService.REQUEST_ID_NONE
+ ? RoutingSessionInfo.TRANSFER_REASON_SYSTEM_REQUEST
+ : RoutingSessionInfo.TRANSFER_REASON_APP;
provider.requestCreateSession(
uniqueRequestId,
@@ -2743,8 +2713,8 @@ class MediaRouter2ServiceImpl {
route.getOriginalId(),
sessionHints,
transferReason,
- transferInitiatorUserHandle,
- transferInitiatorPackageName);
+ UserHandle.of(routerRecord.mUserRecord.mUserId),
+ routerRecord.mPackageName);
}
// routerRecord can be null if the session is system's or RCN.
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 064443ce7d10..192ac6287884 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -495,18 +495,9 @@ public final class MediaRouterService extends IMediaRouterService.Stub
long managerRequestId,
RoutingSessionInfo oldSession,
MediaRoute2Info route,
- Bundle sessionHints,
- @Nullable UserHandle transferInitiatorUserHandle,
- @Nullable String transferInitiatorPackageName) {
+ Bundle sessionHints) {
mService2.requestCreateSessionWithRouter2(
- router,
- requestId,
- managerRequestId,
- oldSession,
- route,
- sessionHints,
- transferInitiatorUserHandle,
- transferInitiatorPackageName);
+ router, requestId, managerRequestId, oldSession, route, sessionHints);
}
// Binder call
diff --git a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
index b2e861cf2876..dd7603714718 100644
--- a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
+++ b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.ondeviceintelligence;
+import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.DEVICE_CONFIG_UPDATE_BUNDLE_KEY;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_LOADED_BUNDLE_KEY;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_UNLOADED_BUNDLE_KEY;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.REGISTER_MODEL_UPDATE_CALLBACK_BUNDLE_KEY;
@@ -115,9 +116,10 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
/** Handler message to {@link #resetTemporaryServices()} */
private static final int MSG_RESET_TEMPORARY_SERVICE = 0;
-
/** Handler message to clean up temporary broadcast keys. */
private static final int MSG_RESET_BROADCAST_KEYS = 1;
+ /** Handler message to clean up temporary config namespace. */
+ private static final int MSG_RESET_CONFIG_NAMESPACE = 2;
/** Default value in absence of {@link DeviceConfig} override. */
private static final boolean DEFAULT_SERVICE_ENABLED = true;
@@ -129,6 +131,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
private final Executor resourceClosingExecutor = Executors.newCachedThreadPool();
private final Executor callbackExecutor = Executors.newCachedThreadPool();
private final Executor broadcastExecutor = Executors.newCachedThreadPool();
+ private final Executor mConfigExecutor = Executors.newCachedThreadPool();
private final Context mContext;
@@ -145,6 +148,12 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
private String[] mTemporaryBroadcastKeys;
@GuardedBy("mLock")
private String mBroadcastPackageName;
+ @GuardedBy("mLock")
+ private String mTemporaryConfigNamespace;
+
+ private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
+ this::sendUpdatedConfig;
+
/**
* Handler used to reset the temporary service names.
@@ -593,12 +602,14 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
@NonNull IOnDeviceSandboxedInferenceService service) {
try {
ensureRemoteIntelligenceServiceInitialized();
+ service.registerRemoteStorageService(
+ getIRemoteStorageService());
mRemoteOnDeviceIntelligenceService.run(
IOnDeviceIntelligenceService::notifyInferenceServiceConnected);
broadcastExecutor.execute(
() -> registerModelLoadingBroadcasts(service));
- service.registerRemoteStorageService(
- getIRemoteStorageService());
+ mConfigExecutor.execute(
+ () -> registerDeviceConfigChangeListener());
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to send connected event", ex);
}
@@ -658,6 +669,56 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
}
}
+ private void registerDeviceConfigChangeListener() {
+ Log.d(TAG, "registerDeviceConfigChangeListener");
+ String configNamespace = getConfigNamespace();
+ if (configNamespace.isEmpty()) {
+ Slog.e(TAG, "config_defaultOnDeviceIntelligenceDeviceConfigNamespace is empty");
+ return;
+ }
+ DeviceConfig.addOnPropertiesChangedListener(
+ configNamespace,
+ mConfigExecutor,
+ mOnPropertiesChangedListener);
+ }
+
+ private String getConfigNamespace() {
+ synchronized (mLock) {
+ if (mTemporaryConfigNamespace != null) {
+ return mTemporaryConfigNamespace;
+ }
+
+ return mContext.getResources().getString(
+ R.string.config_defaultOnDeviceIntelligenceDeviceConfigNamespace);
+ }
+ }
+
+ private void sendUpdatedConfig(
+ DeviceConfig.Properties props) {
+ Log.d(TAG, "sendUpdatedConfig");
+
+ PersistableBundle persistableBundle = new PersistableBundle();
+ for (String key : props.getKeyset()) {
+ persistableBundle.putString(key, props.getString(key, ""));
+ }
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(DEVICE_CONFIG_UPDATE_BUNDLE_KEY, persistableBundle);
+ ensureRemoteInferenceServiceInitialized();
+ mRemoteInferenceService.run(service -> service.updateProcessingState(bundle,
+ new IProcessingUpdateStatusCallback.Stub() {
+ @Override
+ public void onSuccess(PersistableBundle result) {
+ Slog.d(TAG, "Config update successful." + result);
+ }
+
+ @Override
+ public void onFailure(int errorCode, String errorMessage) {
+ Slog.e(TAG, "Config update failed with code ["
+ + String.valueOf(errorCode) + "] and message = " + errorMessage);
+ }
+ }));
+ }
+
@NonNull
private IRemoteStorageService.Stub getIRemoteStorageService() {
return new IRemoteStorageService.Stub() {
@@ -849,8 +910,23 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
}
@RequiresPermission(Manifest.permission.USE_ON_DEVICE_INTELLIGENCE)
+ public void setTemporaryDeviceConfigNamespace(@NonNull String configNamespace,
+ int durationMs) {
+ Objects.requireNonNull(configNamespace);
+ enforceShellOnly(Binder.getCallingUid(), "setTemporaryDeviceConfigNamespace");
+ mContext.enforceCallingPermission(
+ Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
+ synchronized (mLock) {
+ mTemporaryConfigNamespace = configNamespace;
+ if (durationMs != -1) {
+ getTemporaryHandler().sendEmptyMessageDelayed(MSG_RESET_CONFIG_NAMESPACE,
+ durationMs);
+ }
+ }
+ }
+
+ @RequiresPermission(Manifest.permission.USE_ON_DEVICE_INTELLIGENCE)
public void resetTemporaryServices() {
- enforceShellOnly(Binder.getCallingUid(), "resetTemporaryServices");
mContext.enforceCallingPermission(
Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
synchronized (mLock) {
@@ -937,17 +1013,17 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
@Override
public void handleMessage(Message msg) {
- if (msg.what == MSG_RESET_TEMPORARY_SERVICE) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (msg.what == MSG_RESET_TEMPORARY_SERVICE) {
resetTemporaryServices();
- }
- } else if (msg.what == MSG_RESET_BROADCAST_KEYS) {
- synchronized (mLock) {
+ } else if (msg.what == MSG_RESET_BROADCAST_KEYS) {
mTemporaryBroadcastKeys = null;
mBroadcastPackageName = SYSTEM_PACKAGE;
+ } else if (msg.what == MSG_RESET_CONFIG_NAMESPACE) {
+ mTemporaryConfigNamespace = null;
+ } else {
+ Slog.wtf(TAG, "invalid handler msg: " + msg);
}
- } else {
- Slog.wtf(TAG, "invalid handler msg: " + msg);
}
}
};
diff --git a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java
index 5744b5c3c2c4..d2c84fa1b18a 100644
--- a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java
+++ b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java
@@ -17,6 +17,7 @@
package com.android.server.ondeviceintelligence;
import android.annotation.NonNull;
+import android.os.Binder;
import android.os.ShellCommand;
import java.io.PrintWriter;
@@ -45,6 +46,8 @@ final class OnDeviceIntelligenceShellCommand extends ShellCommand {
return getConfiguredServices();
case "set-model-broadcasts":
return setBroadcastKeys();
+ case "set-deviceconfig-namespace":
+ return setDeviceConfigNamespace();
default:
return handleDefaultCommands(cmd);
}
@@ -69,6 +72,10 @@ final class OnDeviceIntelligenceShellCommand extends ShellCommand {
+ "[ReceiverPackageName] "
+ "[DURATION] To set the names of broadcast intent keys that are to be "
+ "emitted for cts tests.");
+ pw.println(
+ " set-deviceconfig-namespace [DeviceConfigNamespace] "
+ + "[DURATION] To set the device config namespace "
+ + "to use for cts tests.");
}
private int setTemporaryServices() {
@@ -78,6 +85,8 @@ final class OnDeviceIntelligenceShellCommand extends ShellCommand {
if (getRemainingArgsCount() == 0 && intelligenceServiceName == null
&& inferenceServiceName == null) {
+ OnDeviceIntelligenceManagerService.enforceShellOnly(Binder.getCallingUid(),
+ "resetTemporaryServices");
mService.resetTemporaryServices();
out.println("OnDeviceIntelligenceManagerService temporary reset. ");
return 0;
@@ -120,4 +129,16 @@ final class OnDeviceIntelligenceShellCommand extends ShellCommand {
return 0;
}
+ private int setDeviceConfigNamespace() {
+ final PrintWriter out = getOutPrintWriter();
+ final String configNamespace = getNextArg();
+
+ final int duration = Integer.parseInt(getNextArgRequired());
+ mService.setTemporaryDeviceConfigNamespace(configNamespace, duration);
+ out.println("OnDeviceIntelligence DeviceConfig Namespace temporarily set to "
+ + configNamespace
+ + " for " + duration + "ms");
+ return 0;
+ }
+
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/PackageFreezer.java b/services/core/java/com/android/server/pm/PackageFreezer.java
index 7c5615771607..0afda4598bcb 100644
--- a/services/core/java/com/android/server/pm/PackageFreezer.java
+++ b/services/core/java/com/android/server/pm/PackageFreezer.java
@@ -18,6 +18,7 @@ package com.android.server.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.Flags;
import android.content.pm.PackageManager;
import dalvik.system.CloseGuard;
@@ -76,8 +77,13 @@ final class PackageFreezer implements AutoCloseable {
ps = mPm.mSettings.getPackageLPr(mPackageName);
}
if (ps != null) {
- mPm.killApplication(ps.getPackageName(), ps.getAppId(), userId, killReason,
- exitInfoReason);
+ if (Flags.waitApplicationKilled()) {
+ mPm.killApplicationSync(ps.getPackageName(), ps.getAppId(), userId, killReason,
+ exitInfoReason);
+ } else {
+ mPm.killApplication(ps.getPackageName(), ps.getAppId(), userId, killReason,
+ exitInfoReason);
+ }
}
mCloseGuard.open("close");
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fda8535913d5..f8fceda0582c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -53,6 +53,7 @@ import android.annotation.StringRes;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.ApplicationExitInfo;
import android.app.ApplicationPackageManager;
@@ -3132,6 +3133,20 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
}
+ void killApplicationSync(String pkgName, @AppIdInt int appId,
+ @UserIdInt int userId, String reason, int exitInfoReason) {
+ ActivityManagerInternal mAmi = LocalServices.getService(ActivityManagerInternal.class);
+ if (mAmi != null) {
+ if (Thread.holdsLock(mLock)) {
+ // holds PM's lock, go back killApplication to avoid it run into watchdog reset.
+ Slog.e(TAG, "Holds PM's locker, unable kill application synchronized");
+ killApplication(pkgName, appId, userId, reason, exitInfoReason);
+ } else {
+ mAmi.killApplicationSync(pkgName, appId, userId, reason, exitInfoReason);
+ }
+ }
+ }
+
@Override
public void notifyPackageAdded(String packageName, int uid) {
mPackageObserverHelper.notifyAdded(packageName, uid);
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 23ae98325cb9..6700f00a8856 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -1252,7 +1252,7 @@ public class PackageManagerServiceUtils {
}
final ParsedMainComponent comp = componentInfoToComponent(
resolveInfo.getComponentInfo(), resolver, isReceiver);
- if (!comp.getIntents().isEmpty() && intent.getAction() == null) {
+ if (comp != null && !comp.getIntents().isEmpty() && intent.getAction() == null) {
match = false;
}
} else if (c instanceof IntentFilter) {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 5fa8856f2940..11b9e776204c 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -64,6 +64,7 @@ import com.android.server.LocalServices;
import com.android.server.input.InputManagerInternal;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.feature.PowerManagerFlags;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
@@ -187,11 +188,16 @@ public class Notifier {
private final AtomicBoolean mIsPlayingChargingStartedFeedback = new AtomicBoolean(false);
+ private final Injector mInjector;
+
+ private final PowerManagerFlags mFlags;
+
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
- Executor backgroundExecutor) {
+ Executor backgroundExecutor, PowerManagerFlags powerManagerFlags, Injector injector) {
mContext = context;
+ mFlags = powerManagerFlags;
mBatteryStats = batteryStats;
mAppOps = mContext.getSystemService(AppOpsManager.class);
mSuspendBlocker = suspendBlocker;
@@ -224,8 +230,8 @@ public class Notifier {
mShowWirelessChargingAnimationConfig = context.getResources().getBoolean(
com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim);
- mWakeLockLog = new WakeLockLog(context);
-
+ mInjector = (injector == null) ? new RealInjector() : injector;
+ mWakeLockLog = mInjector.getWakeLockLog(context);
// Initialize interactive state for battery stats.
try {
mBatteryStats.noteInteractive(true);
@@ -267,7 +273,7 @@ public class Notifier {
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
- notifyWakeLockListener(callback, tag, true);
+ notifyWakeLockListener(callback, tag, true, ownerUid, flags);
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
@@ -287,8 +293,9 @@ public class Notifier {
}
}
- mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags);
-
+ if (!mFlags.improveWakelockLatency()) {
+ mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, /*eventTime=*/ -1);
+ }
mWakefulnessSessionObserver.onWakeLockAcquired(flags);
}
@@ -406,7 +413,7 @@ public class Notifier {
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
- notifyWakeLockListener(callback, tag, false);
+ notifyWakeLockListener(callback, tag, false, ownerUid, flags);
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
@@ -422,8 +429,9 @@ public class Notifier {
// Ignore
}
}
- mWakeLockLog.onWakeLockReleased(tag, ownerUid);
-
+ if (!mFlags.improveWakelockLatency()) {
+ mWakeLockLog.onWakeLockReleased(tag, ownerUid, /*eventTime=*/ -1);
+ }
mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason);
}
@@ -1040,10 +1048,19 @@ public class Notifier {
return enabled && dndOff;
}
- private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled) {
+ private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled,
+ int ownerUid, int flags) {
if (callback != null) {
+ long currentTime = mInjector.currentTimeMillis();
mHandler.post(() -> {
try {
+ if (mFlags.improveWakelockLatency()) {
+ if (isEnabled) {
+ mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, currentTime);
+ } else {
+ mWakeLockLog.onWakeLockReleased(tag, ownerUid, currentTime);
+ }
+ }
callback.onStateChanged(isEnabled);
} catch (RemoteException e) {
Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e);
@@ -1057,6 +1074,7 @@ public class Notifier {
public NotifierHandler(Looper looper) {
super(looper, null, true /*async*/);
}
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -1085,4 +1103,28 @@ public class Notifier {
}
}
}
+
+ public interface Injector {
+ /**
+ * Gets the current time in millis
+ */
+ long currentTimeMillis();
+
+ /**
+ * Gets the WakeLockLog object
+ */
+ WakeLockLog getWakeLockLog(Context context);
+ }
+
+ static class RealInjector implements Injector {
+ @Override
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ @Override
+ public WakeLockLog getWakeLockLog(Context context) {
+ return new WakeLockLog(context);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 76cedd8e5e60..ce0120c245d6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -988,10 +988,10 @@ public final class PowerManagerService extends SystemService
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
- Executor backgroundExecutor) {
+ Executor backgroundExecutor, PowerManagerFlags powerManagerFlags) {
return new Notifier(
looper, context, batteryStats, suspendBlocker, policy, faceDownDetector,
- screenUndimDetector, backgroundExecutor);
+ screenUndimDetector, backgroundExecutor, powerManagerFlags, /*injector=*/ null);
}
SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
@@ -1373,7 +1373,7 @@ public final class PowerManagerService extends SystemService
mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
mPolicy, mFaceDownDetector, mScreenUndimDetector,
- BackgroundThread.getExecutor());
+ BackgroundThread.getExecutor(), mFeatureFlags);
mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP,
new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener,
diff --git a/services/core/java/com/android/server/power/WakeLockLog.java b/services/core/java/com/android/server/power/WakeLockLog.java
index b131311f76c7..968ff59ad8fc 100644
--- a/services/core/java/com/android/server/power/WakeLockLog.java
+++ b/services/core/java/com/android/server/power/WakeLockLog.java
@@ -154,9 +154,10 @@ final class WakeLockLog {
* @param tag The wake lock tag
* @param ownerUid The owner UID of the wake lock.
* @param flags Flags used for the wake lock.
+ * @param eventTime The time at which the event occurred
*/
- public void onWakeLockAcquired(String tag, int ownerUid, int flags) {
- onWakeLockEvent(TYPE_ACQUIRE, tag, ownerUid, flags);
+ public void onWakeLockAcquired(String tag, int ownerUid, int flags, long eventTime) {
+ onWakeLockEvent(TYPE_ACQUIRE, tag, ownerUid, flags, eventTime);
}
/**
@@ -164,9 +165,10 @@ final class WakeLockLog {
*
* @param tag The wake lock tag
* @param ownerUid The owner UID of the wake lock.
+ * @param eventTime The time at which the event occurred
*/
- public void onWakeLockReleased(String tag, int ownerUid) {
- onWakeLockEvent(TYPE_RELEASE, tag, ownerUid, 0 /* flags */);
+ public void onWakeLockReleased(String tag, int ownerUid, long eventTime) {
+ onWakeLockEvent(TYPE_RELEASE, tag, ownerUid, 0 /* flags */, eventTime);
}
/**
@@ -242,9 +244,10 @@ final class WakeLockLog {
* @param tag The wake lock's identifying tag.
* @param ownerUid The owner UID of the wake lock.
* @param flags The flags used with the wake lock.
+ * @param eventTime The time at which the event occurred
*/
private void onWakeLockEvent(int eventType, String tag, int ownerUid,
- int flags) {
+ int flags, long eventTime) {
if (tag == null) {
Slog.w(TAG, "Insufficient data to log wakelock [tag: " + tag
+ ", ownerUid: " + ownerUid
@@ -252,7 +255,8 @@ final class WakeLockLog {
return;
}
- final long time = mInjector.currentTimeMillis();
+ final long time = (eventTime == -1) ? mInjector.currentTimeMillis() : eventTime;
+
final int translatedFlags = eventType == TYPE_ACQUIRE
? translateFlagsFromPowerManager(flags)
: 0;
diff --git a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
index a5a7069b6ea1..ff1d2e402350 100644
--- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
+++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
@@ -35,18 +35,31 @@ public class PowerManagerFlags {
Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR,
Flags::enableEarlyScreenTimeoutDetector);
+ private final FlagState mImproveWakelockLatency = new FlagState(
+ Flags.FLAG_IMPROVE_WAKELOCK_LATENCY,
+ Flags::improveWakelockLatency
+ );
+
/** Returns whether early-screen-timeout-detector is enabled on not. */
public boolean isEarlyScreenTimeoutDetectorEnabled() {
return mEarlyScreenTimeoutDetectorFlagState.isEnabled();
}
/**
+ * @return Whether to improve the wakelock acquire/release latency or not
+ */
+ public boolean improveWakelockLatency() {
+ return mImproveWakelockLatency.isEnabled();
+ }
+
+ /**
* dumps all flagstates
* @param pw printWriter
*/
public void dump(PrintWriter pw) {
pw.println("PowerManagerFlags:");
pw.println(" " + mEarlyScreenTimeoutDetectorFlagState);
+ pw.println(" " + mImproveWakelockLatency);
}
private static class FlagState {
diff --git a/services/core/java/com/android/server/power/feature/power_flags.aconfig b/services/core/java/com/android/server/power/feature/power_flags.aconfig
index ca58153cf25b..3581b2fad1df 100644
--- a/services/core/java/com/android/server/power/feature/power_flags.aconfig
+++ b/services/core/java/com/android/server/power/feature/power_flags.aconfig
@@ -10,3 +10,11 @@ flag {
bug: "309861917"
is_fixed_read_only: true
}
+
+flag {
+ name: "improve_wakelock_latency"
+ namespace: "power"
+ description: "Feature flag for tracking the optimizations to improve the latency of acquiring and releasing a wakelock."
+ bug: "339590565"
+ is_fixed_read_only: true
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index e280bdc7780b..5be5bc5e3952 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -984,36 +984,26 @@ final class AccessibilityController {
Region touchableRegion = mTempRegion3;
windowState.getTouchableRegion(touchableRegion);
Region windowBounds = mTempRegion2;
- if (Flags.useWindowOriginalTouchableRegionWhenMagnificationRecomputeBounds()) {
- // For b/323366243, if using the bounds from touchableRegion.getBounds, in
- // non-magnifiable windowBounds computation, part of the non-touchableRegion
- // may be included into nonMagnifiedBounds. This will make users lose
- // the magnification control on mis-included areas.
- // Therefore, to prevent the above issue, we change to use the window exact
- // touchableRegion in magnificationRegion computation.
- // Like the original approach, the touchableRegion is in non-magnified display
- // space, so first we need to offset the region by the windowFrames bounds, then
- // apply the transform matrix to the region to get the exact region in magnified
- // display space.
- // TODO: For a long-term plan, since touchable regions provided by WindowState
- // doesn't actually reflect the real touchable regions on display, we should
- // delete the WindowState dependency and migrate to use the touchableRegion
- // from WindowInfoListener data. (b/330653961)
- touchableRegion.translate(-windowState.getFrame().left,
- -windowState.getFrame().top);
- applyMatrixToRegion(matrix, touchableRegion);
- windowBounds.set(touchableRegion);
- } else {
- Rect touchableFrame = mTempRect1;
- touchableRegion.getBounds(touchableFrame);
- RectF windowFrame = mTempRectF;
- windowFrame.set(touchableFrame);
- windowFrame.offset(-windowState.getFrame().left,
- -windowState.getFrame().top);
- matrix.mapRect(windowFrame);
- windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
- (int) windowFrame.right, (int) windowFrame.bottom);
- }
+
+ // For b/323366243, if using the bounds from touchableRegion.getBounds, in
+ // non-magnifiable windowBounds computation, part of the non-touchableRegion
+ // may be included into nonMagnifiedBounds. This will make users lose
+ // the magnification control on mis-included areas.
+ // Therefore, to prevent the above issue, we change to use the window exact
+ // touchableRegion in magnificationRegion computation.
+ // Like the original approach, the touchableRegion is in non-magnified display
+ // space, so first we need to offset the region by the windowFrames bounds, then
+ // apply the transform matrix to the region to get the exact region in magnified
+ // display space.
+ // TODO: For a long-term plan, since touchable regions provided by WindowState
+ // doesn't actually reflect the real touchable regions on display, we should
+ // delete the WindowState dependency and migrate to use the touchableRegion
+ // from WindowInfoListener data. (b/330653961)
+ touchableRegion.translate(-windowState.getFrame().left,
+ -windowState.getFrame().top);
+ applyMatrixToRegion(matrix, touchableRegion);
+ windowBounds.set(touchableRegion);
+
// Only update new regions
Region portionOfWindowAlreadyAccountedFor = mTempRegion3;
portionOfWindowAlreadyAccountedFor.set(mMagnificationRegion);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 76e7f535c60f..2f6e07c24d67 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -77,7 +77,6 @@ import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_INSETS_DECOUPLED_CONFIGURATION;
import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED;
import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
@@ -87,6 +86,7 @@ import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
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;
@@ -121,6 +121,7 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15;
+import static android.view.WindowManager.ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -128,7 +129,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED;
import static android.view.WindowManager.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING;
-import static android.view.WindowManager.ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
@@ -660,6 +660,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private final TaskFragment.ConfigOverrideHint mResolveConfigHint;
+ private final boolean mOptOutEdgeToEdge;
+
private static ConstrainDisplayApisConfig sConstrainDisplayApisConfig;
boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
@@ -682,6 +684,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// it references to gets removed. This should also be cleared when we move out of pip.
private Task mLastParentBeforePip;
+ // The token of the previous TaskFragment parent of this embedded ActivityRecord when it is
+ // reparented to a new Task due to picture-in-picture.
+ // Note that the TaskFragment may be finished and no longer attached in WM hierarchy.
+ @Nullable
+ private IBinder mLastEmbeddedParentTfTokenBeforePip;
+
// Only set if this instance is a launch-into-pip Activity, points to the
// host Activity the launch-into-pip Activity is originated from.
private ActivityRecord mLaunchIntoPipHostActivity;
@@ -1806,6 +1814,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mLastTaskFragmentOrganizerBeforePip = organizedTf != null
? organizedTf.getTaskFragmentOrganizer()
: null;
+ if (organizedTf != null
+ // Not necessary for content pip.
+ && launchIntoPipHostActivity == null) {
+ mLastEmbeddedParentTfTokenBeforePip = organizedTf.getFragmentToken();
+ }
}
void clearLastParentBeforePip() {
@@ -1815,12 +1828,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
mLaunchIntoPipHostActivity = null;
mLastTaskFragmentOrganizerBeforePip = null;
+ mLastEmbeddedParentTfTokenBeforePip = null;
}
@Nullable Task getLastParentBeforePip() {
return mLastParentBeforePip;
}
+ @Nullable IBinder getLastEmbeddedParentTfTokenBeforePip() {
+ return mLastEmbeddedParentTfTokenBeforePip;
+ }
+
@Nullable ActivityRecord getLaunchIntoPipHostActivity() {
return mLaunchIntoPipHostActivity;
}
@@ -2163,9 +2181,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|| ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
mStyleFillsParent = mOccludesParent;
noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
+ mOptOutEdgeToEdge = ent.array.getBoolean(
+ R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false);
} else {
mStyleFillsParent = mOccludesParent = true;
noDisplay = false;
+ mOptOutEdgeToEdge = false;
}
if (options != null) {
@@ -8694,9 +8715,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming()) {
rotation = mDisplayContent.getRotation();
}
- if (!mResolveConfigHint.mUseOverrideInsetsForConfig
- || getCompatDisplayInsets() != null || shouldCreateCompatDisplayInsets()
- || isFloating(parentWindowingMode) || rotation == ROTATION_UNDEFINED) {
+ if (!mOptOutEdgeToEdge && (!mResolveConfigHint.mUseOverrideInsetsForConfig
+ || getCompatDisplayInsets() != null || isFloating(parentWindowingMode)
+ || 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.
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 08aeedebf77d..72b854be74bd 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1768,7 +1768,6 @@ class ActivityStarter {
if (!avoidMoveToFront() && (mService.mHomeProcess == null
|| mService.mHomeProcess.mUid != realCallingUid)
&& (prevTopTask != null && prevTopTask.isActivityTypeHomeOrRecents())
- && !targetTask.isActivityTypeHomeOrRecents()
&& r.mTransitionController.isTransientHide(targetTask)) {
mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY;
}
@@ -2167,7 +2166,7 @@ class ActivityStarter {
// We don't need to start a new activity, and the client said not to do anything
// if that is the case, so this is it! And for paranoia, make sure we have
// correctly resumed the top activity.
- if (!mMovedToFront && mDoResume && !avoidMoveToFront()) {
+ if (!mMovedToFront && mDoResume) {
ProtoLog.d(WM_DEBUG_TASKS, "Bring to front target: %s from %s", mTargetRootTask,
targetTaskTop);
mTargetRootTask.moveToFront("intentActivityFound");
@@ -2196,7 +2195,7 @@ class ActivityStarter {
if (mMovedToFront) {
// We moved the task to front, use starting window to hide initial drawn delay.
targetTaskTop.showStartingWindow(true /* taskSwitch */);
- } else if (mDoResume && !avoidMoveToFront()) {
+ } else if (mDoResume) {
// Make sure the root task and its belonging display are moved to topmost.
mTargetRootTask.moveToFront("intentActivityFound");
}
@@ -2733,7 +2732,7 @@ class ActivityStarter {
// If a target task is specified, try to reuse that one
if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
- if (launchTask != null) {
+ if (launchTask != null && launchTask.isLeafTask()) {
return launchTask;
}
return null;
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 16d7b4fb6eed..6e11e082cc07 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1149,6 +1149,17 @@ final class LetterboxUiController {
}
boolean shouldApplyUserFullscreenOverride() {
+ // 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.
+ final DisplayContent displayContent = mActivityRecord.mDisplayContent;
+ if (displayContent != null && displayContent.mDisplayRotationCompatPolicy != null
+ && displayContent.mDisplayRotationCompatPolicy
+ .isCameraActive(mActivityRecord, /* mustBeFullscreen= */ true)) {
+ return false;
+ }
+
if (isUserFullscreenOverrideEnabled()) {
mUserAspectRatio = getUserMinAspectRatioOverrideCode();
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 26e4eaaedfe2..a3f15038865c 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1241,7 +1241,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
// have any running activities, not starting one and not home stack.
shouldBeVisible = hasRunningActivities
|| (starting != null && starting.isDescendantOf(this))
- || isActivityTypeHome();
+ || (isActivityTypeHome() && !isEmbedded());
break;
}
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 24b533a23af6..c4e932abecd3 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -365,7 +365,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
@Nullable
TaskFragmentTransaction.Change prepareActivityReparentedToTask(
- @NonNull ActivityRecord activity) {
+ @NonNull ActivityRecord activity, @Nullable ActivityRecord nextFillTaskActivity,
+ @Nullable IBinder lastParentTfToken) {
if (activity.finishing) {
Slog.d(TAG, "Reparent activity=" + activity.token + " is finishing");
return null;
@@ -408,10 +409,21 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Activity=%s reparent to taskId=%d",
activity.token, task.mTaskId);
- return new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENTED_TO_TASK)
- .setTaskId(task.mTaskId)
- .setActivityIntent(trimIntent(activity.intent))
- .setActivityToken(activityToken);
+
+ final TaskFragmentTransaction.Change change =
+ new TaskFragmentTransaction.Change(TYPE_ACTIVITY_REPARENTED_TO_TASK)
+ .setTaskId(task.mTaskId)
+ .setActivityIntent(trimIntent(activity.intent))
+ .setActivityToken(activityToken);
+ if (lastParentTfToken != null) {
+ change.setTaskFragmentToken(lastParentTfToken);
+ }
+ // Only pass the activity token to the client if it belongs to the same process.
+ if (Flags.fixPipRestoreToOverlay() && nextFillTaskActivity != null
+ && nextFillTaskActivity.getPid() == mOrganizerPid) {
+ change.setOtherActivityToken(nextFillTaskActivity.token);
+ }
+ return change;
}
void dispatchTransaction(@NonNull TaskFragmentTransaction transaction) {
@@ -733,13 +745,13 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
void onActivityReparentedToTask(@NonNull ActivityRecord activity) {
+ final Task task = activity.getTask();
final ITaskFragmentOrganizer organizer;
if (activity.mLastTaskFragmentOrganizerBeforePip != null) {
// If the activity is previously embedded in an organized TaskFragment.
organizer = activity.mLastTaskFragmentOrganizerBeforePip;
} else {
// Find the topmost TaskFragmentOrganizer.
- final Task task = activity.getTask();
final TaskFragment[] organizedTf = new TaskFragment[1];
task.forAllLeafTaskFragments(tf -> {
if (tf.isOrganizedTaskFragment()) {
@@ -757,10 +769,24 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
Slog.w(TAG, "The last TaskFragmentOrganizer no longer exists");
return;
}
- addPendingEvent(new PendingTaskFragmentEvent.Builder(
+
+ final IBinder parentTfTokenBeforePip = activity.getLastEmbeddedParentTfTokenBeforePip();
+ final PendingTaskFragmentEvent.Builder builder = new PendingTaskFragmentEvent.Builder(
PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENTED_TO_TASK, organizer)
.setActivity(activity)
- .build());
+ .setTaskFragmentToken(activity.getLastEmbeddedParentTfTokenBeforePip());
+
+ // Sets the next activity behinds the reparented Activity that's also not in the last
+ // embedded parent TF.
+ final ActivityRecord candidateAssociatedActivity = task.getActivity(
+ ar -> ar != activity && !ar.finishing
+ && ar.getTaskFragment().getFragmentToken() != parentTfTokenBeforePip);
+ if (candidateAssociatedActivity != null && (!candidateAssociatedActivity.isEmbedded()
+ || candidateAssociatedActivity.getTaskFragment().fillsParent())) {
+ builder.setOtherActivity(candidateAssociatedActivity);
+ }
+
+ addPendingEvent(builder.build());
}
void onTaskFragmentParentInfoChanged(@NonNull ITaskFragmentOrganizer organizer,
@@ -889,11 +915,16 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
@Nullable
private final TaskFragment mTaskFragment;
@Nullable
+ private final IBinder mTaskFragmentToken;
+ @Nullable
private final IBinder mErrorCallbackToken;
@Nullable
private final Throwable mException;
@Nullable
private final ActivityRecord mActivity;
+ // An additional Activity that's needed to send back to the client other than the mActivity.
+ @Nullable
+ private final ActivityRecord mOtherActivity;
@Nullable
private final Task mTask;
// Set when the event is deferred due to the host task is invisible. The defer time will
@@ -905,17 +936,21 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
private PendingTaskFragmentEvent(@EventType int eventType,
ITaskFragmentOrganizer taskFragmentOrg,
@Nullable TaskFragment taskFragment,
+ @Nullable IBinder taskFragmentToken,
@Nullable IBinder errorCallbackToken,
@Nullable Throwable exception,
@Nullable ActivityRecord activity,
+ @Nullable ActivityRecord otherActivity,
@Nullable Task task,
@TaskFragmentOperation.OperationType int opType) {
mEventType = eventType;
mTaskFragmentOrg = taskFragmentOrg;
mTaskFragment = taskFragment;
+ mTaskFragmentToken = taskFragmentToken;
mErrorCallbackToken = errorCallbackToken;
mException = exception;
mActivity = activity;
+ mOtherActivity = otherActivity;
mTask = task;
mOpType = opType;
}
@@ -943,12 +978,16 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
@Nullable
private TaskFragment mTaskFragment;
@Nullable
+ private IBinder mTaskFragmentToken;
+ @Nullable
private IBinder mErrorCallbackToken;
@Nullable
private Throwable mException;
@Nullable
private ActivityRecord mActivity;
@Nullable
+ private ActivityRecord mOtherActivity;
+ @Nullable
private Task mTask;
@TaskFragmentOperation.OperationType
private int mOpType;
@@ -963,6 +1002,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return this;
}
+ Builder setTaskFragmentToken(@Nullable IBinder fragmentToken) {
+ mTaskFragmentToken = fragmentToken;
+ return this;
+ }
+
Builder setErrorCallbackToken(@Nullable IBinder errorCallbackToken) {
mErrorCallbackToken = errorCallbackToken;
return this;
@@ -978,6 +1022,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return this;
}
+ Builder setOtherActivity(@NonNull ActivityRecord otherActivity) {
+ mOtherActivity = otherActivity;
+ return this;
+ }
+
Builder setTask(@NonNull Task task) {
mTask = requireNonNull(task);
return this;
@@ -990,7 +1039,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
PendingTaskFragmentEvent build() {
return new PendingTaskFragmentEvent(mEventType, mTaskFragmentOrg, mTaskFragment,
- mErrorCallbackToken, mException, mActivity, mTask, mOpType);
+ mTaskFragmentToken, mErrorCallbackToken, mException, mActivity,
+ mOtherActivity, mTask, mOpType);
}
}
}
@@ -1191,7 +1241,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
return state.prepareTaskFragmentError(event.mErrorCallbackToken, taskFragment,
event.mOpType, event.mException);
case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENTED_TO_TASK:
- return state.prepareActivityReparentedToTask(event.mActivity);
+ return state.prepareActivityReparentedToTask(event.mActivity, event.mOtherActivity,
+ event.mTaskFragmentToken);
default:
throw new IllegalArgumentException("Unknown TaskFragmentEvent=" + event.mEventType);
}
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index ce53290da49c..2dc439da992d 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -492,6 +492,27 @@ class TransitionController {
return false;
}
+ /** Returns {@code true} if the display contains a transient-launch transition. */
+ boolean hasTransientLaunch(@NonNull DisplayContent dc) {
+ if (mCollectingTransition != null && mCollectingTransition.hasTransientLaunch()
+ && mCollectingTransition.isOnDisplay(dc)) {
+ return true;
+ }
+ for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) {
+ final Transition transition = mWaitingTransitions.get(i);
+ if (transition.hasTransientLaunch() && transition.isOnDisplay(dc)) {
+ return true;
+ }
+ }
+ for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
+ final Transition transition = mPlayingTransitions.get(i);
+ if (transition.hasTransientLaunch() && transition.isOnDisplay(dc)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
boolean isTransientHide(@NonNull Task task) {
if (mCollectingTransition != null && mCollectingTransition.isInTransientHide(task)) {
return true;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 65e17615f775..3e43f5a2da66 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -165,7 +165,7 @@ class WallpaperController {
|| (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());
}
} else if (w.hasWallpaper() && mService.mPolicy.isKeyguardHostWindow(w.mAttrs)
- && w.mTransitionController.isTransitionOnDisplay(mDisplayContent)) {
+ && w.mTransitionController.hasTransientLaunch(mDisplayContent)) {
// If we have no candidates at all, notification shade is allowed to be the target
// of last resort even if it has not been made visible yet.
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found keyguard as wallpaper target: " + w);
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 97f1e19e35b1..4c746a97bafa 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -2451,12 +2451,6 @@ static void nativeMonitor(JNIEnv* env, jobject nativeImplObj) {
im->getInputManager()->getDispatcher().monitor();
}
-static jboolean nativeIsInputDeviceEnabled(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
- NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
-
- return im->getInputManager()->getReader().isInputDeviceEnabled(deviceId);
-}
-
static void nativeEnableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
@@ -2798,7 +2792,6 @@ static const JNINativeMethod gInputManagerMethods[] = {
{"sysfsNodeChanged", "(Ljava/lang/String;)V", (void*)nativeSysfsNodeChanged},
{"dump", "()Ljava/lang/String;", (void*)nativeDump},
{"monitor", "()V", (void*)nativeMonitor},
- {"isInputDeviceEnabled", "(I)Z", (void*)nativeIsInputDeviceEnabled},
{"enableInputDevice", "(I)V", (void*)nativeEnableInputDevice},
{"disableInputDevice", "(I)V", (void*)nativeDisableInputDevice},
{"reloadPointerIcons", "()V", (void*)nativeReloadPointerIcons},
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodMapTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodMapTest.java
index 5e3bc564f0f6..be7042177a35 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodMapTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodMapTest.java
@@ -44,49 +44,49 @@ public final class InputMethodMapTest {
}
@Test
- public void testEqualsSameObject() {
+ public void testAreSameSameObject() {
final var imi1 = createFakeInputMethodInfo(TEST_IME_ID1, createFakeSubtypes(0));
final var imi2 = createFakeInputMethodInfo(TEST_IME_ID2, createFakeSubtypes(3));
final var map = toMap(imi1, imi2);
assertTrue("Must return true for the same instance",
- InputMethodMap.equals(map, map));
+ InputMethodMap.areSame(map, map));
}
@Test
- public void testEqualsEquivalentObject() {
+ public void testAreSameEquivalentObject() {
final var imi1 = createFakeInputMethodInfo(TEST_IME_ID1, createFakeSubtypes(0));
final var imi2 = createFakeInputMethodInfo(TEST_IME_ID2, createFakeSubtypes(3));
assertTrue("Must return true for the equivalent instances",
- InputMethodMap.equals(toMap(imi1, imi2), toMap(imi1, imi2)));
+ InputMethodMap.areSame(toMap(imi1, imi2), toMap(imi1, imi2)));
assertTrue("Must return true for the equivalent instances",
- InputMethodMap.equals(toMap(imi1, imi2), toMap(imi2, imi1)));
+ InputMethodMap.areSame(toMap(imi1, imi2), toMap(imi2, imi1)));
}
@Test
- public void testEqualsDifferentKeys() {
+ public void testAreSameDifferentKeys() {
final var imi1 = createFakeInputMethodInfo(TEST_IME_ID1, createFakeSubtypes(0));
final var imi2 = createFakeInputMethodInfo(TEST_IME_ID2, createFakeSubtypes(3));
final var imi3 = createFakeInputMethodInfo(TEST_IME_ID3, createFakeSubtypes(3));
assertFalse("Must return false if keys are different",
- InputMethodMap.equals(toMap(imi1), toMap(imi1, imi2)));
+ InputMethodMap.areSame(toMap(imi1), toMap(imi1, imi2)));
assertFalse("Must return false if keys are different",
- InputMethodMap.equals(toMap(imi1, imi2), toMap(imi1)));
+ InputMethodMap.areSame(toMap(imi1, imi2), toMap(imi1)));
assertFalse("Must return false if keys are different",
- InputMethodMap.equals(toMap(imi1, imi2), toMap(imi1, imi3)));
+ InputMethodMap.areSame(toMap(imi1, imi2), toMap(imi1, imi3)));
}
@Test
- public void testEqualsDifferentValues() {
+ public void testAreSameDifferentValues() {
final var imi1_without_subtypes =
createFakeInputMethodInfo(TEST_IME_ID1, createFakeSubtypes(0));
final var imi1_with_subtypes =
createFakeInputMethodInfo(TEST_IME_ID1, createFakeSubtypes(3));
final var imi2 = createFakeInputMethodInfo(TEST_IME_ID2, createFakeSubtypes(3));
assertFalse("Must return false if values are different",
- InputMethodMap.equals(toMap(imi1_without_subtypes), toMap(imi1_with_subtypes)));
+ InputMethodMap.areSame(toMap(imi1_without_subtypes), toMap(imi1_with_subtypes)));
assertFalse("Must return false if values are different",
- InputMethodMap.equals(
+ InputMethodMap.areSame(
toMap(imi1_without_subtypes, imi2),
toMap(imi1_with_subtypes, imi2)));
}
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 54b2d4dd1429..8844e6cc3a2c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -709,6 +709,64 @@ public class DisplayManagerServiceTest {
assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) == 0);
}
+ @Test
+ public void testCreateVirtualDisplayOwnFocus_checkDisplayDeviceInfo() throws RemoteException {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ // This is effectively the DisplayManager service published to ServiceManager.
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+ final String uniqueId = "uniqueId --- Own Focus Test -- checkDisplayDeviceInfo";
+ float refreshRate = 60.0f;
+ int width = 600;
+ int height = 800;
+ int dpi = 320;
+ int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS;
+
+ when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, width, height, dpi);
+ builder.setFlags(flags);
+ builder.setUniqueId(uniqueId);
+ builder.setRequestedRefreshRate(refreshRate);
+
+ // Create a virtual display in its own display group.
+ final VirtualDisplayConfig ownerDisplayConfig = builder.build();
+ int displayId = bs.createVirtualDisplay(ownerDisplayConfig, /* callback= */ mMockAppToken,
+ /* projection= */ null, PACKAGE_NAME);
+ verify(mMockProjectionService, never()).setContentRecordingSession(any(),
+ nullable(IMediaProjection.class));
+
+ DisplayInfo displayInfo = bs.getDisplayInfo(displayId);
+ assertNotNull(displayInfo);
+ assertTrue((displayInfo.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) == 0);
+ final String displayUniqueId = VirtualDisplayAdapter.generateDisplayUniqueId(
+ PACKAGE_NAME, Process.myUid(), ownerDisplayConfig);
+ assertEquals(displayInfo.uniqueId, displayUniqueId);
+ assertEquals(displayInfo.name, VIRTUAL_DISPLAY_NAME);
+ assertEquals(displayInfo.ownerPackageName, PACKAGE_NAME);
+ assertEquals(displayInfo.getRefreshRate(), refreshRate, 0.1f);
+
+ performTraversalInternal(displayManager);
+
+ // Flush the handler.
+ displayManager.getDisplayHandler().runWithScissors(() -> {}, /* now= */ 0);
+
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) == 0);
+ assertEquals(ddi.width, width);
+ assertEquals(ddi.height, height);
+ assertEquals(ddi.name, displayInfo.name);
+ assertEquals(ddi.ownerPackageName, displayInfo.ownerPackageName);
+ assertEquals(ddi.uniqueId, displayInfo.uniqueId);
+ assertEquals(ddi.renderFrameRate, displayInfo.getRefreshRate(), 0.1f);
+ }
+
/**
* Tests that the virtual display is created along-side the default display.
*/
diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
index c01b15c17483..81e6cc3f546b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
@@ -18,12 +18,14 @@ package com.android.server.display;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
import android.os.IBinder;
+import android.os.Process;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -88,6 +90,25 @@ public class VirtualDisplayAdapterTest {
}
@Test
+ public void testCreatesVirtualDisplay_checkGeneratedDisplayUniqueIdPrefix() {
+ VirtualDisplayConfig config = new VirtualDisplayConfig.Builder("test", /* width= */ 1,
+ /* height= */ 1, /* densityDpi= */ 1).build();
+
+ final String packageName = "testpackage";
+ final String displayUniqueId = VirtualDisplayAdapter.generateDisplayUniqueId(
+ packageName, Process.myUid(), config);
+
+ DisplayDevice result = mVirtualDisplayAdapter.createVirtualDisplayLocked(
+ mMockCallback, /* projection= */ null, /* ownerUid= */ 10,
+ packageName, displayUniqueId, /* surface= */ null, /* flags= */ 0, config);
+
+ assertNotNull(result);
+
+ final String uniqueId = result.getUniqueId();
+ assertTrue(uniqueId.startsWith(VirtualDisplayAdapter.UNIQUE_ID_PREFIX + packageName));
+ }
+
+ @Test
public void testDoesNotCreateVirtualDisplayForSameCallback() {
VirtualDisplayConfig config1 = new VirtualDisplayConfig.Builder("test", /* width= */ 1,
/* height= */ 1, /* densityDpi= */ 1).build();
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 19bff56a4b29..d19f47951df1 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
@@ -395,7 +395,7 @@ public class AutomaticBrightnessStrategyTest {
automaticBrightnessController);
assertEquals(automaticScreenBrightness,
mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
- new BrightnessEvent(DISPLAY_ID)), 0.0f);
+ new BrightnessEvent(DISPLAY_ID), false), 0.0f);
assertEquals(automaticScreenBrightness,
mAutomaticBrightnessStrategy.getAutomaticScreenBrightnessBasedOnLastUsedLux(
new BrightnessEvent(DISPLAY_ID)), 0.0f);
@@ -461,8 +461,12 @@ public class AutomaticBrightnessStrategyTest {
}
@Test
- public void isAutoBrightnessValid_returnsTrueWhenBrightnessIsValid() {
+ public void isAutoBrightnessValid_returnsTrueWhenBrightnessIsValid_adjustsAutoBrightness()
+ throws Settings.SettingNotFoundException {
+ float adjustment = 0.1f;
mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment())
+ .thenReturn(0.1f);
mAutomaticBrightnessStrategy.setAutoBrightnessState(Display.STATE_ON, true,
BrightnessReason.REASON_UNKNOWN,
DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT, 0.1f,
@@ -470,6 +474,11 @@ public class AutomaticBrightnessStrategyTest {
when(mAutomaticBrightnessController.getAutomaticScreenBrightness(null))
.thenReturn(0.2f);
assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessValid());
+ assertEquals(adjustment, mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
+ assertEquals(adjustment, Settings.System.getFloatForUser(
+ mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
+ UserHandle.USER_CURRENT), 0.0f);
}
@Test
@@ -486,6 +495,15 @@ public class AutomaticBrightnessStrategyTest {
when(mAutomaticBrightnessController.getAutomaticScreenBrightness(brightnessEvent))
.thenReturn(brightness);
+
+ // We do this to apply the automatic brightness adjustments
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()).thenReturn(
+ 0.25f);
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightness(null))
+ .thenReturn(brightness);
+ assertEquals(brightness, mAutomaticBrightnessStrategy
+ .getAutomaticScreenBrightness(null, false), 0.0f);
+
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
mock(DisplayManagerInternal.DisplayPowerRequest.class);
DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
@@ -529,6 +547,12 @@ public class AutomaticBrightnessStrategyTest {
when(mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()).thenReturn(
autoBrightnessAdjustment);
+ // We do this to apply the automatic brightness adjustments
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightness(null))
+ .thenReturn(brightness);
+ assertEquals(brightness, mAutomaticBrightnessStrategy
+ .getAutomaticScreenBrightness(null, false), 0.0f);
+
DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
.setBrightness(brightness)
.setSdrBrightness(brightness)
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index c359412b6ccd..cb15d6f84403 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -3094,13 +3094,14 @@ public final class AlarmManagerServiceTest {
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class),
any(), any(Handler.class), isNull(), bundleCaptor.capture());
+ Bundle bundle = bundleCaptor.getValue();
if (idleOptions != null) {
- assertEquals(idleOptions, bundleCaptor.getValue());
+ assertEquals(idleOptions, bundle);
} else {
- assertFalse("BAL flag needs to be false in alarm manager",
- bundleCaptor.getValue().getBoolean(
- ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
- true));
+ ActivityOptions options = ActivityOptions.fromBundle(bundle);
+ assertEquals("BAL should not be allowed in alarm manager",
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED,
+ options.getPendingIntentBackgroundActivityStartMode());
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
index c1f4feee9c57..e88e28b37551 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
@@ -142,6 +142,7 @@ public class ApplicationStartInfoTest {
final String app1PackageName = "com.android.test.stub1";
final long appStartTimestampIntentStarted = 1000000;
final long appStartTimestampActivityLaunchFinished = 2000000;
+ final long appStartTimestampFirstFrameDrawn = 2500000;
final long appStartTimestampReportFullyDrawn = 3000000;
final long appStartTimestampService = 4000000;
final long appStartTimestampBroadcast = 5000000;
@@ -272,6 +273,8 @@ public class ApplicationStartInfoTest {
mAppStartInfoTracker.onActivityLaunchFinished(appStartTimestampIntentStarted, COMPONENT,
appStartTimestampActivityLaunchFinished, ApplicationStartInfo.LAUNCH_MODE_STANDARD);
+ mAppStartInfoTracker.addTimestampToStart(app1PackageName, app1Uid,
+ appStartTimestampFirstFrameDrawn, ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME);
list.clear();
mAppStartInfoTracker.getStartInfo(app1PackageName, app1Uid, app1Pid1, 0, list);
verifyInProgressRecordsSize(1);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
index 72c0a9e6e90c..2cbc226da780 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
@@ -1 +1,3 @@
include /services/core/java/com/android/server/am/OWNERS
+
+per-file ApplicationStartInfoTest.java = yforta@google.com, carmenjackson@google.com, jji@google.com
diff --git a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
index a9ff3a133f6e..4460c6af0691 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
@@ -22,10 +22,12 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -52,6 +54,7 @@ import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.batterysaver.BatterySaverStateMachine;
+import com.android.server.power.feature.PowerManagerFlags;
import com.android.server.statusbar.StatusBarManagerInternal;
import org.junit.Before;
@@ -77,6 +80,9 @@ public class NotifierTest {
@Mock private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
@Mock private Vibrator mVibrator;
@Mock private StatusBarManagerInternal mStatusBarManagerInternal;
+ @Mock private WakeLockLog mWakeLockLog;
+
+ @Mock private PowerManagerFlags mPowerManagerFlags;
private PowerManagerService mService;
private Context mContextSpy;
@@ -222,6 +228,7 @@ public class NotifierTest {
@Test
public void testOnWakeLockListener_RemoteException_NoRethrow() {
+ when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
createNotifier();
IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
@@ -235,6 +242,9 @@ public class NotifierTest {
mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
"my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
exceptingCallback);
+ verifyZeroInteractions(mWakeLockLog);
+ mTestLooper.dispatchAll();
+ verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, 1);
mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
"my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
exceptingCallback);
@@ -244,8 +254,27 @@ public class NotifierTest {
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
"my.package.name", uid, pid, /* newWorkSource= */ null, /* newHistoryTag= */ null,
exceptingCallback);
+ verifyNoMoreInteractions(mWakeLockLog);
mTestLooper.dispatchAll();
+ verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid,
+ PowerManager.PARTIAL_WAKE_LOCK, 1);
// If we didn't throw, we're good!
+
+ // Test with improveWakelockLatency flag false, hence the wakelock log will run on the same
+ // thread
+ clearInvocations(mWakeLockLog);
+ when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(false);
+
+ mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+ "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+ exceptingCallback);
+ verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid,
+ PowerManager.PARTIAL_WAKE_LOCK, -1);
+
+ mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+ "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+ exceptingCallback);
+ verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1);
}
private final PowerManagerService.Injector mInjector = new PowerManagerService.Injector() {
@@ -253,7 +282,7 @@ public class NotifierTest {
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
- Executor backgroundExecutor) {
+ Executor backgroundExecutor, PowerManagerFlags powerManagerFlags) {
return mNotifierMock;
}
@@ -326,6 +355,18 @@ public class NotifierTest {
}
private void createNotifier() {
+ Notifier.Injector injector = new Notifier.Injector() {
+ @Override
+ public long currentTimeMillis() {
+ return 1;
+ }
+
+ @Override
+ public WakeLockLog getWakeLockLog(Context context) {
+ return mWakeLockLog;
+ }
+ };
+
mNotifier = new Notifier(
mTestLooper.getLooper(),
mContextSpy,
@@ -335,7 +376,7 @@ public class NotifierTest {
null,
null,
null,
- mTestExecutor);
+ mTestExecutor, mPowerManagerFlags, injector);
}
private static class FakeExecutor implements Executor {
diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
index 7f165e0e8885..b737e0f98317 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -114,6 +114,7 @@ import com.android.server.power.PowerManagerService.WakeLock;
import com.android.server.power.batterysaver.BatterySaverController;
import com.android.server.power.batterysaver.BatterySaverPolicy;
import com.android.server.power.batterysaver.BatterySaverStateMachine;
+import com.android.server.power.feature.PowerManagerFlags;
import com.android.server.testutils.OffsettableClock;
import com.google.testing.junit.testparameterinjector.TestParameter;
@@ -275,7 +276,7 @@ public class PowerManagerServiceTest {
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
- Executor executor) {
+ Executor executor, PowerManagerFlags powerManagerFlags) {
return mNotifierMock;
}
diff --git a/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java b/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
index 0fad25d35515..1c4db6ad883b 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
@@ -57,19 +57,42 @@ public class WakeLockLogTest {
}
@Test
- public void testAddTwoItems() {
+ public void testAddTwoItems_withNoEventTimeSupplied() {
final int tagDatabaseSize = 128;
final int logSize = 20;
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
-
when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("TagPartial", 101,
- PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE);
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, -1);
when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
log.onWakeLockAcquired("TagFull", 102,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, -1);
+
+ assertEquals("Wake Lock Log\n"
+ + " 01-01 00:00:01.000 - 101 (some.package1) - ACQ TagPartial "
+ + "(partial,on-after-release)\n"
+ + " 01-01 00:00:01.150 - 102 (some.package2) - ACQ TagFull "
+ + "(full,acq-causes-wake)\n"
+ + " -\n"
+ + " Events: 2, Time-Resets: 0\n"
+ + " Buffer, Bytes used: 6\n",
+ dumpLog(log, false));
+ }
+
+ @Test
+ public void testAddTwoItems() {
+ final int tagDatabaseSize = 128;
+ final int logSize = 20;
+ TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+ WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
+
+ log.onWakeLockAcquired("TagPartial", 101,
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, 1000L);
+
+ log.onWakeLockAcquired("TagFull", 102,
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1150L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1) - ACQ TagPartial "
@@ -89,11 +112,9 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
- log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1350L);
- log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK, 1350L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1) - ACQ TagPartial (partial)\n"
@@ -111,11 +132,9 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
- log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
- log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK, 1150L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - --- - ACQ UNKNOWN (partial)\n"
@@ -134,41 +153,33 @@ public class WakeLockLogTest {
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
// Wake lock 1 acquired - log size = 3
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
- log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
// Wake lock 2 acquired - log size = 3 + 3 = 6
- when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
- log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK, 1150L);
// Wake lock 3 acquired - log size = 6 + 3 = 9
- when(injectorSpy.currentTimeMillis()).thenReturn(1151L);
- log.onWakeLockAcquired("TagThree", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagThree", 101, PowerManager.PARTIAL_WAKE_LOCK, 1151L);
// We need more space - wake lock 1 acquisition is removed from the log and saved in the
// list. Log size = 9 - 3 + 2 = 8
- when(injectorSpy.currentTimeMillis()).thenReturn(1152L);
- log.onWakeLockReleased("TagThree", 101);
+ log.onWakeLockReleased("TagThree", 101, 1152L);
// We need more space - wake lock 2 acquisition is removed from the log and saved in the
// list. Log size = 8 - 3 + 2 = 7
- when(injectorSpy.currentTimeMillis()).thenReturn(1153L);
- log.onWakeLockReleased("TagPartial", 101);
+ log.onWakeLockReleased("TagPartial", 101, 1153L);
// We need more space - wake lock 3 acquisition is removed from the log and saved in the
// list. Log size = 7 - 3 + 3 = 7
- when(injectorSpy.currentTimeMillis()).thenReturn(1154L);
- log.onWakeLockAcquired("TagFour", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagFour", 101, PowerManager.PARTIAL_WAKE_LOCK, 1154L);
// We need more space - wake lock 3 release is removed from the log and wake lock 3
// acquisition is removed from the list. Log size = 7 - 2 + 3 = 8
- when(injectorSpy.currentTimeMillis()).thenReturn(1155L);
- log.onWakeLockAcquired("TagFive", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("TagFive", 101, PowerManager.PARTIAL_WAKE_LOCK, 1155L);
// We need more space - wake lock 1 release is removed from the log and wake lock 1
// acquisition is removed from the list. Log size = 8 - 2 + 2 = 8
- when(injectorSpy.currentTimeMillis()).thenReturn(1156L);
- log.onWakeLockReleased("TagFull", 102);
+ log.onWakeLockReleased("TagFull", 102, 1156L);
// Wake lock 2 acquisition is still printed because its release have not rolled off the log
// yet.
@@ -191,8 +202,8 @@ public class WakeLockLogTest {
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
// Bad tag means it wont get written
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
- log.onWakeLockAcquired(null /* tag */, 0 /* ownerUid */, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired(
+ null /* tag */, 0 /* ownerUid */, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
assertEquals("Wake Lock Log\n"
+ " -\n"
@@ -208,9 +219,8 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("*job*/com.one.two.3hree/.one..Last", 101,
- PowerManager.PARTIAL_WAKE_LOCK);
+ PowerManager.PARTIAL_WAKE_LOCK, 1000L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1) - ACQ "
@@ -228,10 +238,8 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
- log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK);
- when(injectorSpy.currentTimeMillis()).thenReturn(1001L);
- log.onWakeLockReleased("HowdyTag", 101);
+ log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
+ log.onWakeLockReleased("HowdyTag", 101, 1001L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1) - ACQ HowdyTag (partial)\n"
@@ -250,12 +258,10 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1100L);
- log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK);
+ log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK, 1100L);
// New element goes back in time...should not be written to log.
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
- log.onWakeLockReleased("HowdyTag", 101);
+ log.onWakeLockReleased("HowdyTag", 101, 1000L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.100 - 101 (some.package1) - ACQ HowdyTag (partial)\n"
@@ -272,9 +278,8 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("TagPartial", 101,
- PowerManager.PARTIAL_WAKE_LOCK | PowerManager.SYSTEM_WAKELOCK);
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.SYSTEM_WAKELOCK, 1000L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1) - ACQ TagPartial "
@@ -293,9 +298,8 @@ public class WakeLockLogTest {
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
when(mPackageManager.getPackagesForUid(101)).thenReturn(null);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("TagPartial", 101,
- PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE);
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, 1000L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 - ACQ TagPartial "
@@ -316,9 +320,8 @@ public class WakeLockLogTest {
when(mPackageManager.getPackagesForUid(101)).thenReturn(
new String[]{ "some.package1", "some.package2", "some.package3" });
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("TagPartial", 101,
- PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE);
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, 1000L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1,...) - ACQ TagPartial "
@@ -336,17 +339,14 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("TagPartial", 101,
- PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE);
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, 1000L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
log.onWakeLockAcquired("TagFull", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1150L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1151L);
log.onWakeLockAcquired("TagFull2", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1151L);
assertEquals("Wake Lock Log\n"
+ " 01-01 00:00:01.000 - 101 (some.package1) - ACQ TagPartial "
@@ -370,29 +370,23 @@ public class WakeLockLogTest {
TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
- when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
log.onWakeLockAcquired("TagPartial", 101,
- PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE);
+ PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, 1000L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
log.onWakeLockAcquired("TagFull", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1150L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1151L);
log.onWakeLockAcquired("TagFull2", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1151L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1152L);
log.onWakeLockAcquired("TagFull3", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1152L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1153L);
log.onWakeLockAcquired("TagFull4", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1153L);
- when(injectorSpy.currentTimeMillis()).thenReturn(1154L);
log.onWakeLockAcquired("TagFull5", 101,
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
+ PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 1154L);
// The first 3 events have been removed from the log and they exist in the saved
// acquisitions list. They should also use the cache when fetching the package names.
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index cb4fc753aa4d..6152326bb6d4 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -30,7 +30,9 @@ import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULL
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -42,6 +44,7 @@ import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -102,6 +105,7 @@ import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutT
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.internal.compat.IPlatformCompat;
+import com.android.internal.content.PackageMonitor;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
@@ -910,6 +914,38 @@ public class AccessibilityManagerServiceTest {
}
@Test
+ public void onPackageChanged_disableComponent_updateInstalledServices() {
+ // Sets up two accessibility services as installed services
+ setupShortcutTargetServices();
+ assertThat(mA11yms.getCurrentUserState().mInstalledServices).hasSize(2);
+ AccessibilityServiceInfo installedService1 =
+ mA11yms.getCurrentUserState().mInstalledServices.getFirst();
+ ResolveInfo resolveInfo1 = installedService1.getResolveInfo();
+ AccessibilityServiceInfo installedService2 =
+ mA11yms.getCurrentUserState().mInstalledServices.getLast();
+
+ // Disables `installedService2`
+ when(mMockPackageManager.queryIntentServicesAsUser(any(), anyInt(), anyInt()))
+ .thenReturn(List.of(resolveInfo1));
+ when(mMockSecurityPolicy.canRegisterService(any())).thenReturn(true);
+ final Intent packageIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
+ packageIntent.setData(
+ Uri.parse("package:" + installedService2.getResolveInfo().serviceInfo.packageName));
+ packageIntent.putExtra(Intent.EXTRA_UID, UserHandle.myUserId());
+ packageIntent.putExtra(Intent.EXTRA_USER_HANDLE, mA11yms.getCurrentUserIdLocked());
+ packageIntent.putExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST,
+ new String[]{
+ installedService2.getComponentName().flattenToString()});
+ mA11yms.getPackageMonitor().doHandlePackageEvent(packageIntent);
+
+ assertThat(mA11yms.getCurrentUserState().mInstalledServices).hasSize(1);
+ ComponentName installedService =
+ mA11yms.getCurrentUserState().mInstalledServices.getFirst().getComponentName();
+ assertThat(installedService)
+ .isEqualTo(installedService1.getComponentName());
+ }
+
+ @Test
public void testSwitchUserScanPackages_scansWithoutHoldingLock() {
setupAccessibilityServiceConnection(0);
final AtomicReference<Set<Boolean>> lockState = collectLockStateWhilePackageScanning();
@@ -1620,6 +1656,67 @@ public class AccessibilityManagerServiceTest {
.containsExactlyElementsIn(Set.of(daltonizerTile));
}
+ @Test
+ @EnableFlags(Flags.FLAG_MANAGER_PACKAGE_MONITOR_LOGIC_FIX)
+ public void onHandleForceStop_dontDoIt_packageEnabled_returnsTrue() {
+ setupShortcutTargetServices();
+ AccessibilityUserState userState = mA11yms.getCurrentUserState();
+ userState.mEnabledServices.addAll(
+ userState.mInstalledServices.stream().map(
+ (AccessibilityServiceInfo::getComponentName)).toList());
+ String[] packages = userState.mEnabledServices.stream().map(
+ ComponentName::getPackageName).toList().toArray(new String[0]);
+
+ PackageMonitor monitor = spy(mA11yms.getPackageMonitor());
+ when(monitor.getChangingUserId()).thenReturn(UserHandle.USER_SYSTEM);
+ mA11yms.setPackageMonitor(monitor);
+
+ assertTrue(mA11yms.getPackageMonitor().onHandleForceStop(
+ new Intent(),
+ packages,
+ UserHandle.USER_SYSTEM,
+ false
+ ));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_MANAGER_PACKAGE_MONITOR_LOGIC_FIX)
+ public void onHandleForceStop_doIt_packageEnabled_returnsFalse() {
+ setupShortcutTargetServices();
+ AccessibilityUserState userState = mA11yms.getCurrentUserState();
+ userState.mEnabledServices.addAll(
+ userState.mInstalledServices.stream().map(
+ (AccessibilityServiceInfo::getComponentName)).toList());
+ String[] packages = userState.mEnabledServices.stream().map(
+ ComponentName::getPackageName).toList().toArray(new String[0]);
+
+ PackageMonitor monitor = spy(mA11yms.getPackageMonitor());
+ when(monitor.getChangingUserId()).thenReturn(UserHandle.USER_SYSTEM);
+ mA11yms.setPackageMonitor(monitor);
+
+ assertFalse(mA11yms.getPackageMonitor().onHandleForceStop(
+ new Intent(),
+ packages,
+ UserHandle.USER_SYSTEM,
+ true
+ ));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_MANAGER_PACKAGE_MONITOR_LOGIC_FIX)
+ public void onHandleForceStop_dontDoIt_packageNotEnabled_returnsFalse() {
+ PackageMonitor monitor = spy(mA11yms.getPackageMonitor());
+ when(monitor.getChangingUserId()).thenReturn(UserHandle.USER_SYSTEM);
+ mA11yms.setPackageMonitor(monitor);
+
+ assertFalse(mA11yms.getPackageMonitor().onHandleForceStop(
+ new Intent(),
+ new String[]{ "FOO", "BAR"},
+ UserHandle.USER_SYSTEM,
+ false
+ ));
+ }
+
private static AccessibilityServiceInfo mockAccessibilityServiceInfo(
ComponentName componentName) {
return mockAccessibilityServiceInfo(
@@ -1630,7 +1727,7 @@ public class AccessibilityManagerServiceTest {
ComponentName componentName,
boolean isSystemApp, boolean isAlwaysOnService) {
AccessibilityServiceInfo accessibilityServiceInfo =
- Mockito.spy(new AccessibilityServiceInfo());
+ spy(new AccessibilityServiceInfo());
accessibilityServiceInfo.setComponentName(componentName);
ResolveInfo mockResolveInfo = Mockito.mock(ResolveInfo.class);
when(accessibilityServiceInfo.getResolveInfo()).thenReturn(mockResolveInfo);
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
index 06726b031a36..55d93fb8d9dc 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
@@ -144,7 +144,9 @@ public class AppIdleHistoryTests extends AndroidTestCase {
assertEquals(aih.getAppStandbyReason(PACKAGE_4, USER_ID, 3000),
REASON_MAIN_FORCED_BY_USER);
- assertTrue(aih.shouldInformListeners(PACKAGE_1, USER_ID, 5000, STANDBY_BUCKET_RARE));
+ if (!Flags.avoidIdleCheck()) {
+ assertTrue(aih.shouldInformListeners(PACKAGE_1, USER_ID, 5000, STANDBY_BUCKET_RARE));
+ }
assertFalse(aih.shouldInformListeners(PACKAGE_1, USER_ID, 5000, STANDBY_BUCKET_RARE));
assertTrue(aih.shouldInformListeners(PACKAGE_1, USER_ID, 5000, STANDBY_BUCKET_FREQUENT));
}
@@ -243,4 +245,4 @@ public class AppIdleHistoryTests extends AndroidTestCase {
expectedExpiryTimeMs, actualExpiryTimeMs);
}
}
-} \ No newline at end of file
+}
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 6b17de4c8640..c7f502045ac8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -908,6 +908,24 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
}
@Test
+ public void testOverrideOrientationIfNeeded_fullscreenOverride_cameraActivity_unchanged() {
+ doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabledAtBuildTime();
+
+ // Recreate DisplayContent with DisplayRotationCompatPolicy
+ mActivity = setUpActivityWithComponent();
+ mController = new LetterboxUiController(mWm, mActivity);
+ spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
+
+ doReturn(false).when(mDisplayContent.mDisplayRotationCompatPolicy)
+ .isCameraActive(mActivity, /* mustBeFullscreen= */ true);
+
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
+ /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
+ }
+
+ @Test
public void testOverrideOrientationIfNeeded_respectOrientationRequestOverUserFullScreen() {
spyOn(mController);
doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
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 a90a158e0c2a..d57a7e61ad63 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.Manifest.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE;
import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
@@ -961,6 +962,22 @@ public class TaskFragmentTest extends WindowTestsBase {
assertEquals(appLeftTop, task.getDisplayContent().mFocusedApp);
}
+ @Test
+ public void testShouldBeVisible_invisibleForEmptyTaskFragment() {
+ final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN).build();
+ final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .build();
+
+ // Empty taskFragment should be invisible
+ assertFalse(taskFragment.shouldBeVisible(null));
+
+ // Should be invisible even if it is ACTIVITY_TYPE_HOME.
+ when(taskFragment.getActivityType()).thenReturn(ACTIVITY_TYPE_HOME);
+ assertFalse(taskFragment.shouldBeVisible(null));
+ }
+
private WindowState createAppWindow(ActivityRecord app, String name) {
final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, app, name,
0 /* ownerId */, false /* ownerCanAddInternalSystemWindow */, new TestIWindow());
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 5b1a18da3173..9b48cb9d328c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -314,6 +314,18 @@ public class WallpaperControllerTests extends WindowTestsBase {
// Wallpaper is invisible because the lowest show-when-locked activity is opaque.
assertNull(wallpaperController.getWallpaperTarget());
+ // Only transient-launch transition will make notification shade as last resort target.
+ // This verifies that regular transition won't choose invisible keyguard as the target.
+ final WindowState keyguard = createWindow(null /* parent */,
+ WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE, "keyguard");
+ keyguard.mAttrs.flags |= FLAG_SHOW_WALLPAPER;
+ registerTestTransitionPlayer();
+ final Transition transition = wallpaperWindow.mTransitionController.createTransition(
+ WindowManager.TRANSIT_CHANGE);
+ transition.collect(keyguard);
+ wallpaperController.adjustWallpaperWindows();
+ assertNull(wallpaperController.getWallpaperTarget());
+
// A show-when-locked wallpaper is used for lockscreen. So the top wallpaper should
// be the one that is not show-when-locked.
final WindowState wallpaperWindow2 = createWallpaperWindow(mDisplayContent);
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 65de7e479890..7d845a3c086c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3372,4 +3372,13 @@ interface ITelephony {
+ "android.Manifest.permission.SATELLITE_COMMUNICATION)")
void unregisterForCommunicationAllowedStateChanged(int subId,
in ISatelliteCommunicationAllowedStateCallback callback);
+
+ /**
+ * This API can be used by only CTS to override the boolean configs used by the
+ * DatagramController module.
+ *
+ * @param enable Whether to enable boolean config.
+ * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
+ */
+ boolean setDatagramControllerBooleanConfig(boolean reset, int booleanType, boolean enable);
}
diff --git a/tests/BinderLeakTest/Android.bp b/tests/BinderLeakTest/Android.bp
index 78b0ede76d4e..3747d049417f 100644
--- a/tests/BinderLeakTest/Android.bp
+++ b/tests/BinderLeakTest/Android.bp
@@ -24,6 +24,9 @@ java_defaults {
"androidx.test.rules",
"androidx.test.runner",
],
+ test_suites: [
+ "general-tests",
+ ],
}
// Built with target_sdk_version: current
diff --git a/tests/Input/src/com/android/test/input/InputDeviceTest.java b/tests/Input/src/com/android/test/input/InputDeviceTest.java
index 5f1bc8748db8..87a0de63120e 100644
--- a/tests/Input/src/com/android/test/input/InputDeviceTest.java
+++ b/tests/Input/src/com/android/test/input/InputDeviceTest.java
@@ -61,6 +61,7 @@ public class InputDeviceTest {
assertEquals(device.getMotionRanges().size(), outDevice.getMotionRanges().size());
assertEquals(device.getHostUsiVersion(), outDevice.getHostUsiVersion());
assertEquals(device.getAssociatedDisplayId(), outDevice.getAssociatedDisplayId());
+ assertEquals(device.isEnabled(), outDevice.isEnabled());
KeyCharacterMap keyCharacterMap = device.getKeyCharacterMap();
KeyCharacterMap outKeyCharacterMap = outDevice.getKeyCharacterMap();
@@ -100,7 +101,9 @@ public class InputDeviceTest {
.setKeyboardLanguageTag("en-US")
.setKeyboardLayoutType("qwerty")
.setUsiVersion(new HostUsiVersion(2, 0))
- .setShouldSmoothScroll(true);
+ .setShouldSmoothScroll(true)
+ .setAssociatedDisplayId(Display.DEFAULT_DISPLAY)
+ .setEnabled(false);
for (int i = 0; i < 30; i++) {
deviceBuilder.addMotionRange(