summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp22
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java6
-rw-r--r--api/Android.bp1
-rw-r--r--api/javadoc-lint-baseline109
-rw-r--r--core/api/current.txt13
-rw-r--r--core/api/test-current.txt24
-rw-r--r--core/api/test-lint-baseline.txt10
-rw-r--r--core/java/Android.bp10
-rw-r--r--core/java/android/app/ActivityManager.java2
-rw-r--r--core/java/android/app/ActivityThread.java27
-rw-r--r--core/java/android/app/AppOpsManager.java32
-rw-r--r--core/java/android/app/ApplicationPackageManager.java11
-rw-r--r--core/java/android/companion/virtual/flags.aconfig8
-rw-r--r--core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl65
-rw-r--r--core/java/android/companion/virtualnative/OWNERS1
-rw-r--r--core/java/android/content/Intent.java14
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageInstaller.java7
-rw-r--r--core/java/android/content/pm/PackageManager.java13
-rw-r--r--core/java/android/content/pm/multiuser.aconfig15
-rw-r--r--core/java/android/credentials/GetCandidateCredentialsResponse.java9
-rw-r--r--core/java/android/hardware/input/KeyboardLayout.java4
-rw-r--r--core/java/android/os/vibrator/flags.aconfig9
-rw-r--r--core/java/android/os/vibrator/persistence/ParsedVibration.java2
-rw-r--r--core/java/android/os/vibrator/persistence/VibrationXmlParser.java2
-rw-r--r--core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java2
-rw-r--r--core/java/android/provider/Settings.java45
-rw-r--r--core/java/android/service/autofill/Dataset.java38
-rw-r--r--core/java/android/service/credentials/CredentialProviderService.java12
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java16
-rw-r--r--core/java/android/service/notification/NotificationRankingUpdate.java86
-rw-r--r--core/java/android/telephony/PhoneStateListener.java6
-rw-r--r--core/java/android/telephony/SubscriptionPlan.java4
-rw-r--r--core/java/android/telephony/TelephonyCallback.java4
-rw-r--r--core/java/android/telephony/TelephonyRegistryManager.java2
-rw-r--r--core/java/android/text/DynamicLayout.java6
-rw-r--r--core/java/android/text/FontConfig.java149
-rw-r--r--core/java/android/text/MeasuredParagraph.java7
-rw-r--r--core/java/android/text/StaticLayout.java4
-rw-r--r--core/java/android/text/flags/custom_locale_fallback.aconfig8
-rw-r--r--core/java/android/text/style/LineBreakConfigSpan.java24
-rw-r--r--core/java/android/view/IDecorViewGestureListener.aidl32
-rw-r--r--core/java/android/view/IRecentsAnimationController.aidl4
-rw-r--r--core/java/android/view/IWindowManager.aidl15
-rw-r--r--core/java/android/view/IWindowSession.aidl5
-rw-r--r--core/java/android/view/InputWindowHandle.java13
-rw-r--r--core/java/android/view/SurfaceControl.java25
-rw-r--r--core/java/android/view/ViewRootImpl.java27
-rw-r--r--core/java/android/view/WindowlessWindowManager.java10
-rw-r--r--core/java/android/view/autofill/AutofillManager.java42
-rw-r--r--core/java/android/view/flags/refresh_rate_flags.aconfig (renamed from core/java/android/view/flags/variable_refresh_rate_flags.aconfig)7
-rw-r--r--core/java/android/widget/AbsListView.java6
-rw-r--r--core/java/android/widget/DifferentialMotionFlingHelper.java14
-rw-r--r--core/java/android/widget/ScrollView.java6
-rw-r--r--core/java/android/widget/TextView.java12
-rw-r--r--core/java/android/widget/flags/differential_motion_fling_flags.aconfig8
-rw-r--r--core/java/android/widget/flags/scroll_view_flags.aconfig8
-rw-r--r--core/java/android/window/SystemPerformanceHinter.java24
-rw-r--r--core/java/android/window/flags/window_surfaces.aconfig11
-rw-r--r--core/java/com/android/internal/display/RefreshRateSettingsUtils.java56
-rw-r--r--core/java/com/android/internal/foldables/OWNERS1
-rw-r--r--core/java/com/android/internal/policy/DecorView.java20
-rw-r--r--core/java/com/android/internal/policy/WearGestureInterceptionDetector.java211
-rw-r--r--core/jni/android_view_SurfaceControl.cpp7
-rw-r--r--core/proto/android/providers/settings/secure.proto1
-rw-r--r--core/res/AndroidManifest.xml8
-rw-r--r--core/res/res/layout/autofill_save.xml3
-rw-r--r--core/res/res/values-watch/dimens_material.xml3
-rw-r--r--core/res/res/values-watch/styles_material.xml4
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/BroadcastRadioTests/Android.bp2
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java78
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java83
-rw-r--r--core/tests/GameManagerTests/Android.bp2
-rw-r--r--core/tests/PackageInstallerSessions/Android.bp2
-rw-r--r--core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp2
-rw-r--r--core/tests/bugreports/Android.bp2
-rw-r--r--core/tests/coretests/Android.bp5
-rw-r--r--core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java135
-rw-r--r--core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java605
-rw-r--r--core/tests/coretests/src/android/widget/DifferentialMotionFlingHelperTest.java21
-rw-r--r--core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java70
-rw-r--r--core/tests/hdmitests/Android.bp2
-rw-r--r--core/tests/mockingcoretests/Android.bp2
-rw-r--r--core/tests/nfctests/Android.bp2
-rw-r--r--core/tests/overlaytests/device_self_targeting/Android.bp2
-rw-r--r--core/tests/packagemonitortests/Android.bp2
-rw-r--r--core/tests/privacytests/Android.bp2
-rw-r--r--core/tests/utiltests/Android.bp2
-rw-r--r--core/tests/vibrator/Android.bp2
-rw-r--r--errorprone/Android.bp2
-rw-r--r--graphics/java/android/graphics/Canvas.java3
-rw-r--r--graphics/java/android/graphics/FontListParser.java4
-rw-r--r--graphics/java/android/graphics/fonts/FontCustomizationParser.java46
-rw-r--r--graphics/java/android/graphics/fonts/SystemFonts.java97
-rw-r--r--graphics/java/android/graphics/text/LineBreakConfig.java17
-rw-r--r--keystore/java/android/security/AndroidKeyStoreMaintenance.java14
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/Android.bp2
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java38
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java16
-rw-r--r--libs/WindowManager/Shell/tests/unittest/Android.bp2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java33
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java91
-rw-r--r--libs/dream/lowlight/tests/Android.bp2
-rw-r--r--libs/securebox/tests/Android.bp2
-rw-r--r--media/java/android/media/RingtoneSelection.java348
-rw-r--r--media/java/android/media/flags/media_better_together.aconfig15
-rw-r--r--media/tests/MediaFrameworkTest/Android.bp2
-rw-r--r--media/tests/MediaRouter/Android.bp2
-rw-r--r--media/tests/projection/Android.bp2
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt47
-rw-r--r--packages/ExternalStorageProvider/tests/Android.bp2
-rw-r--r--packages/FusedLocation/Android.bp6
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_brazilian.kcm2
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_persian.kcm4
-rw-r--r--packages/InputDevices/res/xml/keyboard_layouts.xml7
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt4
-rw-r--r--packages/SettingsLib/Spa/testutils/Android.bp2
-rw-r--r--packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig7
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-eu/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml3
-rw-r--r--packages/SettingsLib/tests/integ/Android.bp2
-rw-r--r--packages/SettingsLib/tests/robotests/Android.bp2
-rw-r--r--packages/SettingsLib/tests/unit/Android.bp2
-rw-r--r--packages/SettingsProvider/Android.bp2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java6
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java8
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java57
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java5
-rw-r--r--packages/SystemUI/Android.bp4
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp2
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt91
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt17
-rw-r--r--packages/SystemUI/compose/core/tests/Android.bp2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt7
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt8
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt27
-rw-r--r--packages/SystemUI/customization/res/values-af/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-am/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ar/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-as/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-az/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-be/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-bg/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-bn/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-bs/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ca/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-cs/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-da/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-de/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-el/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-en-rAU/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-en-rCA/strings.xml23
-rw-r--r--packages/SystemUI/customization/res/values-en-rGB/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-en-rIN/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-en-rXC/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-es-rUS/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-es/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-et/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-eu/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-fa/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-fi/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-fr-rCA/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-fr/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-gl/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-gu/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-hi/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-hr/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-hu/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-hy/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-in/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-is/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-it/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-iw/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ja/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ka/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-kk/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-km/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-kn/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ko/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ky/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-lo/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-lt/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-lv/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-mk/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ml/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-mn/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-mr/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ms/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-my/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-nb/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ne/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-nl/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-or/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-pa/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-pl/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-pt-rPT/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-pt/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ro/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ru/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-si/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-sk/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-sl/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-sq/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-sr/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-sv/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-sw/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ta/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-te/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-th/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-tl/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-tr/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-uk/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-ur/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-uz/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-vi/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-zh-rCN/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-zh-rHK/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-zh-rTW/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values-zu/strings.xml22
-rw-r--r--packages/SystemUI/customization/res/values/strings.xml25
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt8
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt4
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt11
-rw-r--r--packages/SystemUI/res/layout/internet_connectivity_dialog.xml20
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_footer.xml4
-rw-r--r--packages/SystemUI/res/values-af/strings.xml6
-rw-r--r--packages/SystemUI/res/values-am/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml6
-rw-r--r--packages/SystemUI/res/values-as/strings.xml6
-rw-r--r--packages/SystemUI/res/values-az/strings.xml6
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-be/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml6
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-da/strings.xml6
-rw-r--r--packages/SystemUI/res/values-de/strings.xml6
-rw-r--r--packages/SystemUI/res/values-el/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml6
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml6
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml6
-rw-r--r--packages/SystemUI/res/values-es/strings.xml6
-rw-r--r--packages/SystemUI/res/values-et/strings.xml6
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml10
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml6
-rw-r--r--packages/SystemUI/res/values-in/strings.xml6
-rw-r--r--packages/SystemUI/res/values-is/strings.xml6
-rw-r--r--packages/SystemUI/res/values-it/strings.xml6
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-km/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml6
-rw-r--r--packages/SystemUI/res/values-my/strings.xml6
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml6
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-or/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml6
-rw-r--r--packages/SystemUI/res/values-si/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml6
-rw-r--r--packages/SystemUI/res/values-te/strings.xml6
-rw-r--r--packages/SystemUI/res/values-th/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml6
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml6
-rw-r--r--packages/SystemUI/res/values/dimens.xml2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java11
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ClockEventController.kt24
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java9
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java29
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepository.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryModule.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractor.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt69
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProvider.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/model/SysUiState.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepository.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractor.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt156
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt148
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt85
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/TestMocksModule.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java82
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorTest.kt117
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerTest.kt147
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt113
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt99
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepositoryTest.kt102
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt89
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt225
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java1
-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/StackScrollAlgorithmTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt98
-rw-r--r--packages/SystemUI/tests/utils/src/android/animation/PlatformAnimatorIsolationRule.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestDependency.kt26
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/FakeAuthenticationDataLayerModule.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt20
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt25
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt30
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeNotificationsKeyguardViewStateRepository.kt49
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutorModule.kt15
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockModule.kt30
-rw-r--r--packages/WallpaperBackup/Android.bp2
-rw-r--r--packages/overlays/tests/Android.bp2
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java32
-rw-r--r--services/autofill/Android.bp15
-rw-r--r--services/autofill/bugfixes.aconfig7
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java14
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java21
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java21
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java6
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java46
-rw-r--r--services/core/java/com/android/server/am/AppProfiler.java4
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java5
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java4
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java247
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java11
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java23
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig8
-rw-r--r--services/core/java/com/android/server/display/mode/DisplayModeDirector.java43
-rw-r--r--services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java4
-rw-r--r--services/core/java/com/android/server/input/GestureMonitorSpyWindow.java4
-rw-r--r--services/core/java/com/android/server/input/KeyboardLayoutManager.java9
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java4
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java14
-rw-r--r--services/core/java/com/android/server/pm/Computer.java3
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java7
-rw-r--r--services/core/java/com/android/server/pm/IPackageManagerBase.java6
-rw-r--r--services/core/java/com/android/server/pm/InstallRequest.java56
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java31
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java42
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java17
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java73
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java38
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java4
-rw-r--r--services/core/java/com/android/server/wm/CompatModePackages.java195
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java24
-rw-r--r--services/core/java/com/android/server/wm/DragState.java10
-rw-r--r--services/core/java/com/android/server/wm/InputConsumerImpl.java4
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java7
-rw-r--r--services/core/java/com/android/server/wm/InputWindowHandleWrapper.java5
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java11
-rw-r--r--services/core/java/com/android/server/wm/Session.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java68
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java22
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd39
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt26
-rw-r--r--services/core/xsd/display-layout-config/display-layout-config.xsd1
-rw-r--r--services/core/xsd/display-layout-config/schema/current.txt2
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerService.java369
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerUi.java7
-rw-r--r--services/credentials/java/com/android/server/credentials/ProviderGetSession.java20
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java15
-rw-r--r--services/foldables/devicestateprovider/tests/Android.bp4
-rw-r--r--services/robotests/backup/Android.bp2
-rw-r--r--services/tests/InputMethodSystemServerTests/Android.bp4
-rw-r--r--services/tests/PackageManager/packageinstaller/Android.bp2
-rw-r--r--services/tests/PackageManagerComponentOverrideTests/Android.bp2
-rw-r--r--services/tests/PackageManagerServiceTests/appenumeration/Android.bp2
-rw-r--r--services/tests/PackageManagerServiceTests/host/Android.bp2
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp2
-rw-r--r--services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp2
-rw-r--r--services/tests/PackageManagerServiceTests/server/Android.bp4
-rw-r--r--services/tests/PackageManagerServiceTests/unit/Android.bp2
-rw-r--r--services/tests/RemoteProvisioningServiceTests/Android.bp4
-rw-r--r--services/tests/apexsystemservices/Android.bp2
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java142
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java85
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java34
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java122
-rw-r--r--services/tests/inprocesstests/Android.bp2
-rw-r--r--services/tests/mockingservicestests/Android.bp2
-rw-r--r--services/tests/powerstatstests/Android.bp2
-rw-r--r--services/tests/servicestests/Android.bp4
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java23
-rw-r--r--services/tests/uiservicestests/Android.bp2
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java122
-rw-r--r--services/tests/voiceinteractiontests/Android.bp2
-rw-r--r--services/tests/wmtests/Android.bp4
-rw-r--r--services/tests/wmtests/AndroidManifest.xml7
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java217
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java293
-rw-r--r--telecomm/java/android/telecom/Call.java2
-rw-r--r--telecomm/java/android/telecom/CallControl.java2
-rw-r--r--telecomm/java/android/telecom/CallControlCallback.java2
-rw-r--r--telecomm/java/android/telecom/PhoneAccountSuggestion.java2
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java79
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationInfo.java2
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java9
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java11
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java8
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java2
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java2
-rw-r--r--telephony/java/android/telephony/ims/ImsRcsManager.java2
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java9
-rw-r--r--telephony/java/android/telephony/ims/RegistrationManager.java5
-rw-r--r--tests/BatteryStatsPerfTest/Android.bp2
-rw-r--r--tests/BinaryTransparencyHostTest/Android.bp2
-rw-r--r--tests/BlobStoreTestUtils/Android.bp16
-rw-r--r--tests/ChoreographerTests/Android.bp2
-rw-r--r--tests/CtsSurfaceControlTestsStaging/Android.bp2
-rw-r--r--tests/DynamicCodeLoggerIntegrationTests/Android.bp2
-rw-r--r--tests/FlickerTests/Android.bp4
-rw-r--r--tests/Input/Android.bp6
-rw-r--r--tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt172
-rw-r--r--tests/InputMethodStressTest/Android.bp2
-rw-r--r--tests/InputScreenshotTest/Android.bp4
-rw-r--r--tests/Internal/Android.bp2
-rw-r--r--tests/LocalizationTest/Android.bp2
-rw-r--r--tests/MidiTests/Android.bp2
-rw-r--r--tests/PackageWatchdog/Android.bp2
-rw-r--r--tests/PlatformCompatGating/Android.bp2
-rw-r--r--tests/PlatformCompatGating/test-rules/Android.bp4
-rw-r--r--tests/SurfaceViewBufferTests/Android.bp2
-rw-r--r--tests/TaskOrganizerTest/Android.bp2
-rw-r--r--tests/TelephonyCommonTests/Android.bp4
-rw-r--r--tests/TrustTests/Android.bp2
-rw-r--r--tests/UpdatableSystemFontTest/Android.bp2
-rw-r--r--tests/UsbManagerTests/Android.bp2
-rw-r--r--tests/UsbManagerTests/lib/Android.bp2
-rw-r--r--tests/UsbTests/Android.bp2
-rw-r--r--tests/componentalias/Android.bp2
-rw-r--r--tools/aapt2/Android.bp1
-rw-r--r--tools/aapt2/java/AnnotationProcessor.cpp16
-rw-r--r--tools/aapt2/java/AnnotationProcessor_test.cpp30
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp2
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp2
-rw-r--r--tools/processors/immutability/Android.bp2
-rw-r--r--tools/processors/intdef_mappings/Android.bp2
-rw-r--r--wifi/tests/Android.bp2
651 files changed, 9942 insertions, 2749 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index c30164c065af..864caf4da9fd 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -42,6 +42,7 @@ aconfig_srcjars = [
":android.credentials.flags-aconfig-java{.generated_srcjars}",
":android.view.contentprotection.flags-aconfig-java{.generated_srcjars}",
":android.service.voice.flags-aconfig-java{.generated_srcjars}",
+ ":android.service.autofill.flags-aconfig-java{.generated_srcjars}",
]
filegroup {
@@ -242,6 +243,11 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+cc_aconfig_library {
+ name: "aconfig_view_flags_c_lib",
+ aconfig_declarations: "android.view.flags-aconfig",
+}
+
// View.accessibility
aconfig_declarations {
name: "android.view.accessibility.flags-aconfig",
@@ -416,3 +422,19 @@ java_aconfig_library {
aconfig_declarations: "android.service.voice.flags-aconfig",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+
+// Autofill
+aconfig_declarations {
+ name: "android.service.autofill.flags-aconfig",
+ package: "android.service.autofill",
+ srcs: [
+ "services/autofill/bugfixes.aconfig",
+ "services/autofill/features.aconfig"
+ ],
+}
+
+java_aconfig_library {
+ name: "android.service.autofill.flags-aconfig-java",
+ aconfig_declarations: "android.service.autofill.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 43d2ae9e077b..f47766ed0393 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -1335,13 +1335,13 @@ public final class JobServiceContext implements ServiceConnection {
private void handleOpTimeoutLocked() {
switch (mVerb) {
case VERB_BINDING:
- onSlowAppResponseLocked(/* reschedule */ false, /* updateStopReasons */ true,
+ // The system may have been too busy. Don't drop the job or trigger an ANR.
+ onSlowAppResponseLocked(/* reschedule */ true, /* updateStopReasons */ true,
/* texCounterMetricId */
"job_scheduler.value_cntr_w_uid_slow_app_response_binding",
/* debugReason */ "timed out while binding",
/* anrMessage */ "Timed out while trying to bind",
- CompatChanges.isChangeEnabled(ANR_PRE_UDC_APIS_ON_SLOW_RESPONSES,
- mRunningJob.getUid()));
+ /* triggerAnr */ false);
break;
case VERB_STARTING:
// Client unresponsive - wedged or failed to respond in time. We don't really
diff --git a/api/Android.bp b/api/Android.bp
index 45e70719e6c0..222275f9a4e4 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -82,7 +82,6 @@ combined_apis {
"framework-media",
"framework-mediaprovider",
"framework-ondevicepersonalization",
- "framework-pdf",
"framework-permission",
"framework-permission-s",
"framework-scheduling",
diff --git a/api/javadoc-lint-baseline b/api/javadoc-lint-baseline
index 871312640acf..2cc5078c8844 100644
--- a/api/javadoc-lint-baseline
+++ b/api/javadoc-lint-baseline
@@ -8,9 +8,12 @@ android/adservices/ondevicepersonalization/ExecuteOutput.java:20: lint: Unresolv
android/adservices/ondevicepersonalization/ExecuteOutput.java:31: lint: Unresolved link/see tag "android.adservices.ondevicepersonalization.IsolatedWorker#onExecute() IsolatedWorker#onExecute()" in android.adservices.ondevicepersonalization.ExecuteOutput [101]
android/adservices/ondevicepersonalization/ExecuteOutput.java:93: lint: Unresolved link/see tag "android.adservices.ondevicepersonalization.IsolatedWorker#onExecute() IsolatedWorker#onExecute()" in android.adservices.ondevicepersonalization.ExecuteOutput.Builder [101]
android/adservices/ondevicepersonalization/IsolatedService.java:18: lint: Unresolved link/see tag "SurfaceView" in android.adservices.ondevicepersonalization.IsolatedService [101]
+android/adservices/ondevicepersonalization/IsolatedService.java:18: lint: Unresolved link/see tag "android.adservices.ondevicepersonalization.OnDevicePersonalizationManager#execute" in android.adservices.ondevicepersonalization.IsolatedService [101]
android/adservices/ondevicepersonalization/IsolatedService.java:119: lint: Unresolved link/see tag "IsolatedCmputationCallback#onWebViewEvent()" in android.adservices.ondevicepersonalization.IsolatedService [101]
+android/adservices/ondevicepersonalization/IsolatedService.java:119: lint: Unresolved link/see tag "IsolatedCmputationCallback#onEvent()" in android.adservices.ondevicepersonalization.IsolatedService [101]
android/adservices/ondevicepersonalization/IsolatedService.java:119: lint: Unresolved link/see tag "WebView" in android.adservices.ondevicepersonalization.IsolatedService [101]
android/adservices/ondevicepersonalization/IsolatedWorker.java:9: lint: Unresolved link/see tag "RunTimeException" in android.adservices.ondevicepersonalization.IsolatedWorker [101]
+android/adservices/ondevicepersonalization/IsolatedWorker.java:24: lint: Unresolved link/see tag "android.adservices.ondevicepersonalization.OnDevicePersonalizationManager#execute" in android.adservices.ondevicepersonalization.IsolatedWorker [101]
android/adservices/ondevicepersonalization/IsolatedWorker.java:57: lint: Unresolved link/see tag "#onExecute()" in android.adservices.ondevicepersonalization.IsolatedWorker [101]
android/adservices/ondevicepersonalization/IsolatedWorker.java:74: lint: Unresolved link/see tag "#onRender()" in android.adservices.ondevicepersonalization.IsolatedWorker [101]
android/adservices/ondevicepersonalization/OnDevicePersonalizationManager.java:-11: lint: Unresolved link/see tag "requestSurfacePackage" in android.adservices.ondevicepersonalization.OnDevicePersonalizationManager [101]
@@ -226,40 +229,6 @@ android/service/notification/NotificationListenerService.java:1155: lint: Unreso
android/service/notification/NotificationListenerService.java:1166: lint: Unresolved link/see tag "android.service.notification.NotificationAssistantService NotificationAssistantService" in android.service.notification.NotificationListenerService.Ranking [101]
android/service/quickaccesswallet/WalletCard.java:285: lint: Unresolved link/see tag "PackageManager.FEATURE_WALLET_LOCATION_BASED_SUGGESTIONS" in android.service.quickaccesswallet.WalletCard.Builder [101]
android/service/voice/VoiceInteractionSession.java:293: lint: Unresolved link/see tag "android.service.voice.VoiceInteractionService#KEY_SHOW_SESSION_ID VoiceInteractionService#KEY_SHOW_SESSION_ID" in android.service.voice.VoiceInteractionSession [101]
-android/telecom/Call.java:94: lint: unable to parse link/see tag: #playDtmfTone(char [101]
-android/telecom/CallControl.java:163: lint: Unresolved link/see tag "android.telecom.CallStreamingService CallStreamingService" in android.telecom.CallControl [101]
-android/telecom/CallControlCallback.java:63: lint: Unresolved link/see tag "android.telecom.CallAttributes.CallType" in android.telecom.CallControlCallback [101]
-android/telecom/PhoneAccountSuggestion.java:17: lint: Unresolved link/see tag "android.telecom.PhoneAccountSuggestionService PhoneAccountSuggestionService" in android.telecom.PhoneAccountSuggestion [101]
-android/telephony/CarrierConfigManager.java:2934: lint: Unresolved link/see tag "android.telephony.TelephonyManager.PremiumCapability TelephonyManager.PremiumCapability" in android.telephony.CarrierConfigManager [101]
-android/telephony/CarrierConfigManager.java:4020: lint: Unresolved link/see tag "ImsRegistrationImplBase.ImsRegistrationTech" in android.telephony.CarrierConfigManager.Ims [101]
-android/telephony/CarrierConfigManager.java:4108: lint: Unresolved link/see tag "ImsRegistrationImplBase.ImsRegistrationTech" in android.telephony.CarrierConfigManager.Ims [101]
-android/telephony/CarrierConfigManager.java:3920: lint: Unresolved link/see tag "android.telephony.ims.SipDelegateManager" in android.telephony.CarrierConfigManager.Ims [101]
-android/telephony/CarrierConfigManager.java:4001: lint: Unresolved link/see tag "ImsRegistrationImplBase.ImsRegistrationTech" in android.telephony.CarrierConfigManager.Ims [101]
-android/telephony/CarrierConfigManager.java:4089: lint: Unresolved link/see tag "ImsRegistrationImplBase.ImsRegistrationTech" in android.telephony.CarrierConfigManager.Ims [101]
-android/telephony/NetworkRegistrationInfo.java:131: lint: Unresolved link/see tag "android.telephony.Annotation.NetworkType NetworkType" in android.telephony.NetworkRegistrationInfo [101]
-android/telephony/PhoneStateListener.java:293: lint: Unresolved link/see tag "android.telephony.PreciseDisconnectCause PreciseDisconnectCause" in android.telephony.PhoneStateListener [101]
-android/telephony/PhoneStateListener.java:544: lint: Unresolved link/see tag "android.telephony.PreciseDisconnectCause PreciseDisconnectCause" in android.telephony.PhoneStateListener [101]
-android/telephony/SubscriptionManager.java:1385: lint: Unresolved link/see tag "Build.VERSION_CODES.P" in android.telephony.SubscriptionManager.OnSubscriptionsChangedListener [101]
-android/telephony/SubscriptionManager.java:1385: lint: Unresolved link/see tag "Build.VERSION_CODES.V" in android.telephony.SubscriptionManager.OnSubscriptionsChangedListener [101]
-android/telephony/SubscriptionPlan.java:134: lint: Unresolved link/see tag "android.telephony.Annotation.NetworkType NetworkType" in android.telephony.SubscriptionPlan [101]
-android/telephony/SubscriptionPlan.java:288: lint: Unresolved link/see tag "android.telephony.Annotation.NetworkType NetworkType" in android.telephony.SubscriptionPlan.Builder [101]
-android/telephony/TelephonyCallback.java:113: lint: Unresolved link/see tag "android.telephony.PreciseDisconnectCause PreciseDisconnectCause" in android.telephony.TelephonyCallback.CallDisconnectCauseListener [101]
-android/telephony/TelephonyManager.java:2544: lint: Unresolved link/see tag "android.telephony.TelephonyManager.CarrierRestrictionStatus CarrierRestrictionStatus" in android.telephony.TelephonyManager [101]
-android/telephony/TelephonyManager.java:2841: lint: Unresolved link/see tag "android.telephony.TelephonyManager.SetOpportunisticSubscriptionResult TelephonyManager.SetOpportunisticSubscriptionResult" in android.telephony.TelephonyManager [101]
-android/telephony/TelephonyManager.java:3273: lint: Unresolved link/see tag "android.telephony.TelephonyManager.PurchasePremiumCapabilityResult PurchasePremiumCapabilityResult" in android.telephony.TelephonyManager [101]
-android/telephony/TelephonyManager.java:3989: lint: Unresolved link/see tag "android.telephony.TelephonyManager.MobileDataPolicy MobileDataPolicy" in android.telephony.TelephonyManager [101]
-android/telephony/data/ApnSetting.java:39: lint: Unresolved link/see tag "android.telephony.data.DataCallResponse#getMtuV4() DataCallResponse#getMtuV4()" in android.telephony.data.ApnSetting [101]
-android/telephony/data/ApnSetting.java:50: lint: Unresolved link/see tag "android.telephony.data.DataCallResponse#getMtuV6() DataCallResponse#getMtuV6()" in android.telephony.data.ApnSetting [101]
-android/telephony/data/ApnSetting.java:597: lint: Unresolved link/see tag "android.telephony.data.DataCallResponse#getMtuV4() DataCallResponse#getMtuV4()" in android.telephony.data.ApnSetting.Builder [101]
-android/telephony/data/ApnSetting.java:611: lint: Unresolved link/see tag "android.telephony.data.DataCallResponse#getMtuV6() DataCallResponse#getMtuV6()" in android.telephony.data.ApnSetting.Builder [101]
-android/telephony/euicc/EuiccManager.java:331: lint: Unresolved link/see tag "android.service.euicc.EuiccService#ACTION_BIND_CARRIER_PROVISIONING_SERVICE" in android.telephony.euicc.EuiccManager [101]
-android/telephony/ims/ImsMmTelManager.java:117: lint: Unresolved link/see tag "android.telephony.ims.ImsService ImsService" in android.telephony.ims.ImsMmTelManager [101]
-android/telephony/ims/ImsRcsManager.java:43: lint: Unresolved link/see tag "android.telephony.ims.ImsService ImsService" in android.telephony.ims.ImsRcsManager [101]
-android/telephony/ims/ProvisioningManager.java:102: lint: Unresolved link/see tag "android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability MmTelFeature.MmTelCapabilities.MmTelCapability" in android.telephony.ims.ProvisioningManager [101]
-android/telephony/ims/ProvisioningManager.java:102: lint: Unresolved link/see tag "android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech ImsRegistrationImplBase.ImsRegistrationTech" in android.telephony.ims.ProvisioningManager [101]
-android/telephony/ims/ProvisioningManager.java:136: lint: Unresolved link/see tag "android.telephony.ims.ImsRcsManager.RcsImsCapabilityFlag ImsRcsManager.RcsImsCapabilityFlag" in android.telephony.ims.ProvisioningManager [101]
-android/telephony/ims/RegistrationManager.java:21: lint: Unresolved link/see tag "android.telephony.ims.feature.ImsFeature ImsFeature" in android.telephony.ims.RegistrationManager [101]
-android/telephony/ims/RegistrationManager.java:24: lint: Unresolved link/see tag "android.telephony.ims.ImsService ImsService" in android.telephony.ims.RegistrationManager [101]
android/text/DynamicLayout.java:141: lint: Unresolved link/see tag "LineBreakconfig" in android.text.DynamicLayout [101]
android/text/WordSegmentFinder.java:13: lint: Unresolved link/see tag "android.text.method.WordIterator WordIterator" in android.text.WordSegmentFinder [101]
android/view/InputDevice.java:71: lint: Unresolved link/see tag "InputManagerGlobal.InputDeviceListener" in android.view.InputDevice [101]
@@ -291,76 +260,6 @@ android/view/inputmethod/InputMethodManager.java:456: lint: Unresolved link/see
android/view/inspector/PropertyReader.java:141: lint: Unresolved link/see tag "android.annotation.ColorInt ColorInt" in android.view.inspector.PropertyReader [101]
android/window/BackEvent.java:24: lint: Unresolved link/see tag "android.window.BackMotionEvent BackMotionEvent" in android.window.BackEvent [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_30" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_35" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_40" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_45" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_50" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_55" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_60" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_65" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_70" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_75" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_80" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_85" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_90" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_30" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_35" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_40" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_45" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_50" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_55" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_60" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_65" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_70" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_75" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_80" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_85" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_90" in android [101]
-com/android/server/wm/CompatModePackages.java:135: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:135: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:135: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_90" in android [101]
-com/android/server/wm/CompatModePackages.java:148: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:148: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:148: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_85" in android [101]
-com/android/server/wm/CompatModePackages.java:161: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:161: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:161: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_80" in android [101]
-com/android/server/wm/CompatModePackages.java:174: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:174: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:174: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_75" in android [101]
-com/android/server/wm/CompatModePackages.java:187: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:187: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:187: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_70" in android [101]
-com/android/server/wm/CompatModePackages.java:200: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:200: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:200: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_65" in android [101]
-com/android/server/wm/CompatModePackages.java:213: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:213: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:213: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_60" in android [101]
-com/android/server/wm/CompatModePackages.java:226: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:226: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:226: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_55" in android [101]
-com/android/server/wm/CompatModePackages.java:239: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:239: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:239: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_50" in android [101]
-com/android/server/wm/CompatModePackages.java:252: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:252: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:252: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_45" in android [101]
-com/android/server/wm/CompatModePackages.java:265: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:265: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:265: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_40" in android [101]
-com/android/server/wm/CompatModePackages.java:278: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:278: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:278: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_35" in android [101]
-com/android/server/wm/CompatModePackages.java:291: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:291: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:291: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_30" in android [101]
-
android/net/wifi/SoftApConfiguration.java:173: lint: Unresolved link/see tag "android.net.wifi.SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)" in android.net.wifi.SoftApConfiguration [101]
android/content/pm/ActivityInfo.java:1197: lint: Unresolved link/see tag "android.view.ViewRootImpl" in android.content.pm.ActivityInfo [101]
android/os/UserManager.java:2384: lint: Unresolved link/see tag "android.annotation.UserHandleAware @UserHandleAware" in android.os.UserManager [101]
@@ -370,7 +269,6 @@ android/service/voice/AlwaysOnHotwordDetector.java:269: lint: Unresolved link/se
android/service/voice/AlwaysOnHotwordDetector.java:278: lint: Unresolved link/see tag "#STATE_ERROR" in android [101]
android/service/voice/AlwaysOnHotwordDetector.java:278: lint: Unresolved link/see tag "Callback#onFailure" in android [101]
android/service/voice/AlwaysOnHotwordDetector.java:278: lint: Unresolved link/see tag "Callback#onUnknownFailure" in android [101]
-android/telephony/TelephonyRegistryManager.java:242: lint: Unresolved link/see tag "#listenFromListener" in android [101]
android/view/animation/AnimationUtils.java:64: lint: Unresolved link/see tag "Build.VERSION_CODES#VANILLA_ICE_CREAM" in android.view.animation.AnimationUtils [101]
android/view/contentcapture/ContentCaptureSession.java:188: lint: Unresolved link/see tag "UPSIDE_DOWN_CAKE" in android.view.contentcapture.ContentCaptureSession [101]
com/android/internal/policy/PhoneWindow.java:172: lint: Unresolved link/see tag "Build.VERSION_CODES#VANILLA_ICE_CREAM" in com.android.internal.policy.PhoneWindow [101]
@@ -393,7 +291,6 @@ com/android/server/pm/PackageInstallerSession.java:327: lint: Unresolved link/se
com/android/server/pm/PackageInstallerSession.java:327: lint: Unresolved link/see tag "PackageInstaller.SessionParams#setRequestUpdateOwnership(boolean)" in android [101]
com/android/server/pm/PackageInstallerSession.java:358: lint: Unresolved link/see tag "IntentSender" in android [101]
com/android/server/devicepolicy/DevicePolicyManagerService.java:860: lint: Unresolved link/see tag "android.security.IKeyChainService#setGrant" in android [101]
-android/telephony/SubscriptionManager.java:1370: lint: Unresolved link/see tag "Build.VERSION_CODES.Q" in android.telephony.SubscriptionManager.OnSubscriptionsChangedListener [101]
android/companion/virtual/sensor/VirtualSensorDirectChannelWriter.java:-4: lint: Invalid tag: @Override [131]
android/companion/virtual/sensor/VirtualSensorDirectChannelWriter.java:-1: lint: Invalid tag: @Override [131]
diff --git a/core/api/current.txt b/core/api/current.txt
index d037c31e5af7..5a1561ad80da 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10992,6 +10992,7 @@ package android.content {
field public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
field public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
+ field @FlaggedApi("android.content.pm.stay_stopped") public static final String ACTION_PACKAGE_UNSTOPPED = "android.intent.action.PACKAGE_UNSTOPPED";
field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
field public static final String ACTION_PASTE = "android.intent.action.PASTE";
field public static final String ACTION_PICK = "android.intent.action.PICK";
@@ -12673,6 +12674,7 @@ package android.content.pm {
method public boolean isDeviceUpgrading();
method public abstract boolean isInstantApp();
method public abstract boolean isInstantApp(@NonNull String);
+ method @FlaggedApi("android.content.pm.stay_stopped") public boolean isPackageStopped(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method public boolean isPackageSuspended(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method public boolean isPackageSuspended();
method @CheckResult public abstract boolean isPermissionRevokedByPolicy(@NonNull String, @NonNull String);
@@ -17666,6 +17668,7 @@ package android.graphics.text {
field public static final int LINE_BREAK_STYLE_LOOSE = 1; // 0x1
field public static final int LINE_BREAK_STYLE_NONE = 0; // 0x0
field public static final int LINE_BREAK_STYLE_NORMAL = 2; // 0x2
+ field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int LINE_BREAK_STYLE_NO_BREAK = 4; // 0x4
field public static final int LINE_BREAK_STYLE_STRICT = 3; // 0x3
field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int LINE_BREAK_STYLE_UNSPECIFIED = -1; // 0xffffffff
field public static final int LINE_BREAK_WORD_STYLE_NONE = 0; // 0x0
@@ -46672,10 +46675,10 @@ package android.text {
method @NonNull public android.text.DynamicLayout.Builder setHyphenationFrequency(int);
method @NonNull public android.text.DynamicLayout.Builder setIncludePad(boolean);
method @NonNull public android.text.DynamicLayout.Builder setJustificationMode(int);
- method @NonNull public android.text.DynamicLayout.Builder setLineBreakConfig(@NonNull android.graphics.text.LineBreakConfig);
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public android.text.DynamicLayout.Builder setLineBreakConfig(@NonNull android.graphics.text.LineBreakConfig);
method @NonNull public android.text.DynamicLayout.Builder setLineSpacing(float, @FloatRange(from=0.0) float);
method @NonNull public android.text.DynamicLayout.Builder setTextDirection(@NonNull android.text.TextDirectionHeuristic);
- method @NonNull public android.text.DynamicLayout.Builder setUseBoundsForWidth(boolean);
+ method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.DynamicLayout.Builder setUseBoundsForWidth(boolean);
method @NonNull public android.text.DynamicLayout.Builder setUseLineSpacingFromFallbacks(boolean);
}
@@ -47199,7 +47202,7 @@ package android.text {
method @NonNull public android.text.StaticLayout.Builder setMaxLines(@IntRange(from=0) int);
method public android.text.StaticLayout.Builder setText(CharSequence);
method @NonNull public android.text.StaticLayout.Builder setTextDirection(@NonNull android.text.TextDirectionHeuristic);
- method @NonNull public android.text.StaticLayout.Builder setUseBoundsForWidth(boolean);
+ method @FlaggedApi("com.android.text.flags.use_bounds_for_width") @NonNull public android.text.StaticLayout.Builder setUseBoundsForWidth(boolean);
method @NonNull public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean);
}
@@ -47912,6 +47915,10 @@ package android.text.style {
method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
}
+ @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final class LineBreakConfigSpan.NoBreakSpan extends android.text.style.LineBreakConfigSpan {
+ ctor @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public LineBreakConfigSpan.NoBreakSpan();
+ }
+
@FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final class LineBreakConfigSpan.NoHyphenationSpan extends android.text.style.LineBreakConfigSpan {
ctor @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public LineBreakConfigSpan.NoHyphenationSpan();
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index db751a432dd7..b87a6407a195 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1903,7 +1903,7 @@ package android.media {
method public android.media.PlaybackParams setAudioStretchMode(int);
}
- public final class RingtoneSelection {
+ @FlaggedApi("android.os.vibrator.haptics_customization_enabled") public final class RingtoneSelection {
method @NonNull public static android.media.RingtoneSelection fromUri(@Nullable android.net.Uri, int);
method public int getSoundSource();
method @Nullable public android.net.Uri getSoundUri();
@@ -1915,14 +1915,16 @@ package android.media {
field public static final int FROM_URI_RINGTONE_SELECTION_ONLY = 3; // 0x3
field public static final int FROM_URI_RINGTONE_SELECTION_OR_SOUND = 1; // 0x1
field public static final int FROM_URI_RINGTONE_SELECTION_OR_VIBRATION = 2; // 0x2
- field public static final int SOUND_SOURCE_DEFAULT = 0; // 0x0
field public static final int SOUND_SOURCE_OFF = 1; // 0x1
+ field public static final int SOUND_SOURCE_SYSTEM_DEFAULT = 3; // 0x3
+ field public static final int SOUND_SOURCE_UNSPECIFIED = 0; // 0x0
field public static final int SOUND_SOURCE_URI = 2; // 0x2
- field public static final int VIBRATION_SOURCE_APPLICATION_PROVIDED = 3; // 0x3
+ field public static final int VIBRATION_SOURCE_APPLICATION_DEFAULT = 4; // 0x4
field public static final int VIBRATION_SOURCE_AUDIO_CHANNEL = 10; // 0xa
- field public static final int VIBRATION_SOURCE_DEFAULT = 0; // 0x0
field public static final int VIBRATION_SOURCE_HAPTIC_GENERATOR = 11; // 0xb
field public static final int VIBRATION_SOURCE_OFF = 1; // 0x1
+ field public static final int VIBRATION_SOURCE_SYSTEM_DEFAULT = 3; // 0x3
+ field public static final int VIBRATION_SOURCE_UNSPECIFIED = 0; // 0x0
field public static final int VIBRATION_SOURCE_URI = 2; // 0x2
}
@@ -2610,17 +2612,17 @@ package android.os.vibrator {
package android.os.vibrator.persistence {
- public class ParsedVibration {
+ @FlaggedApi("android.os.vibrator.enable_vibration_serialization_apis") public class ParsedVibration {
method @NonNull public java.util.List<android.os.VibrationEffect> getVibrationEffects();
method @Nullable public android.os.VibrationEffect resolve(@NonNull android.os.Vibrator);
}
- public final class VibrationXmlParser {
+ @FlaggedApi("android.os.vibrator.enable_vibration_serialization_apis") public final class VibrationXmlParser {
method @Nullable public static android.os.vibrator.persistence.ParsedVibration parseDocument(@NonNull java.io.Reader) throws java.io.IOException;
method @Nullable public static android.os.VibrationEffect parseVibrationEffect(@NonNull java.io.Reader) throws java.io.IOException;
}
- public final class VibrationXmlSerializer {
+ @FlaggedApi("android.os.vibrator.enable_vibration_serialization_apis") public final class VibrationXmlSerializer {
method public static void serialize(@NonNull android.os.VibrationEffect, @NonNull java.io.Writer) throws java.io.IOException, android.os.vibrator.persistence.VibrationXmlSerializer.SerializationFailedException;
}
@@ -3281,12 +3283,12 @@ package android.text {
}
public class MeasuredParagraph {
- method @NonNull public static android.text.MeasuredParagraph buildForStaticLayoutTest(@NonNull android.text.TextPaint, @Nullable android.graphics.text.LineBreakConfig, @NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @NonNull android.text.TextDirectionHeuristic, int, boolean, @Nullable android.text.MeasuredParagraph.StyleRunCallback);
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public static android.text.MeasuredParagraph buildForStaticLayoutTest(@NonNull android.text.TextPaint, @Nullable android.graphics.text.LineBreakConfig, @NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @NonNull android.text.TextDirectionHeuristic, int, boolean, @Nullable android.text.MeasuredParagraph.StyleRunCallback);
}
- public static interface MeasuredParagraph.StyleRunCallback {
- method public void onAppendReplacementRun(@NonNull android.graphics.Paint, @IntRange(from=0) int, @FloatRange(from=0) @Px float);
- method public void onAppendStyleRun(@NonNull android.graphics.Paint, @Nullable android.graphics.text.LineBreakConfig, @IntRange(from=0) int, boolean);
+ @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static interface MeasuredParagraph.StyleRunCallback {
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public void onAppendReplacementRun(@NonNull android.graphics.Paint, @IntRange(from=0) int, @FloatRange(from=0) @Px float);
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public void onAppendStyleRun(@NonNull android.graphics.Paint, @Nullable android.graphics.text.LineBreakConfig, @IntRange(from=0) int, boolean);
}
public static final class Selection.MemoryTextWatcher implements android.text.TextWatcher {
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 107be8be42e2..93e39d5f41f7 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -191,8 +191,14 @@ UnflaggedApi: android.media.RingtoneSelection#SOUND_SOURCE_DEFAULT:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.SOUND_SOURCE_DEFAULT
UnflaggedApi: android.media.RingtoneSelection#SOUND_SOURCE_OFF:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.SOUND_SOURCE_OFF
+UnflaggedApi: android.media.RingtoneSelection#SOUND_SOURCE_SYSTEM_DEFAULT:
+ New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.SOUND_SOURCE_SYSTEM_DEFAULT
+UnflaggedApi: android.media.RingtoneSelection#SOUND_SOURCE_UNSPECIFIED:
+ New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.SOUND_SOURCE_UNSPECIFIED
UnflaggedApi: android.media.RingtoneSelection#SOUND_SOURCE_URI:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.SOUND_SOURCE_URI
+UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_APPLICATION_DEFAULT:
+ New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_APPLICATION_DEFAULT
UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_APPLICATION_PROVIDED:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_APPLICATION_PROVIDED
UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_AUDIO_CHANNEL:
@@ -203,6 +209,10 @@ UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_HAPTIC_GENERATOR:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_HAPTIC_GENERATOR
UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_OFF:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_OFF
+UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_SYSTEM_DEFAULT:
+ New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_SYSTEM_DEFAULT
+UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_UNSPECIFIED:
+ New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_UNSPECIFIED
UnflaggedApi: android.media.RingtoneSelection#VIBRATION_SOURCE_URI:
New API must be flagged with @FlaggedApi: field android.media.RingtoneSelection.VIBRATION_SOURCE_URI
UnflaggedApi: android.media.RingtoneSelection#fromUri(android.net.Uri, int):
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 13a1bd6ca176..c3f3d875b0e0 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -431,6 +431,16 @@ aidl_interface {
},
}
+aidl_interface {
+ name: "android.companion.virtual.virtualdevice_aidl",
+ unstable: true,
+ host_supported: true,
+ srcs: [
+ "android/companion/virtualnative/IVirtualDeviceManagerNative.aidl",
+ ],
+ local_include_dir: ".",
+}
+
filegroup {
name: "frameworks-base-java-overview",
srcs: ["overview.html"],
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 3bf2ccaf9923..f68681b54e48 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4288,7 +4288,7 @@ public class ActivityManager {
}
/**
- * Start monitoring changes to the imoportance of uids running in the system.
+ * Start monitoring changes to the importance of uids running in the system.
* @param listener The listener callback that will receive change reports.
* @param importanceCutpoint The level of importance in which the caller is interested
* in differences. For example, if {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9a90df93b2cd..e12181a08db3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -101,6 +101,7 @@ import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.ResourcesImpl;
import android.content.res.loader.ResourcesLoader;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDebug;
@@ -297,6 +298,7 @@ public final class ActivityThread extends ClientTransactionHandler
public static final boolean DEBUG_MEMORY_TRIM = false;
private static final boolean DEBUG_PROVIDER = false;
public static final boolean DEBUG_ORDER = false;
+ private static final boolean DEBUG_APP_INFO = true;
private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
/**
* The delay to release the provider when it has no more references. It reduces the number of
@@ -6473,10 +6475,35 @@ public final class ActivityThread extends ClientTransactionHandler
resApk.updateApplicationInfo(ai, oldPaths);
}
+ ResourcesImpl beforeImpl = getApplication().getResources().getImpl();
+
synchronized (mResourcesManager) {
// Update all affected Resources objects to use new ResourcesImpl
mResourcesManager.applyAllPendingAppInfoUpdates();
}
+
+ ResourcesImpl afterImpl = getApplication().getResources().getImpl();
+
+ if ((beforeImpl != afterImpl) && !Arrays.equals(beforeImpl.getAssets().getApkAssets(),
+ afterImpl.getAssets().getApkAssets())) {
+ List<String> beforeAssets = Arrays.asList(beforeImpl.getAssets().getApkPaths());
+ List<String> afterAssets = Arrays.asList(afterImpl.getAssets().getApkPaths());
+
+ List<String> onlyBefore = new ArrayList<>(beforeAssets);
+ onlyBefore.removeAll(afterAssets);
+ List<String> onlyAfter = new ArrayList<>(afterAssets);
+ onlyAfter.removeAll(beforeAssets);
+
+ Slog.i(TAG, "ApplicationInfo updating for " + ai.packageName + ", new timestamp: "
+ + ai.createTimestamp + "\nassets removed: " + onlyBefore + "\nassets added: "
+ + onlyAfter);
+
+ if (DEBUG_APP_INFO) {
+ Slog.v(TAG, "ApplicationInfo updating for " + ai.packageName
+ + ", assets before change: " + beforeAssets + "\n assets after change: "
+ + afterAssets);
+ }
+ }
}
/**
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ca10d144d4cd..68589456dec3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1478,7 +1478,8 @@ public class AppOpsManager {
AppProtoEnums.APP_OP_RECORD_AUDIO_SANDBOXED;
/**
- * Allows the assistant app to receive the PCC-validated hotword and be voice-triggered.
+ * Allows the assistant app to be voice-triggered by detected hotwords from a trusted detection
+ * service.
*
* @hide
*/
@@ -1486,13 +1487,13 @@ public class AppOpsManager {
AppProtoEnums.APP_OP_RECEIVE_SANDBOX_TRIGGER_AUDIO;
/**
- * Allows the assistant app to get the training data from the PCC sandbox to improve the
+ * Allows the assistant app to get the training data from the trusted process to improve the
* hotword training model.
*
* @hide
*/
- public static final int OP_RECEIVE_SANDBOX_TRAINING_DATA =
- AppProtoEnums.APP_OP_RECEIVE_SANDBOX_TRAINING_DATA;
+ public static final int OP_RECEIVE_TRUSTED_PROCESS_TRAINING_DATA =
+ AppProtoEnums.APP_OP_RECEIVE_TRUSTED_PROCESS_TRAINING_DATA;
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -1640,7 +1641,7 @@ public class AppOpsManager {
OPSTR_CAMERA_SANDBOXED,
OPSTR_RECORD_AUDIO_SANDBOXED,
OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO,
- OPSTR_RECEIVE_SANDBOX_TRAINING_DATA
+ OPSTR_RECEIVE_TRUSTED_PROCESS_TRAINING_DATA
})
public @interface AppOpString {}
@@ -2252,7 +2253,8 @@ public class AppOpsManager {
public static final String OPSTR_USE_FULL_SCREEN_INTENT = "android:use_full_screen_intent";
/**
- * Allows the assistant app to receive the PCC-validated hotword and be voice-triggered.
+ * Allows the assistant app to be voice-triggered by detected hotwords from a trusted detection
+ * service.
*
* @hide
*/
@@ -2261,13 +2263,13 @@ public class AppOpsManager {
"android:receive_sandbox_trigger_audio";
/**
- * Allows the assistant app to get the training data from the PCC sandbox to improve
+ * Allows the assistant app to get the training data from the trusted process to improve
* the hotword training model.
*
* @hide
*/
- public static final String OPSTR_RECEIVE_SANDBOX_TRAINING_DATA =
- "android:receive_sandbox_training_data";
+ public static final String OPSTR_RECEIVE_TRUSTED_PROCESS_TRAINING_DATA =
+ "android:receive_trusted_process_training_data";
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
@@ -2379,7 +2381,8 @@ public class AppOpsManager {
OP_RUN_USER_INITIATED_JOBS,
OP_FOREGROUND_SERVICE_SPECIAL_USE,
OP_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
- OP_USE_FULL_SCREEN_INTENT
+ OP_USE_FULL_SCREEN_INTENT,
+ OP_RECEIVE_SANDBOX_TRIGGER_AUDIO
};
static final AppOpInfo[] sAppOpInfos = new AppOpInfo[]{
@@ -2810,10 +2813,11 @@ public class AppOpsManager {
new AppOpInfo.Builder(OP_RECEIVE_SANDBOX_TRIGGER_AUDIO,
OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO,
"RECEIVE_SANDBOX_TRIGGER_AUDIO")
- .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
- new AppOpInfo.Builder(OP_RECEIVE_SANDBOX_TRAINING_DATA,
- OPSTR_RECEIVE_SANDBOX_TRAINING_DATA,
- "RECEIVE_SANDBOX_TRAINING_DATA").build()
+ .setPermission(Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO)
+ .setDefaultMode(AppOpsManager.MODE_DEFAULT).build(),
+ new AppOpInfo.Builder(OP_RECEIVE_TRUSTED_PROCESS_TRAINING_DATA,
+ OPSTR_RECEIVE_TRUSTED_PROCESS_TRAINING_DATA,
+ "RECEIVE_TRUSTED_PROCESS_TRAINING_DATA").build()
};
// The number of longs needed to form a full bitmask of app ops
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e5a73be5023a..21ed098f448a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2954,6 +2954,17 @@ public class ApplicationPackageManager extends PackageManager {
}
}
+ @Override
+ public boolean isPackageStopped(@NonNull String packageName) throws NameNotFoundException {
+ try {
+ return mPM.isPackageStoppedForUser(packageName, getUserId());
+ } catch (IllegalArgumentException ie) {
+ throw new NameNotFoundException(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/** @hide */
@Override
public void setApplicationCategoryHint(String packageName, int categoryHint) {
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index d0e13cd977ef..cf274f5cbbb9 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -8,6 +8,14 @@ flag {
}
flag {
+ name: "enable_native_vdm"
+ namespace: "virtual_devices"
+ description: "Enable native VDM service"
+ bug: "303535376"
+ is_fixed_read_only: true
+}
+
+flag {
name: "dynamic_policy"
namespace: "virtual_devices"
description: "Enable dynamic policy API"
diff --git a/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl b/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl
new file mode 100644
index 000000000000..9f09d043a89b
--- /dev/null
+++ b/core/java/android/companion/virtualnative/IVirtualDeviceManagerNative.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion.virtualnative;
+
+/**
+ * Parallel implementation of certain VirtualDeviceManager APIs that need to be exposed to native
+ * code.
+ *
+ * <p>These APIs are a parallel definition to the APIs in VirtualDeviceManager and/or
+ * VirtualDeviceManagerInternal, so they can technically diverge. However, it's good practice to
+ * keep these APIs in sync with each other.</p>
+ *
+ * <p>Even though the name implies otherwise, the implementation is actually in Java. The 'native'
+ * suffix comes from the intended usage - native framework backends that need to communicate with
+ * VDM for some reason.</p>
+ *
+ * <p>Because these APIs are exposed to native code that runs in the app process, they may be
+ * accessed by apps directly, even though they're hidden. Care should be taken to avoid exposing
+ * sensitive data or potential security holes.</p>
+ *
+ * @hide
+ */
+interface IVirtualDeviceManagerNative {
+ /**
+ * Counterpart to VirtualDeviceParams#DevicePolicy.
+ */
+ const int DEVICE_POLICY_DEFAULT = 0;
+ const int DEVICE_POLICY_CUSTOM = 1;
+
+ /**
+ * Counterpart to VirtualDeviceParams#PolicyType.
+ */
+ const int POLICY_TYPE_SENSORS = 0;
+ const int POLICY_TYPE_AUDIO = 1;
+ const int POLICY_TYPE_RECENTS = 2;
+ const int POLICY_TYPE_ACTIVITY = 3;
+
+ /**
+ * Returns the IDs for all VirtualDevices where an app with the given is running.
+ *
+ * Note that this returns only VirtualDevice IDs: if the app is not running on any virtual
+ * device, then an an empty array is returned. This does not include information about whether
+ * the app is running on the default device or not.
+ */
+ int[] getDeviceIdsForUid(int uid);
+
+ /**
+ * Returns the device policy for the given virtual device and policy type.
+ */
+ int getDevicePolicy(int deviceId, int policyType);
+} \ No newline at end of file
diff --git a/core/java/android/companion/virtualnative/OWNERS b/core/java/android/companion/virtualnative/OWNERS
new file mode 100644
index 000000000000..29681045ac4a
--- /dev/null
+++ b/core/java/android/companion/virtualnative/OWNERS
@@ -0,0 +1 @@
+include /services/companion/java/com/android/server/companion/virtual/OWNERS
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 44a9acd6ba2f..5f4c05f001ff 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2790,6 +2790,20 @@ public class Intent implements Parcelable, Cloneable {
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
+
+ /**
+ * Broadcast Action: An application package that was previously in the stopped state has been
+ * started and is no longer considered stopped.
+ * <ul>
+ * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
+ * </ul>
+ *
+ * <p class="note">This is a protected intent that can only be sent by the system.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @FlaggedApi(android.content.pm.Flags.FLAG_STAY_STOPPED)
+ public static final String ACTION_PACKAGE_UNSTOPPED = "android.intent.action.PACKAGE_UNSTOPPED";
+
/**
* Broadcast Action: Sent to the system rollback manager when a package
* needs to have rollback enabled.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index aca88d6af033..99264150f7d0 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -308,6 +308,8 @@ interface IPackageManager {
boolean isPackageQuarantinedForUser(String packageName, int userId);
+ boolean isPackageStoppedForUser(String packageName, int userId);
+
Bundle getSuspendedPackageAppExtras(String packageName, int userId);
/**
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3a9e9bf01f04..673a8a5edcba 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -371,13 +371,6 @@ public class PackageInstaller {
"android.content.pm.extra.UNARCHIVE_ALL_USERS";
/**
- * A list of warnings that occurred during installation.
- *
- * @hide
- */
- public static final String EXTRA_WARNINGS = "android.content.pm.extra.WARNINGS";
-
- /**
* Streaming installation pending.
* Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
*
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8fbe50c32881..45338bb2c0a2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -9878,6 +9878,18 @@ public abstract class PackageManager {
}
/**
+ * Query if an app is currently stopped.
+ *
+ * @return {@code true} if the given package is stopped, {@code false} otherwise
+ * @throws NameNotFoundException if the package could not be found.
+ * @see ApplicationInfo#FLAG_STOPPED
+ */
+ @FlaggedApi(android.content.pm.Flags.FLAG_STAY_STOPPED)
+ public boolean isPackageStopped(@NonNull String packageName) throws NameNotFoundException {
+ throw new UnsupportedOperationException("isPackageStopped not implemented");
+ }
+
+ /**
* Query if an app is currently quarantined.
*
* @return {@code true} if the given package is quarantined, {@code false} otherwise
@@ -9888,7 +9900,6 @@ public abstract class PackageManager {
public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException {
throw new UnsupportedOperationException("isPackageQuarantined not implemented");
}
-
/**
* Provide a hint of what the {@link ApplicationInfo#category} value should
* be for the given package.
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index ea0f049cece3..3ec239c7125e 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -8,8 +8,23 @@ flag {
}
flag {
+ name: "save_global_and_guest_restrictions_on_system_user_xml_read_only"
+ namespace: "multiuser"
+ description: "Save guest and device policy global restrictions on the SYSTEM user's XML file. (Read only flag)"
+ bug: "301067944"
+ is_fixed_read_only: true
+}
+
+flag {
name: "bind_wallpaper_service_on_its_own_thread_during_a_user_switch"
namespace: "multiuser"
description: "Bind wallpaper service on its own thread instead of system_server's main handler during a user switch."
bug: "302100344"
}
+
+flag {
+ name: "support_communal_profile"
+ namespace: "multiuser"
+ description: "Framework support for communal profile."
+ bug: "285426179"
+}
diff --git a/core/java/android/credentials/GetCandidateCredentialsResponse.java b/core/java/android/credentials/GetCandidateCredentialsResponse.java
index 231e4bc4ac75..1b130a9fb64d 100644
--- a/core/java/android/credentials/GetCandidateCredentialsResponse.java
+++ b/core/java/android/credentials/GetCandidateCredentialsResponse.java
@@ -53,6 +53,15 @@ public final class GetCandidateCredentialsResponse implements Parcelable {
mCandidateProviderDataList = new ArrayList<>(candidateProviderDataList);
}
+ /**
+ * Returns candidate provider data list.
+ *
+ * @hide
+ */
+ public List<GetCredentialProviderData> getCandidateProviderDataList() {
+ return mCandidateProviderDataList;
+ }
+
protected GetCandidateCredentialsResponse(Parcel in) {
List<GetCredentialProviderData> candidateProviderDataList = new ArrayList<>();
in.readTypedList(candidateProviderDataList, GetCredentialProviderData.CREATOR);
diff --git a/core/java/android/hardware/input/KeyboardLayout.java b/core/java/android/hardware/input/KeyboardLayout.java
index bbfed24f9dc1..883f157bbfe5 100644
--- a/core/java/android/hardware/input/KeyboardLayout.java
+++ b/core/java/android/hardware/input/KeyboardLayout.java
@@ -82,8 +82,8 @@ public final class KeyboardLayout implements Parcelable, Comparable<KeyboardLayo
DVORAK(4, LAYOUT_TYPE_DVORAK),
COLEMAK(5, LAYOUT_TYPE_COLEMAK),
WORKMAN(6, LAYOUT_TYPE_WORKMAN),
- TURKISH_F(7, LAYOUT_TYPE_TURKISH_F),
- TURKISH_Q(8, LAYOUT_TYPE_TURKISH_Q),
+ TURKISH_Q(7, LAYOUT_TYPE_TURKISH_Q),
+ TURKISH_F(8, LAYOUT_TYPE_TURKISH_F),
EXTENDED(9, LAYOUT_TYPE_EXTENDED);
private final int mValue;
diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig
index d8e60c8b6464..88f62f327fdd 100644
--- a/core/java/android/os/vibrator/flags.aconfig
+++ b/core/java/android/os/vibrator/flags.aconfig
@@ -19,4 +19,11 @@ flag {
name: "haptics_customization_ringtone_v2_enabled"
description: "Enables the usage of the new RingtoneV2 class"
bug: "241918098"
-} \ No newline at end of file
+}
+
+flag {
+ namespace: "haptics"
+ name: "enable_vibration_serialization_apis"
+ description: "Enables the APIs for vibration serialization/deserialization."
+ bug: "245129509"
+}
diff --git a/core/java/android/os/vibrator/persistence/ParsedVibration.java b/core/java/android/os/vibrator/persistence/ParsedVibration.java
index ded74eab149e..3d1deea57f14 100644
--- a/core/java/android/os/vibrator/persistence/ParsedVibration.java
+++ b/core/java/android/os/vibrator/persistence/ParsedVibration.java
@@ -16,6 +16,7 @@
package android.os.vibrator.persistence;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -34,6 +35,7 @@ import java.util.List;
*
* @hide
*/
+@FlaggedApi(android.os.vibrator.Flags.FLAG_ENABLE_VIBRATION_SERIALIZATION_APIS)
@TestApi
public class ParsedVibration {
private final List<VibrationEffect> mEffects;
diff --git a/core/java/android/os/vibrator/persistence/VibrationXmlParser.java b/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
index e08cc4262bed..fed1053e2a12 100644
--- a/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
+++ b/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
@@ -16,6 +16,7 @@
package android.os.vibrator.persistence;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -115,6 +116,7 @@ import java.util.List;
*
* @hide
*/
+@FlaggedApi(android.os.vibrator.Flags.FLAG_ENABLE_VIBRATION_SERIALIZATION_APIS)
@TestApi
public final class VibrationXmlParser {
private static final String TAG = "VibrationXmlParser";
diff --git a/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java b/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java
index 1cdfa4f74dbd..28804544edaf 100644
--- a/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java
+++ b/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java
@@ -16,6 +16,7 @@
package android.os.vibrator.persistence;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.TestApi;
@@ -42,6 +43,7 @@ import java.lang.annotation.RetentionPolicy;
*
* @hide
*/
+@FlaggedApi(android.os.vibrator.Flags.FLAG_ENABLE_VIBRATION_SERIALIZATION_APIS)
@TestApi
public final class VibrationXmlSerializer {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b414ed4faea2..5c64389e8c27 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4866,7 +4866,8 @@ public final class Settings {
"display_color_mode_vendor_hint";
/**
- * The user selected min refresh rate in frames per second.
+ * The user selected min refresh rate in frames per second. If infinite, the user wants
+ * the highest possible refresh rate.
*
* If this isn't set, 0 will be used.
* @hide
@@ -4875,7 +4876,8 @@ public final class Settings {
public static final String MIN_REFRESH_RATE = "min_refresh_rate";
/**
- * The user selected peak refresh rate in frames per second.
+ * The user selected peak refresh rate in frames per second. If infinite, the user wants
+ * the highest possible refresh rate.
*
* If this isn't set, the system falls back to a device specific default.
* @hide
@@ -11607,6 +11609,45 @@ public final class Settings {
"accessibility_magnification_joystick_enabled";
/**
+ * Controls magnification enable gesture. Accessibility magnification can have one or more
+ * enable gestures.
+ *
+ * @see #ACCESSIBILITY_MAGNIFICATION_GESTURE_NONE
+ * @see #ACCESSIBILITY_MAGNIFICATION_GESTURE_SINGLE_FINGER_TRIPLE_TAP
+ * @see #ACCESSIBILITY_MAGNIFICATION_GESTURE_TWO_FINGER_TRIPLE_TAP
+ * @hide
+ */
+ public static final String ACCESSIBILITY_MAGNIFICATION_GESTURE =
+ "accessibility_magnification_gesture";
+
+ /**
+ * Magnification enable gesture value that is a default value.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_NONE = 0x0;
+
+ /**
+ * Magnification enable gesture value is single finger triple tap.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_SINGLE_FINGER_TRIPLE_TAP = 0x1;
+
+ /**
+ * Magnification enable gesture value is two finger triple tap.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_TWO_FINGER_TRIPLE_TAP = 0x2;
+
+ /**
+ * Magnification enable gesture values include single finger triple tap and two finger
+ * triple tap.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_ALL =
+ ACCESSIBILITY_MAGNIFICATION_GESTURE_SINGLE_FINGER_TRIPLE_TAP
+ | ACCESSIBILITY_MAGNIFICATION_GESTURE_TWO_FINGER_TRIPLE_TAP;
+
+ /**
* Controls magnification capability. Accessibility magnification is capable of at least one
* of the magnification modes.
*
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 115894f586f2..a29bf7a06334 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -18,6 +18,7 @@ package android.service.autofill;
import static android.view.autofill.Helper.sDebug;
+import android.annotation.Hide;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -26,6 +27,7 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.ClipData;
import android.content.IntentSender;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -187,6 +189,9 @@ public final class Dataset implements Parcelable {
@Nullable private final InlinePresentation mInlinePresentation;
@Nullable private final InlinePresentation mInlineTooltipPresentation;
private final IntentSender mAuthentication;
+
+ @Nullable private final Bundle mAuthenticationExtras;
+
@Nullable String mId;
/**
@@ -224,6 +229,7 @@ public final class Dataset implements Parcelable {
mInlinePresentation = inlinePresentation;
mInlineTooltipPresentation = inlineTooltipPresentation;
mAuthentication = authentication;
+ mAuthenticationExtras = null;
mId = id;
}
@@ -246,6 +252,7 @@ public final class Dataset implements Parcelable {
mInlinePresentation = dataset.mInlinePresentation;
mInlineTooltipPresentation = dataset.mInlineTooltipPresentation;
mAuthentication = dataset.mAuthentication;
+ mAuthenticationExtras = dataset.mAuthenticationExtras;
mId = dataset.mId;
mAutofillDatatypes = dataset.mAutofillDatatypes;
}
@@ -264,6 +271,7 @@ public final class Dataset implements Parcelable {
mInlinePresentation = builder.mInlinePresentation;
mInlineTooltipPresentation = builder.mInlineTooltipPresentation;
mAuthentication = builder.mAuthentication;
+ mAuthenticationExtras = builder.mAuthenticationExtras;
mId = builder.mId;
mAutofillDatatypes = builder.mAutofillDatatypes;
}
@@ -345,6 +353,12 @@ public final class Dataset implements Parcelable {
}
/** @hide */
+ @Hide
+ public @Nullable Bundle getAuthenticationExtras() {
+ return mAuthenticationExtras;
+ }
+
+ /** @hide */
@TestApi
public boolean isEmpty() {
return mFieldIds == null || mFieldIds.isEmpty();
@@ -401,6 +415,9 @@ public final class Dataset implements Parcelable {
if (mAuthentication != null) {
builder.append(", hasAuthentication");
}
+ if (mAuthenticationExtras != null) {
+ builder.append(", hasAuthenticationExtras");
+ }
if (mAutofillDatatypes != null) {
builder.append(", autofillDatatypes=").append(mAutofillDatatypes);
}
@@ -454,6 +471,8 @@ public final class Dataset implements Parcelable {
@Nullable private InlinePresentation mInlinePresentation;
@Nullable private InlinePresentation mInlineTooltipPresentation;
private IntentSender mAuthentication;
+
+ private Bundle mAuthenticationExtras;
private boolean mDestroyed;
@Nullable private String mId;
@@ -624,6 +643,25 @@ public final class Dataset implements Parcelable {
}
/**
+ * Sets extras to be associated with the {@code authentication} intent sender, to be
+ * set on the intent that is fired through the intent sender.
+ *
+ * Autofill providers can set any extras they wish to receive directly on the intent
+ * that is used to create the {@code authentication}. This is an internal API, to be
+ * used by the platform to associate data with a given dataset. These extras will be
+ * merged with the {@code clientState} and sent as part of the fill in intent when
+ * the {@code authentication} intentSender is invoked.
+ *
+ * @hide
+ */
+ @Hide
+ public @NonNull Builder setAuthenticationExtras(@Nullable Bundle authenticationExtra) {
+ throwIfDestroyed();
+ mAuthenticationExtras = authenticationExtra;
+ return this;
+ }
+
+ /**
* Sets the id for the dataset so its usage can be tracked.
*
* <p>Dataset usage can be tracked for 2 purposes:
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index be7b72202b3f..a2b0a669c768 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -153,6 +153,18 @@ public abstract class CredentialProviderService extends Service {
public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST =
"android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";
+ /**
+ * The key to autofillId associated with the requested credential option and the corresponding
+ * credential entry. The associated autofillId will be contained inside the candidate query
+ * bundle of {@link android.credentials.CredentialOption} if requested through the
+ * {@link com.android.credentialmanager.autofill.CredentialAutofillService}. The resulting
+ * credential entry will contain the autofillId inside its framework extras intent.
+ *
+ * @hide
+ */
+ public static final String EXTRA_AUTOFILL_ID =
+ "android.service.credentials.extra.AUTOFILL_ID";
+
private static final String TAG = "CredProviderService";
/**
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 07f8aac43bf5..1cfff14b2d7c 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -2007,6 +2007,20 @@ public abstract class NotificationListenerService extends Service {
return mSmartActions == null ? Collections.emptyList() : mSmartActions;
}
+
+ /**
+ * Sets the smart {@link Notification.Action} objects.
+ *
+ * Should ONLY be used in cases where smartActions need to be removed from, then restored
+ * on, Ranking objects during Parceling, when they are transmitted between processes via
+ * Shared Memory.
+ *
+ * @hide
+ */
+ public void setSmartActions(@Nullable ArrayList<Notification.Action> smartActions) {
+ mSmartActions = smartActions;
+ }
+
/**
* Returns a list of smart replies that can be added by the
* {@link NotificationAssistantService}
@@ -2353,11 +2367,9 @@ public abstract class NotificationListenerService extends Service {
/**
* Get a reference to the actual Ranking object corresponding to the key.
- * Used only by unit tests.
*
* @hide
*/
- @VisibleForTesting
public Ranking getRawRankingObject(String key) {
return mRankings.get(key);
}
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index f3b4c6da4a01..0dad96eb3b5b 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -18,6 +18,8 @@ package android.service.notification;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
+import android.app.Notification;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SharedMemory;
@@ -29,9 +31,12 @@ import androidx.annotation.NonNull;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
/**
* Represents an update to notification rankings.
+ *
* @hide
*/
@SuppressLint({"ParcelNotFinal", "ParcelCreator"})
@@ -64,6 +69,7 @@ public class NotificationRankingUpdate implements Parcelable {
// The ranking map should be stored in shared memory when it is parceled, so we
// unwrap the SharedMemory object.
mRankingMapFd = in.readParcelable(getClass().getClassLoader(), SharedMemory.class);
+ Bundle smartActionsBundle = in.readBundle(getClass().getClassLoader());
// In the case that the ranking map can't be read, readParcelable may return null.
// In this case, we set mRankingMap to null;
@@ -82,8 +88,13 @@ public class NotificationRankingUpdate implements Parcelable {
mapParcel.unmarshall(payload, 0, payload.length);
mapParcel.setDataPosition(0);
- mRankingMap = mapParcel.readParcelable(getClass().getClassLoader(),
- android.service.notification.NotificationListenerService.RankingMap.class);
+ mRankingMap =
+ mapParcel.readParcelable(
+ getClass().getClassLoader(),
+ NotificationListenerService.RankingMap.class);
+
+ addSmartActionsFromBundleToRankingMap(smartActionsBundle);
+
} catch (ErrnoException e) {
// TODO(b/284297289): remove throw when associated flag is moved to droidfood, to
// avoid crashes; change to Log.wtf.
@@ -102,7 +113,31 @@ public class NotificationRankingUpdate implements Parcelable {
}
/**
+ * For each key in the rankingMap, extracts lists of smart actions stored in the provided
+ * bundle and adds them to the corresponding Ranking object in the provided ranking
+ * map, then returns the rankingMap.
+ *
+ * @hide
+ */
+ private void addSmartActionsFromBundleToRankingMap(Bundle smartActionsBundle) {
+ if (smartActionsBundle == null) {
+ return;
+ }
+
+ String[] rankingMapKeys = mRankingMap.getOrderedKeys();
+ for (int i = 0; i < rankingMapKeys.length; i++) {
+ String key = rankingMapKeys[i];
+ ArrayList<Notification.Action> smartActions =
+ smartActionsBundle.getParcelableArrayList(key, Notification.Action.class);
+ // Get the ranking object from the ranking map.
+ NotificationListenerService.Ranking ranking = mRankingMap.getRawRankingObject(key);
+ ranking.setSmartActions(smartActions);
+ }
+ }
+
+ /**
* Confirms that the SharedMemory file descriptor is closed. Should only be used for testing.
+ *
* @hide
*/
@TestApi
@@ -145,9 +180,45 @@ public class NotificationRankingUpdate implements Parcelable {
if (SystemUiSystemPropertiesFlags.getResolver().isEnabled(
SystemUiSystemPropertiesFlags.NotificationFlags.RANKING_UPDATE_ASHMEM)) {
final Parcel mapParcel = Parcel.obtain();
+ ArrayList<NotificationListenerService.Ranking> marshalableRankings = new ArrayList<>();
+ Bundle smartActionsBundle = new Bundle();
+
+ // We need to separate the SmartActions from the RankingUpdate objects.
+ // SmartActions can contain PendingIntents, which cannot be marshalled,
+ // so we extract them to send separately.
+ String[] rankingMapKeys = mRankingMap.getOrderedKeys();
+ for (int i = 0; i < rankingMapKeys.length; i++) {
+ String key = rankingMapKeys[i];
+ NotificationListenerService.Ranking ranking = mRankingMap.getRawRankingObject(key);
+
+ // Removes the SmartActions and stores them in a separate map.
+ // Note that getSmartActions returns a Collections.emptyList() if there are no
+ // smart actions, and we don't want to needlessly store an empty list object, so we
+ // check for null before storing.
+ List<Notification.Action> smartActions = ranking.getSmartActions();
+ if (!smartActions.isEmpty()) {
+ smartActionsBundle.putParcelableList(key, smartActions);
+ }
+
+ // Create a copy of the ranking object that doesn't have the smart actions.
+ NotificationListenerService.Ranking rankingCopy =
+ new NotificationListenerService.Ranking();
+ rankingCopy.populate(ranking);
+ rankingCopy.setSmartActions(null);
+ marshalableRankings.add(rankingCopy);
+ }
+
+ // Create a new marshalable RankingMap.
+ NotificationListenerService.RankingMap marshalableRankingMap =
+ new NotificationListenerService.RankingMap(
+ marshalableRankings.toArray(
+ new NotificationListenerService.Ranking[0]
+ )
+ );
+
try {
// Parcels the ranking map and measures its size.
- mapParcel.writeParcelable(mRankingMap, flags);
+ mapParcel.writeParcelable(marshalableRankingMap, flags);
int mapSize = mapParcel.dataSize();
// Creates a new SharedMemory object with enough space to hold the ranking map.
@@ -158,15 +229,14 @@ public class NotificationRankingUpdate implements Parcelable {
// Gets a read/write buffer mapping the entire shared memory region.
final ByteBuffer buffer = mRankingMapFd.mapReadWrite();
-
// Puts the ranking map into the shared memory region buffer.
buffer.put(mapParcel.marshall(), 0, mapSize);
-
// Protects the region from being written to, by setting it to be read-only.
mRankingMapFd.setProtect(OsConstants.PROT_READ);
-
// Puts the SharedMemory object in the parcel.
out.writeParcelable(mRankingMapFd, flags);
+ // Writes the Parceled smartActions separately.
+ out.writeBundle(smartActionsBundle);
} catch (ErrnoException e) {
// TODO(b/284297289): remove throw when associated flag is moved to droidfood, to
// avoid crashes; change to Log.wtf.
@@ -180,8 +250,8 @@ public class NotificationRankingUpdate implements Parcelable {
}
/**
- * @hide
- */
+ * @hide
+ */
public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR
= new Parcelable.Creator<NotificationRankingUpdate>() {
public NotificationRankingUpdate createFromParcel(Parcel parcel) {
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index f6309f2c9860..cf1156db55e5 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -401,7 +401,7 @@ public class PhoneStateListener {
/**
* Listen for call disconnect causes which contains {@link DisconnectCause} and
- * {@link PreciseDisconnectCause}.
+ * the precise disconnect cause.
*
* <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
* or the calling app has carrier privileges
@@ -851,8 +851,8 @@ public class PhoneStateListener {
* subId. Otherwise, this callback applies to
* {@link SubscriptionManager#getDefaultSubscriptionId()}.
*
- * @param disconnectCause {@link DisconnectCause}.
- * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
+ * @param disconnectCause the disconnect cause
+ * @param preciseDisconnectCause the precise disconnect cause
* @deprecated Use {@link TelephonyCallback.CallDisconnectCauseListener} instead.
*/
@RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index fb2d7714d402..7b48a16c2227 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -221,7 +221,7 @@ public final class SubscriptionPlan implements Parcelable {
}
/**
- * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to.
+ * Return an array containing all network types this SubscriptionPlan applies to.
* @see TelephonyManager for network types values
*/
public @NonNull @NetworkType int[] getNetworkTypes() {
@@ -365,7 +365,7 @@ public final class SubscriptionPlan implements Parcelable {
* Set the network types this SubscriptionPlan applies to. By default the plan will apply
* to all network types. An empty array means this plan applies to no network types.
*
- * @param networkTypes an array of all {@link NetworkType}s that apply to this plan.
+ * @param networkTypes an array of all network types that apply to this plan.
* @see TelephonyManager for network type values
*/
public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) {
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index 7ada058e8e80..19bcf28d6b83 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -948,8 +948,8 @@ public class TelephonyCallback {
* subscription ID. Otherwise, this callback applies to
* {@link SubscriptionManager#getDefaultSubscriptionId()}.
*
- * @param disconnectCause {@link DisconnectCause}.
- * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
+ * @param disconnectCause the disconnect cause
+ * @param preciseDisconnectCause the precise disconnect cause
*/
@RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause,
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index e2c5539141a4..0063d13cb3ab 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -238,7 +238,7 @@ public class TelephonyRegistryManager {
}
/**
- * To check the SDK version for {@link #listenFromListener}.
+ * To check the SDK version for {@code #listenFromListener}.
*/
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 2b3a081ceff6..8862f1d74ab1 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -16,6 +16,10 @@
package android.text;
+import static com.android.text.flags.Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN;
+import static com.android.text.flags.Flags.FLAG_USE_BOUNDS_FOR_WIDTH;
+
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -280,6 +284,7 @@ public class DynamicLayout extends Layout {
* @see android.widget.TextView#setLineBreakWordStyle
*/
@NonNull
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
public Builder setLineBreakConfig(@NonNull LineBreakConfig lineBreakConfig) {
mLineBreakConfig = lineBreakConfig;
return this;
@@ -303,6 +308,7 @@ public class DynamicLayout extends Layout {
* @see Layout.Builder#setUseBoundsForWidth(boolean)
*/
@NonNull
+ @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH)
public Builder setUseBoundsForWidth(boolean useBoundsForWidth) {
mUseBoundsForWidth = useBoundsForWidth;
return this;
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
index c5857347fd45..94c8eaf13ccb 100644
--- a/core/java/android/text/FontConfig.java
+++ b/core/java/android/text/FontConfig.java
@@ -29,6 +29,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontFamily.Builder.VariableFontFamilyType;
import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
+import android.icu.util.ULocale;
import android.os.Build;
import android.os.LocaleList;
import android.os.Parcel;
@@ -39,6 +40,7 @@ import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
@@ -58,6 +60,7 @@ public final class FontConfig implements Parcelable {
private final @NonNull List<FontFamily> mFamilies;
private final @NonNull List<Alias> mAliases;
private final @NonNull List<NamedFamilyList> mNamedFamilyLists;
+ private final @NonNull List<Customization.LocaleFallback> mLocaleFallbackCustomizations;
private final long mLastModifiedTimeMillis;
private final int mConfigVersion;
@@ -71,10 +74,12 @@ public final class FontConfig implements Parcelable {
*/
public FontConfig(@NonNull List<FontFamily> families, @NonNull List<Alias> aliases,
@NonNull List<NamedFamilyList> namedFamilyLists,
+ @NonNull List<Customization.LocaleFallback> localeFallbackCustomizations,
long lastModifiedTimeMillis, @IntRange(from = 0) int configVersion) {
mFamilies = families;
mAliases = aliases;
mNamedFamilyLists = namedFamilyLists;
+ mLocaleFallbackCustomizations = localeFallbackCustomizations;
mLastModifiedTimeMillis = lastModifiedTimeMillis;
mConfigVersion = configVersion;
}
@@ -84,7 +89,8 @@ public final class FontConfig implements Parcelable {
*/
public FontConfig(@NonNull List<FontFamily> families, @NonNull List<Alias> aliases,
long lastModifiedTimeMillis, @IntRange(from = 0) int configVersion) {
- this(families, aliases, Collections.emptyList(), lastModifiedTimeMillis, configVersion);
+ this(families, aliases, Collections.emptyList(), Collections.emptyList(),
+ lastModifiedTimeMillis, configVersion);
}
@@ -113,6 +119,18 @@ public final class FontConfig implements Parcelable {
}
/**
+ * Returns a locale fallback customizations.
+ *
+ * This field is used for creating the system fallback in the system server. This field is
+ * always empty in the application process.
+ *
+ * @hide
+ */
+ public @NonNull List<Customization.LocaleFallback> getLocaleFallbackCustomizations() {
+ return mLocaleFallbackCustomizations;
+ }
+
+ /**
* Returns the last modified time in milliseconds.
*
* This is a value of {@link System#currentTimeMillis()} when the system font configuration was
@@ -169,7 +187,9 @@ public final class FontConfig implements Parcelable {
source.readTypedList(familyLists, NamedFamilyList.CREATOR);
long lastModifiedDate = source.readLong();
int configVersion = source.readInt();
- return new FontConfig(families, aliases, familyLists, lastModifiedDate, configVersion);
+ return new FontConfig(families, aliases, familyLists,
+ Collections.emptyList(), // Don't need to pass customization to API caller.
+ lastModifiedDate, configVersion);
}
@Override
@@ -813,4 +833,129 @@ public final class FontConfig implements Parcelable {
+ '}';
}
}
+
+ /** @hide */
+ public static class Customization {
+ private Customization() {} // Singleton
+
+ /**
+ * A class that represents customization of locale fallback
+ *
+ * This class represents a vendor customization of new-locale-family.
+ *
+ * <pre>
+ * <family customizationType="new-locale-family" operation="prepend" lang="ja-JP">
+ * <font weight="400" style="normal">MyAlternativeFont.ttf
+ * <axis tag="wght" stylevalue="400"/>
+ * </font>
+ * </family>
+ * </pre>
+ *
+ * The operation can be one of prepend, replace or append. The operation prepend means that
+ * the new font family is inserted just before the original font family. The original font
+ * family is still in the fallback. The operation replace means that the original font
+ * family is replaced with new font family. The original font family is removed from the
+ * fallback. The operation append means that the new font family is inserted just after the
+ * original font family. The original font family is still in the fallback.
+ *
+ * The lang attribute is a BCP47 compliant language tag. The font fallback mainly uses ISO
+ * 15924 script code for matching. If the script code is missing, most likely script code
+ * will be used.
+ */
+ public static class LocaleFallback {
+ private final Locale mLocale;
+ private final int mOperation;
+ private final FontFamily mFamily;
+ private final String mScript;
+
+ public static final int OPERATION_PREPEND = 0;
+ public static final int OPERATION_APPEND = 1;
+ public static final int OPERATION_REPLACE = 2;
+
+ /** @hide */
+ @Retention(SOURCE)
+ @IntDef(prefix = { "OPERATION_" }, value = {
+ OPERATION_PREPEND,
+ OPERATION_APPEND,
+ OPERATION_REPLACE
+ })
+ public @interface Operation {}
+
+
+ public LocaleFallback(@NonNull Locale locale, @Operation int operation,
+ @NonNull FontFamily family) {
+ mLocale = locale;
+ mOperation = operation;
+ mFamily = family;
+ mScript = resolveScript(locale);
+ }
+
+ /**
+ * A customization target locale.
+ * @return a locale
+ */
+ public @NonNull Locale getLocale() {
+ return mLocale;
+ }
+
+ /**
+ * An operation to be applied to the original font family.
+ *
+ * The operation can be one of {@link #OPERATION_PREPEND}, {@link #OPERATION_REPLACE} or
+ * {@link #OPERATION_APPEND}.
+ *
+ * The operation prepend ({@link #OPERATION_PREPEND}) means that the new font family is
+ * inserted just before the original font family. The original font family is still in
+ * the fallback.
+ *
+ * The operation replace ({@link #OPERATION_REPLACE}) means that the original font
+ * family is replaced with new font family. The original font family is removed from the
+ * fallback.
+ *
+ * The operation append ({@link #OPERATION_APPEND}) means that the new font family is
+ * inserted just after the original font family. The original font family is still in
+ * the fallback.
+ *
+ * @return an operation.
+ */
+ public @Operation int getOperation() {
+ return mOperation;
+ }
+
+ /**
+ * Returns a family to be inserted or replaced to the fallback.
+ *
+ * @return a family
+ */
+ public @NonNull FontFamily getFamily() {
+ return mFamily;
+ }
+
+ /**
+ * Returns a script of the locale. If the script is missing in the given locale, the
+ * most likely locale is returned.
+ */
+ public @NonNull String getScript() {
+ return mScript;
+ }
+
+ @Override
+ public String toString() {
+ return "LocaleFallback{"
+ + "mLocale=" + mLocale
+ + ", mOperation=" + mOperation
+ + ", mFamily=" + mFamily
+ + '}';
+ }
+ }
+ }
+
+ /** @hide */
+ public static String resolveScript(Locale locale) {
+ String script = locale.getScript();
+ if (script != null && !script.isEmpty()) {
+ return script;
+ }
+ return ULocale.addLikelySubtags(ULocale.forLocale(locale)).getScript();
+ }
}
diff --git a/core/java/android/text/MeasuredParagraph.java b/core/java/android/text/MeasuredParagraph.java
index c1d0e9b95b70..ac5eb3cbeeaa 100644
--- a/core/java/android/text/MeasuredParagraph.java
+++ b/core/java/android/text/MeasuredParagraph.java
@@ -16,6 +16,9 @@
package android.text;
+import static com.android.text.flags.Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN;
+
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -416,10 +419,12 @@ public class MeasuredParagraph {
* @hide
*/
@TestApi
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
public interface StyleRunCallback {
/**
* Called when a single style run is identified.
*/
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
void onAppendStyleRun(@NonNull Paint paint,
@Nullable LineBreakConfig lineBreakConfig, @IntRange(from = 0) int length,
boolean isRtl);
@@ -427,6 +432,7 @@ public class MeasuredParagraph {
/**
* Called when a single replacement run is identified.
*/
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
void onAppendReplacementRun(@NonNull Paint paint,
@IntRange(from = 0) int length, @Px @FloatRange(from = 0) float width);
}
@@ -488,6 +494,7 @@ public class MeasuredParagraph {
@SuppressLint("ExecutorRegistration")
@TestApi
@NonNull
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
public static MeasuredParagraph buildForStaticLayoutTest(
@NonNull TextPaint paint,
@Nullable LineBreakConfig lineBreakConfig,
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index e3c72c964d64..01279cea073f 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -16,6 +16,9 @@
package android.text;
+import static com.android.text.flags.Flags.FLAG_USE_BOUNDS_FOR_WIDTH;
+
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -439,6 +442,7 @@ public class StaticLayout extends Layout {
* @see Layout.Builder#setUseBoundsForWidth(boolean)
*/
@NonNull
+ @FlaggedApi(FLAG_USE_BOUNDS_FOR_WIDTH)
public Builder setUseBoundsForWidth(boolean useBoundsForWidth) {
mUseBoundsForWidth = useBoundsForWidth;
return this;
diff --git a/core/java/android/text/flags/custom_locale_fallback.aconfig b/core/java/android/text/flags/custom_locale_fallback.aconfig
new file mode 100644
index 000000000000..04e64f96454b
--- /dev/null
+++ b/core/java/android/text/flags/custom_locale_fallback.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.text.flags"
+
+flag {
+ name: "custom_locale_fallback"
+ namespace: "text"
+ description: "A feature flag that adds custom locale fallback to the vendor customization XML. This enables vendors to add their locale specific fonts, e.g. Japanese font."
+ bug: ""
+}
diff --git a/core/java/android/text/style/LineBreakConfigSpan.java b/core/java/android/text/style/LineBreakConfigSpan.java
index 25c1db4d9804..682ffa180c0b 100644
--- a/core/java/android/text/style/LineBreakConfigSpan.java
+++ b/core/java/android/text/style/LineBreakConfigSpan.java
@@ -71,6 +71,10 @@ public class LineBreakConfigSpan {
.setHyphenation(LineBreakConfig.HYPHENATION_DISABLED)
.build();
+ private static final LineBreakConfig sNoBreakConfig = new LineBreakConfig.Builder()
+ .setLineBreakStyle(LineBreakConfig.LINE_BREAK_STYLE_NO_BREAK)
+ .build();
+
/**
* A specialized {@link LineBreakConfigSpan} that used for preventing hyphenation.
*/
@@ -84,4 +88,24 @@ public class LineBreakConfigSpan {
super(sNoHyphenationConfig);
}
}
+
+ /**
+ * A specialized {@link LineBreakConfigSpan} that used for preventing line break.
+ *
+ * This is useful when you want to preserve some words in the same line.
+ * Note that even if this style is specified, the grapheme based line break is still performed
+ * for preventing clipping text.
+ *
+ * @see LineBreakConfigSpan
+ */
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ public static final class NoBreakSpan extends LineBreakConfigSpan {
+ /**
+ * Construct a new {@link NoBreakSpan}.
+ */
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ public NoBreakSpan() {
+ super(sNoBreakConfig);
+ }
+ }
}
diff --git a/core/java/android/view/IDecorViewGestureListener.aidl b/core/java/android/view/IDecorViewGestureListener.aidl
new file mode 100644
index 000000000000..1022dbfb70eb
--- /dev/null
+++ b/core/java/android/view/IDecorViewGestureListener.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+/**
+ * Listener for changes to gesture interception detector running at DecorView.
+ *
+ * {@hide}
+ */
+oneway interface IDecorViewGestureListener {
+ /**
+ * Called when a DecorView has started intercepting gesture.
+ *
+ * @param windowToken Where did this gesture interception result comes from.
+ * @param intercepted Whether the gesture interception detector has started interception.
+ */
+ void onInterceptionChanged(in IBinder windowToken, in boolean intercepted);
+}
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index c4d307073d12..a150187bbc6c 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -23,6 +23,8 @@ import android.graphics.GraphicBuffer;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
+import com.android.internal.os.IResultReceiver;
+
/**
* Passed to the {@link IRecentsAnimationRunner} in order for the runner to control to let the
* runner control certain aspects of the recents animation, and to notify window manager when the
@@ -58,7 +60,7 @@ interface IRecentsAnimationController {
* top resumed app, false otherwise.
*/
@UnsupportedAppUsage
- void finish(boolean moveHomeToTop, boolean sendUserLeaveHint);
+ void finish(boolean moveHomeToTop, boolean sendUserLeaveHint, in IResultReceiver finishCb);
/**
* Called by the handler to indicate that the recents animation input consumer should be
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index cccac95b9caa..c10fc9f9cb09 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -48,6 +48,7 @@ import android.view.IScrollCaptureResponseListener;
import android.view.RemoteAnimationAdapter;
import android.view.IRotationWatcher;
import android.view.ISystemGestureExclusionListener;
+import android.view.IDecorViewGestureListener;
import android.view.IWallpaperVisibilityListener;
import android.view.IWindow;
import android.view.IWindowSession;
@@ -1062,4 +1063,18 @@ interface IWindowManager
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.ACCESS_SURFACE_FLINGER)")
boolean replaceContentOnDisplay(int displayId, in SurfaceControl sc);
+
+ /**
+ * Registers a DecorView gesture listener for a given display.
+ */
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MONITOR_INPUT)")
+ void registerDecorViewGestureListener(IDecorViewGestureListener listener, int displayId);
+
+ /**
+ * Unregisters a DecorView gesture listener for a given display.
+ */
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MONITOR_INPUT)")
+ void unregisterDecorViewGestureListener(IDecorViewGestureListener listener, int displayId);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 83de2a0fafbe..7acf2f8ce06d 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -284,6 +284,11 @@ interface IWindowSession {
oneway void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
/**
+ * Called when the DecorView gesture interception state has changed.
+ */
+ oneway void reportDecorViewGestureInterceptionChanged(IWindow window, in boolean intercepted);
+
+ /**
* Called when the keep-clear areas for this window have changed.
*/
oneway void reportKeepClearAreasChanged(IWindow window, in List<Rect> restricted,
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 2761aaeb4a7d..45b3fdd7e5bc 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -16,6 +16,8 @@
package android.view;
+import static com.android.window.flags.Flags.surfaceTrustedOverlay;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Matrix;
@@ -35,7 +37,6 @@ import java.lang.ref.WeakReference;
* @hide
*/
public final class InputWindowHandle {
-
/**
* An internal annotation for all the {@link android.os.InputConfig} flags that can be
* specified to {@link #inputConfig} to control the behavior of an input window. Only the
@@ -59,7 +60,6 @@ public final class InputWindowHandle {
InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
InputConfig.IS_WALLPAPER,
InputConfig.PAUSE_DISPATCHING,
- InputConfig.TRUSTED_OVERLAY,
InputConfig.WATCH_OUTSIDE_TOUCH,
InputConfig.SLIPPERY,
InputConfig.DISABLE_USER_ACTIVITY,
@@ -272,4 +272,13 @@ public final class InputWindowHandle {
}
this.inputConfig &= ~inputConfig;
}
+
+ public void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc,
+ boolean isTrusted) {
+ if (surfaceTrustedOverlay()) {
+ t.setTrustedOverlay(sc, isTrusted);
+ } else if (isTrusted) {
+ inputConfig |= InputConfig.TRUSTED_OVERLAY;
+ }
+ }
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index be6fb313b230..139c0bebedec 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -123,7 +123,8 @@ public final class SurfaceControl implements Parcelable {
private static native long nativeMirrorSurface(long mirrorOfObject);
private static native long nativeCreateTransaction();
private static native long nativeGetNativeTransactionFinalizer();
- private static native void nativeApplyTransaction(long transactionObj, boolean sync);
+ private static native void nativeApplyTransaction(long transactionObj, boolean sync,
+ boolean oneWay);
private static native void nativeMergeTransaction(long transactionObj,
long otherTransactionObj);
private static native void nativeClearTransaction(long transactionObj);
@@ -2785,10 +2786,22 @@ public final class SurfaceControl implements Parcelable {
* as a new transaction.
*/
public void apply() {
- apply(false);
+ apply(/*sync*/ false);
}
/**
+ * Applies the transaction as a one way binder call. This transaction will be applied out
+ * of order with other transactions that are applied synchronously. This method is not
+ * safe. It should only be used when the order does not matter.
+ *
+ * @hide
+ */
+ public void applyAsyncUnsafe() {
+ apply(/*sync*/ false, /*oneWay*/ true);
+ }
+
+
+ /**
* Clear the transaction object, without applying it.
*
* @hide
@@ -2817,9 +2830,13 @@ public final class SurfaceControl implements Parcelable {
* @hide
*/
public void apply(boolean sync) {
+ apply(sync, /*oneWay*/ false);
+ }
+
+ private void apply(boolean sync, boolean oneWay) {
applyResizedSurfaces();
notifyReparentedSurfaces();
- nativeApplyTransaction(mNativeObject, sync);
+ nativeApplyTransaction(mNativeObject, sync, oneWay);
}
/**
@@ -4373,7 +4390,7 @@ public final class SurfaceControl implements Parcelable {
void applyGlobalTransaction(boolean sync) {
applyResizedSurfaces();
notifyReparentedSurfaces();
- nativeApplyTransaction(mNativeObject, sync);
+ nativeApplyTransaction(mNativeObject, sync, /*oneWay*/ false);
}
@Override
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cf46bcccdf87..aa47f077226a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5320,6 +5320,29 @@ public final class ViewRootImpl implements ViewParent,
}
/**
+ * Called from DecorView when gesture interception state has changed.
+ *
+ * @param intercepted If DecorView is intercepting touch events
+ */
+ public void updateDecorViewGestureInterception(boolean intercepted) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(
+ MSG_DECOR_VIEW_GESTURE_INTERCEPTION,
+ /* arg1= */ intercepted ? 1 : 0,
+ /* arg2= */ 0));
+ }
+
+ void decorViewInterceptionChanged(boolean intercepted) {
+ if (mView != null) {
+ try {
+ mWindowSession.reportDecorViewGestureInterceptionChanged(mWindow, intercepted);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
* Set the root-level system gesture exclusion rects. These are added to those provided by
* the root's view hierarchy.
*/
@@ -5942,6 +5965,7 @@ public final class ViewRootImpl implements ViewParent,
private static final int MSG_KEEP_CLEAR_RECTS_CHANGED = 35;
private static final int MSG_REPORT_KEEP_CLEAR_RECTS = 36;
private static final int MSG_PAUSED_FOR_SYNC_TIMEOUT = 37;
+ private static final int MSG_DECOR_VIEW_GESTURE_INTERCEPTION = 38;
final class ViewRootHandler extends Handler {
@Override
@@ -6220,6 +6244,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: {
systemGestureExclusionChanged();
} break;
+ case MSG_DECOR_VIEW_GESTURE_INTERCEPTION: {
+ decorViewInterceptionChanged(/* intercepted= */ msg.arg1 == 1);
+ } break;
case MSG_KEEP_CLEAR_RECTS_CHANGED: {
keepClearRectsChanged(/* accessibilityFocusRectChanged= */ msg.arg1 == 1);
} break;
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 8fe9b7bc0ca4..7c3b6ae42fcf 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -584,9 +584,13 @@ public class WindowlessWindowManager implements IWindowSession {
}
@Override
- public void reportKeepClearAreasChanged(android.view.IWindow window, List<Rect> restrictedRects,
- List<Rect> unrestrictedRects) {
- }
+ public void reportDecorViewGestureInterceptionChanged(IWindow window, boolean intercepted) {}
+
+ @Override
+ public void reportKeepClearAreasChanged(
+ android.view.IWindow window,
+ List<Rect> restrictedRects,
+ List<Rect> unrestrictedRects) {}
@Override
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 89fa83e5c7aa..34e4c37de1b5 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -67,6 +67,7 @@ import android.os.SystemClock;
import android.service.autofill.AutofillService;
import android.service.autofill.FillCallback;
import android.service.autofill.FillEventHistory;
+import android.service.autofill.Flags;
import android.service.autofill.IFillCallback;
import android.service.autofill.UserData;
import android.text.TextUtils;
@@ -277,6 +278,12 @@ public final class AutofillManager {
"android.view.autofill.extra.CLIENT_STATE";
/**
+ * @hide
+ */
+ public static final String EXTRA_AUTH_STATE =
+ "android.view.autofill.extra.AUTH_STATE";
+
+ /**
* Intent extra: the {@link android.view.inputmethod.InlineSuggestionsRequest} in the
* autofill request.
*
@@ -428,6 +435,14 @@ public final class AutofillManager {
public static final int STATE_UNKNOWN_FAILED = 6;
/**
+ * Same as {@link #STATE_ACTIVE}, but when pending authentication after
+ * {@link AutofillManagerClient#authenticate(int, int, IntentSender, Intent, boolean)}
+ *
+ * @hide
+ */
+ public static final int STATE_PENDING_AUTHENTICATION = 7;
+
+ /**
* Timeout in ms for calls to the field classification service.
* @hide
*/
@@ -731,6 +746,10 @@ public final class AutofillManager {
// Indicate whether WebView should always be included in the assist structure
private boolean mShouldAlwaysIncludeWebviewInAssistStructure;
+ // Controls logic around apps changing some properties of their views when activity loses
+ // focus due to autofill showing biometric activity, password manager, or password breach check.
+ private boolean mRelayoutFix;
+
// Indicates whether called the showAutofillDialog() method.
private boolean mShowAutofillDialogCalled = false;
@@ -952,6 +971,8 @@ public final class AutofillManager {
mShouldAlwaysIncludeWebviewInAssistStructure =
AutofillFeatureFlags.shouldAlwaysIncludeWebviewInAssistStructure();
+
+ mRelayoutFix = Flags.relayout();
}
/**
@@ -1715,7 +1736,13 @@ public final class AutofillManager {
synchronized (mLock) {
if (mForAugmentedAutofillOnly) {
if (sVerbose) {
- Log.v(TAG, "notifyViewVisibilityChanged(): ignoring on augmented only mode");
+ Log.v(TAG, "notifyViewVisibilityChanged(): ignoring on augmented only mode");
+ }
+ return;
+ }
+ if (mRelayoutFix && mState == STATE_PENDING_AUTHENTICATION) {
+ if (sVerbose) {
+ Log.v(TAG, "notifyViewVisibilityChanged(): ignoring in auth pending mode");
}
return;
}
@@ -2342,6 +2369,7 @@ public final class AutofillManager {
if (!isActiveLocked()) {
return;
}
+ mState = STATE_ACTIVE;
// If authenticate activity closes itself during onCreate(), there is no onStop/onStart
// of app activity. We enforce enter event to re-show fill ui in such case.
// CTS example:
@@ -2830,6 +2858,9 @@ public final class AutofillManager {
Intent fillInIntent, boolean authenticateInline) {
synchronized (mLock) {
if (sessionId == mSessionId) {
+ if (mRelayoutFix) {
+ mState = STATE_PENDING_AUTHENTICATION;
+ }
final AutofillClient client = getClient();
if (client != null) {
// clear mOnInvisibleCalled and we will see if receive onInvisibleForAutofill()
@@ -3563,6 +3594,8 @@ public final class AutofillManager {
return "UNKNOWN";
case STATE_ACTIVE:
return "ACTIVE";
+ case STATE_PENDING_AUTHENTICATION:
+ return "PENDING_AUTHENTICATION";
case STATE_FINISHED:
return "FINISHED";
case STATE_SHOWING_SAVE_UI:
@@ -3592,7 +3625,12 @@ public final class AutofillManager {
@GuardedBy("mLock")
private boolean isActiveLocked() {
- return mState == STATE_ACTIVE;
+ return mState == STATE_ACTIVE || isPendingAuthenticationLocked();
+ }
+
+ @GuardedBy("mLock")
+ private boolean isPendingAuthenticationLocked() {
+ return mRelayoutFix && mState == STATE_PENDING_AUTHENTICATION;
}
@GuardedBy("mLock")
diff --git a/core/java/android/view/flags/variable_refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index 13a6f8d52dc6..56b5fac1c64a 100644
--- a/core/java/android/view/flags/variable_refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -19,4 +19,11 @@ flag {
namespace: "toolkit"
description: "Feature flag for using expected presentation time of the Choreographer"
bug: "278730197"
+}
+
+flag {
+ name: "set_frame_rate_callback"
+ namespace: "core_graphics"
+ description: "Enable the `setFrameRate` callback"
+ bug: "299946220"
} \ No newline at end of file
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 26ceea6d1e4c..1fdd1a5a5a5f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -80,6 +80,7 @@ import android.view.animation.LinearInterpolator;
import android.view.autofill.AutofillId;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.ContentCaptureSession;
+import android.view.flags.Flags;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
@@ -92,7 +93,6 @@ import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.SurroundingText;
import android.view.inspector.InspectableProperty;
import android.view.inspector.InspectableProperty.EnumEntry;
-import android.widget.flags.Flags;
import android.widget.RemoteViews.InteractionHandler;
import com.android.internal.R;
@@ -4518,7 +4518,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int overscrollMode = getOverScrollMode();
if (!trackMotionScroll(delta, delta)) {
- if (Flags.platformWidgetHapticScrollFeedback()) {
+ if (Flags.scrollFeedbackApi()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollProgress(
event.getDeviceId(), event.getSource(), axis, delta);
@@ -4534,7 +4534,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
float overscroll = (delta - (motionViewRealTop - motionViewPrevTop))
/ ((float) getHeight());
boolean hitTopLimit = delta > 0;
- if (Flags.platformWidgetHapticScrollFeedback()) {
+ if (Flags.scrollFeedbackApi()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(
event.getDeviceId(), event.getSource(), axis,
diff --git a/core/java/android/widget/DifferentialMotionFlingHelper.java b/core/java/android/widget/DifferentialMotionFlingHelper.java
index 95d24ec31209..ef01c3b79059 100644
--- a/core/java/android/widget/DifferentialMotionFlingHelper.java
+++ b/core/java/android/widget/DifferentialMotionFlingHelper.java
@@ -21,6 +21,8 @@ import android.content.Context;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
+import android.widget.flags.FeatureFlags;
+import android.widget.flags.FeatureFlagsImpl;
import com.android.internal.annotations.VisibleForTesting;
@@ -50,6 +52,8 @@ public class DifferentialMotionFlingHelper {
private final FlingVelocityThresholdCalculator mVelocityThresholdCalculator;
private final DifferentialVelocityProvider mVelocityProvider;
+ private final FeatureFlags mWidgetFeatureFlags;
+
@Nullable private VelocityTracker mVelocityTracker;
private float mLastFlingVelocity;
@@ -134,7 +138,8 @@ public class DifferentialMotionFlingHelper {
this(context,
target,
DifferentialMotionFlingHelper::calculateFlingVelocityThresholds,
- DifferentialMotionFlingHelper::getCurrentVelocity);
+ DifferentialMotionFlingHelper::getCurrentVelocity,
+ /* widgetFeatureFlags= */ new FeatureFlagsImpl());
}
@VisibleForTesting
@@ -142,11 +147,13 @@ public class DifferentialMotionFlingHelper {
Context context,
DifferentialMotionFlingTarget target,
FlingVelocityThresholdCalculator velocityThresholdCalculator,
- DifferentialVelocityProvider velocityProvider) {
+ DifferentialVelocityProvider velocityProvider,
+ FeatureFlags widgetFeatureFlags) {
mContext = context;
mTarget = target;
mVelocityThresholdCalculator = velocityThresholdCalculator;
mVelocityProvider = velocityProvider;
+ mWidgetFeatureFlags = widgetFeatureFlags;
}
/**
@@ -156,6 +163,9 @@ public class DifferentialMotionFlingHelper {
* @param axis the axis being processed by the target View.
*/
public void onMotionEvent(MotionEvent event, int axis) {
+ if (!mWidgetFeatureFlags.enablePlatformWidgetDifferentialMotionFling()) {
+ return;
+ }
boolean flingParamsChanged = calculateFlingVelocityThresholds(event, axis);
if (mFlingVelocityThresholds[0] == Integer.MAX_VALUE) {
// Integer.MAX_VALUE means that the device does not support fling for the current
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index e0e72ba1b9db..a1ebde76e98e 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -47,8 +47,8 @@ import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
+import android.view.flags.Flags;
import android.view.inspector.InspectableProperty;
-import android.widget.flags.Flags;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -1011,14 +1011,14 @@ public class ScrollView extends FrameLayout {
if (newScrollY != oldScrollY) {
super.scrollTo(mScrollX, newScrollY);
if (hitLimit) {
- if (Flags.platformWidgetHapticScrollFeedback()) {
+ if (Flags.scrollFeedbackApi()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(
event.getDeviceId(), event.getSource(), axis,
/* isStart= */ newScrollY == 0);
}
} else {
- if (Flags.platformWidgetHapticScrollFeedback()) {
+ if (Flags.scrollFeedbackApi()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollProgress(
event.getDeviceId(), event.getSource(), axis, delta);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2c413300ef17..e8281eac5928 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -567,6 +567,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private float mShadowDy;
private int mShadowColor;
+ private int mLastOrientation;
+
private boolean mPreDrawRegistered;
private boolean mPreDrawListenerDetached;
@@ -1193,6 +1195,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
+ mLastOrientation = getResources().getConfiguration().orientation;
final Resources.Theme theme = context.getTheme();
@@ -4591,6 +4594,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mFontWeightAdjustment = newConfig.fontWeightAdjustment;
setTypeface(getTypeface());
}
+
+ InputMethodManager imm = getInputMethodManager();
+ // if orientation changed and this TextView is currently served.
+ if (mLastOrientation != newConfig.orientation
+ && imm != null && imm.hasActiveInputConnection(this)) {
+ // EditorInfo.internalImeOptions are out of date.
+ imm.restartInput(this);
+ }
+ mLastOrientation = newConfig.orientation;
}
/**
diff --git a/core/java/android/widget/flags/differential_motion_fling_flags.aconfig b/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
new file mode 100644
index 000000000000..79cfe566ac05
--- /dev/null
+++ b/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.widget.flags"
+
+flag {
+ namespace: "toolkit"
+ name: "enable_platform_widget_differential_motion_fling"
+ description: "Enables differential motion fling in platform widgets"
+ bug: "293332089"
+} \ No newline at end of file
diff --git a/core/java/android/widget/flags/scroll_view_flags.aconfig b/core/java/android/widget/flags/scroll_view_flags.aconfig
deleted file mode 100644
index f93ade28750b..000000000000
--- a/core/java/android/widget/flags/scroll_view_flags.aconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-package: "android.widget.flags"
-
-flag {
- namespace: "widget"
- name: "platform_widget_haptic_scroll_feedback"
- description: "Enables haptic scroll feedback in platform widgets"
- bug: "287914819"
-} \ No newline at end of file
diff --git a/core/java/android/window/SystemPerformanceHinter.java b/core/java/android/window/SystemPerformanceHinter.java
index b2c977bb1e57..e1a2b9485e13 100644
--- a/core/java/android/window/SystemPerformanceHinter.java
+++ b/core/java/android/window/SystemPerformanceHinter.java
@@ -17,6 +17,8 @@
package android.window;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
+import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN;
import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF;
@@ -29,8 +31,6 @@ import android.os.Trace;
import android.util.Log;
import android.view.SurfaceControl;
-import com.android.internal.annotations.VisibleForTesting;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Random;
@@ -148,7 +148,6 @@ public class SystemPerformanceHinter {
* Constructor for the hinter.
* @hide
*/
- @VisibleForTesting
public SystemPerformanceHinter(@NonNull Context context,
@Nullable DisplayRootProvider displayRootProvider,
@Nullable Supplier<SurfaceControl.Transaction> transactionSupplier) {
@@ -208,11 +207,14 @@ public class SystemPerformanceHinter {
boolean transactionChanged = false;
// Per-display flags
if (nowEnabled(oldPerDisplayFlags, newPerDisplayFlags, HINT_SF_FRAME_RATE)) {
- mTransaction.setFrameRateSelectionStrategy(
- mDisplayRootProvider.getRootForDisplay(session.displayId),
+ SurfaceControl displaySurfaceControl = mDisplayRootProvider.getRootForDisplay(
+ session.displayId);
+ mTransaction.setFrameRateSelectionStrategy(displaySurfaceControl,
FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN);
+ mTransaction.setFrameRateCategory(displaySurfaceControl, FRAME_RATE_CATEGORY_HIGH);
transactionChanged = true;
- Trace.beginAsyncSection("PerfHint-framerate-" + session.reason, session.traceCookie);
+ Trace.beginAsyncSection("PerfHint-framerate-" + session.displayId + "-"
+ + session.reason, session.traceCookie);
}
// Global flags
@@ -226,7 +228,7 @@ public class SystemPerformanceHinter {
Trace.beginAsyncSection("PerfHint-adpf-" + session.reason, session.traceCookie);
}
if (transactionChanged) {
- mTransaction.apply();
+ mTransaction.applyAsyncUnsafe();
}
}
@@ -245,9 +247,11 @@ public class SystemPerformanceHinter {
boolean transactionChanged = false;
// Per-display flags
if (nowDisabled(oldPerDisplayFlags, newPerDisplayFlags, HINT_SF_FRAME_RATE)) {
- mTransaction.setFrameRateSelectionStrategy(
- mDisplayRootProvider.getRootForDisplay(session.displayId),
+ SurfaceControl displaySurfaceControl = mDisplayRootProvider.getRootForDisplay(
+ session.displayId);
+ mTransaction.setFrameRateSelectionStrategy(displaySurfaceControl,
FRAME_RATE_SELECTION_STRATEGY_SELF);
+ mTransaction.setFrameRateCategory(displaySurfaceControl, FRAME_RATE_CATEGORY_DEFAULT);
transactionChanged = true;
Trace.endAsyncSection("PerfHint-framerate-" + session.reason, session.traceCookie);
}
@@ -263,7 +267,7 @@ public class SystemPerformanceHinter {
Trace.endAsyncSection("PerfHint-adpf-" + session.reason, session.traceCookie);
}
if (transactionChanged) {
- mTransaction.apply();
+ mTransaction.applyAsyncUnsafe();
}
}
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
new file mode 100644
index 000000000000..1b98806a0f01
--- /dev/null
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -0,0 +1,11 @@
+package: "com.android.window.flags"
+
+# Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
+
+flag {
+ namespace: "window_surfaces"
+ name: "surface_trusted_overlay"
+ description: "Whether to add trusted overlay flag on the SurfaceControl or the InputWindow"
+ is_fixed_read_only: true
+ bug: "292032926"
+}
diff --git a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
new file mode 100644
index 000000000000..e55c64199f45
--- /dev/null
+++ b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.display;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.util.Log;
+import android.view.Display;
+
+/**
+ * Constants and utility methods for refresh rate settings.
+ */
+public class RefreshRateSettingsUtils {
+
+ private static final String TAG = "RefreshRateSettingsUtils";
+
+ public static final float DEFAULT_REFRESH_RATE = 60f;
+
+ /**
+ * Find the highest refresh rate among all the modes of the default display.
+ *
+ * @param context The context
+ * @return The highest refresh rate
+ */
+ public static float findHighestRefreshRateForDefaultDisplay(Context context) {
+ final DisplayManager dm = context.getSystemService(DisplayManager.class);
+ final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
+
+ if (display == null) {
+ Log.w(TAG, "No valid default display device");
+ return DEFAULT_REFRESH_RATE;
+ }
+
+ float maxRefreshRate = DEFAULT_REFRESH_RATE;
+ for (Display.Mode mode : display.getSupportedModes()) {
+ if (mode.getRefreshRate() > maxRefreshRate) {
+ maxRefreshRate = mode.getRefreshRate();
+ }
+ }
+ return maxRefreshRate;
+ }
+}
diff --git a/core/java/com/android/internal/foldables/OWNERS b/core/java/com/android/internal/foldables/OWNERS
new file mode 100644
index 000000000000..6ce1ee4d3de2
--- /dev/null
+++ b/core/java/com/android/internal/foldables/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/display/OWNERS
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1be916f44f5b..85662634c22d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -290,11 +290,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
};
private Consumer<Boolean> mCrossWindowBlurEnabledListener;
+ private final WearGestureInterceptionDetector mWearGestureInterceptionDetector;
+
DecorView(Context context, int featureId, PhoneWindow window,
WindowManager.LayoutParams params) {
super(context);
mFeatureId = featureId;
-
mShowInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.linear_out_slow_in);
mHideInterpolator = AnimationUtils.loadInterpolator(context,
@@ -314,6 +315,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
updateLogTag(params);
mLegacyNavigationBarBackgroundPaint.setColor(Color.BLACK);
+
+ mWearGestureInterceptionDetector =
+ WearGestureInterceptionDetector.isEnabled(context)
+ ? new WearGestureInterceptionDetector(context, this)
+ : null;
}
void setBackgroundFallback(@Nullable Drawable fallbackDrawable) {
@@ -544,6 +550,18 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
}
+ ViewRootImpl viewRootImpl = getViewRootImpl();
+ if (viewRootImpl != null && mWearGestureInterceptionDetector != null) {
+ boolean wasIntercepting = mWearGestureInterceptionDetector.isIntercepting();
+ boolean intercepting = mWearGestureInterceptionDetector.onInterceptTouchEvent(event);
+ if (wasIntercepting != intercepting) {
+ viewRootImpl.updateDecorViewGestureInterception(intercepting);
+ }
+ if (intercepting) {
+ return true;
+ }
+ }
+
if (!SWEEP_OPEN_MENU) {
return false;
}
diff --git a/core/java/com/android/internal/policy/WearGestureInterceptionDetector.java b/core/java/com/android/internal/policy/WearGestureInterceptionDetector.java
new file mode 100644
index 000000000000..6fd50180e78b
--- /dev/null
+++ b/core/java/com/android/internal/policy/WearGestureInterceptionDetector.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+
+/**
+ * Wear-specific gesture interception detector to be installed at DecorView, for compatibility of
+ * apps depending on legacy SwipeDismissLayout behavior.
+ *
+ * <p>Results of the detector will be used by {@code DecorView} to intercept motion events. The
+ * interception state will also be sent to {@code android.view.ViewRootImpl} and {@code
+ * com.android.server.wm.DisplayContent} through {@code android.view.IWindowSession}.
+ *
+ * <p>SystemUI can register {@code android.view.IDecorViewGestureListener} to listen for the result
+ * of the detector. The result will be valid for between a pair of touch down/up events.
+ */
+public class WearGestureInterceptionDetector {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "WearGestureInterceptionDetector";
+
+ private final DecorView mInstalledDecorView;
+ private final float mTouchSlop;
+ private final float mSwipingStartThreshold;
+ private boolean mSwiping;
+
+ private float mDownX;
+ private float mDownY;
+ private int mActivePointerId;
+ private boolean mDiscardIntercept;
+
+ WearGestureInterceptionDetector(Context context, DecorView installedDecorView) {
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ mInstalledDecorView = installedDecorView;
+ mSwipingStartThreshold = mTouchSlop * 2;
+ }
+
+ /** Check if this gesture interception detector should be enabled. */
+ public static boolean isEnabled(Context context) {
+ PackageManager pm = context.getPackageManager();
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ return false;
+ }
+
+ // Compatibility check for flag that disables legacy SwipeDismissLayout.
+ TypedArray windowAttr =
+ context.obtainStyledAttributes(new int[] {android.R.attr.windowSwipeToDismiss});
+ boolean windowSwipeToDismiss = true;
+ if (windowAttr.getIndexCount() > 0) {
+ windowSwipeToDismiss = windowAttr.getBoolean(0, true);
+ }
+ windowAttr.recycle();
+ return windowSwipeToDismiss;
+ }
+
+ private boolean isPointerIndexValid(MotionEvent ev) {
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ if (DEBUG) {
+ Log.e(TAG, "Invalid pointer index: ignoring.");
+ }
+ mDiscardIntercept = true;
+ return false;
+ }
+ return true;
+ }
+
+ private void updateSwiping(MotionEvent ev) {
+ if (mSwiping) {
+ return;
+ }
+ float deltaX = ev.getRawX() - mDownX;
+ float deltaY = ev.getRawY() - mDownY;
+ // Check if we have left the touch slop area.
+ if ((deltaX * deltaX) + (deltaY * deltaY) > (mTouchSlop * mTouchSlop)) {
+ mSwiping = deltaX > mSwipingStartThreshold && Math.abs(deltaY) < Math.abs(deltaX);
+ }
+ }
+
+ private void updateDiscardIntercept(MotionEvent ev) {
+ if (!mSwiping) {
+ // Don't look at canScroll until we have passed the touch slop
+ return;
+ }
+ if (mDiscardIntercept) {
+ return;
+ }
+ final boolean checkLeft = mDownX < ev.getRawX();
+ final float x = ev.getX(mActivePointerId);
+ final float y = ev.getY(mActivePointerId);
+ if (canScroll(mInstalledDecorView, false, checkLeft, x, y)) {
+ mDiscardIntercept = true;
+ }
+ }
+
+ /** Resets internal members when canceling. */
+ private void resetMembers() {
+ mDownX = 0;
+ mDownY = 0;
+ mSwiping = false;
+ mDiscardIntercept = false;
+ }
+
+ /** Should we intercept the MotionEvent for system gesture? */
+ public boolean isIntercepting() {
+ return !mDiscardIntercept && mSwiping;
+ }
+
+ /** Tests if the MotionEvent should be intercepted */
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ resetMembers();
+ mDownX = ev.getRawX();
+ mDownY = ev.getRawY();
+ mActivePointerId = ev.getPointerId(0);
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ mActivePointerId = ev.getPointerId(ev.getActionIndex());
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ int associatedPointerIndex = ev.getActionIndex();
+ if (ev.getPointerId(associatedPointerIndex) == mActivePointerId) {
+ // This was our active pointer going up.
+ // Choose the first available pointer index.
+ int newActionIndex = associatedPointerIndex == 0 ? 1 : 0;
+ mActivePointerId = ev.getPointerId(newActionIndex);
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (mDiscardIntercept) {
+ break;
+ }
+ if (!isPointerIndexValid(ev)) {
+ break;
+ }
+ updateSwiping(ev);
+ updateDiscardIntercept(ev);
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ resetMembers();
+ break;
+ }
+ return isIntercepting();
+ }
+
+ /**
+ * Tests scroll-ability within child views of v in the direction of dx.
+ *
+ * @param v View to test for horizontal scroll-ability
+ * @param checkSelf Whether the view v passed should itself be checked for scroll-ability
+ * (true), or just its children (false).
+ * @param checkLeft Which direction to check? Left = true, right = false.
+ * @param x X coordinate of the active touch point
+ * @param y Y coordinate of the active touch point
+ * @return true if child views of v can be scrolled by delta of dx.
+ */
+ private boolean canScroll(View v, boolean checkSelf, boolean checkLeft, float x, float y) {
+ if (v instanceof ViewGroup) {
+ final ViewGroup group = (ViewGroup) v;
+ final int scrollX = v.getScrollX();
+ final int scrollY = v.getScrollY();
+ final int count = group.getChildCount();
+ for (int i = count - 1; i >= 0; i--) {
+ final View child = group.getChildAt(i);
+
+ if (x + scrollX < child.getLeft()
+ || x + scrollX >= child.getRight()
+ || y + scrollY < child.getTop()
+ || y + scrollY >= child.getBottom()) {
+ // This child is out of bound, don't bother checking.
+ continue;
+ }
+
+ // Recursively check until finding the first scrollable or none is scrollable.
+ if (canScroll(
+ /* view= */ child,
+ /* checkSelf= */ true,
+ /* checkLeft= */ checkLeft,
+ /* x= */ x + scrollX - child.getLeft(),
+ /* y= */ y + scrollY - child.getTop())) {
+ return true;
+ }
+ }
+ }
+
+ return checkSelf && v.canScrollHorizontally(checkLeft ? -1 : 1);
+ }
+}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 9384f41e26f5..f79dbe761e07 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -469,9 +469,10 @@ static void nativeSetDefaultBufferSize(JNIEnv* env, jclass clazz, jlong nativeOb
}
}
-static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
+static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync,
+ jboolean oneWay) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
- transaction->apply(sync);
+ transaction->apply(sync, oneWay);
}
static void nativeMergeTransaction(JNIEnv* env, jclass clazz,
@@ -2119,7 +2120,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetDefaultBufferSize},
{"nativeCreateTransaction", "()J",
(void*)nativeCreateTransaction },
- {"nativeApplyTransaction", "(JZ)V",
+ {"nativeApplyTransaction", "(JZZ)V",
(void*)nativeApplyTransaction },
{"nativeGetNativeTransactionFinalizer", "()J",
(void*)nativeGetNativeTransactionFinalizer },
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6c936801de18..473270229bdb 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -98,6 +98,7 @@ message SecureSettingsProto {
// Settings for font scaling
optional SettingProto accessibility_font_scaling_has_been_changed = 51 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto accessibility_force_invert_color_enabled = 52 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto accessibility_magnification_gesture = 53 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Accessibility accessibility = 2;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e34e42317c0c..a0b8cca58d9b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -48,6 +48,7 @@
<protected-broadcast android:name="android.intent.action.CANCEL_ENABLE_ROLLBACK" />
<protected-broadcast android:name="android.intent.action.ROLLBACK_COMMITTED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_RESTARTED" />
+ <protected-broadcast android:name="android.intent.action.PACKAGE_UNSTOPPED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
<protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
<protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION" />
@@ -7232,6 +7233,13 @@
android:description="@string/permdesc_fullScreenIntent"
android:protectionLevel="normal|appop" />
+ <!-- Required for the assistant apps targeting {@link android.os.Build.VERSION_CODES#V}
+ that receive voice trigger from the trusted hotword detection service.
+ <p>Protection level: signature|privileged|appop
+ @hide -->
+ <permission android:name="android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO"
+ android:protectionLevel="signature|privileged|appop" />
+
<!-- @SystemApi Allows requesting the framework broadcast the
{@link Intent#ACTION_DEVICE_CUSTOMIZATION_READY} intent.
@hide -->
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index 8b6c90141bb7..27f8138ac5e3 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -60,10 +60,11 @@
android:gravity="center"
android:textAppearance="@style/AutofillSaveUiTitle">
</TextView>
- <LinearLayout
+ <FrameLayout
android:id="@+id/autofill_save_custom_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:minHeight="0dp"
android:visibility="gone"/>
</LinearLayout>
diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml
index 2ab2d91058e2..8becb0880f97 100644
--- a/core/res/res/values-watch/dimens_material.xml
+++ b/core/res/res/values-watch/dimens_material.xml
@@ -47,11 +47,12 @@
<dimen name="progress_bar_height">24dp</dimen>
<!-- Progress bar message dimens -->
- <dimen name="message_progress_dialog_text_size">18sp</dimen>
+ <dimen name="message_progress_dialog_text_size">14sp</dimen>
<dimen name="message_progress_dialog_bottom_padding">80px</dimen>
<dimen name="message_progress_dialog_top_padding">0dp</dimen>
<dimen name="message_progress_dialog_start_padding">0dp</dimen>
<dimen name="message_progress_dialog_end_padding">0dp</dimen>
+ <item name="message_progress_dialog_letter_spacing" format="float" type="dimen">0.021</item>
<!-- fallback for screen percentage widths -->
<dimen name="screen_percentage_05">0dp</dimen>
diff --git a/core/res/res/values-watch/styles_material.xml b/core/res/res/values-watch/styles_material.xml
index 8698e86ba5f9..f3e412dc948e 100644
--- a/core/res/res/values-watch/styles_material.xml
+++ b/core/res/res/values-watch/styles_material.xml
@@ -100,7 +100,9 @@ please see styles_device_defaults.xml.
<style name="ProgressDialogMessage">
<item name="android:textAlignment">center</item>
- <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
+ <item name="android:fontFamily">google-sans-text</item>
+ <item name="android:letterSpacing">@dimen/message_progress_dialog_letter_spacing</item>
+ <item name="textColor">?attr/textColorPrimary</item>
<item name="textSize">@dimen/message_progress_dialog_text_size</item>
<item name="paddingBottom">@dimen/message_progress_dialog_bottom_padding</item>
<item name="paddingEnd">@dimen/message_progress_dialog_end_padding</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4360c5ae3dc0..7ef81abb8f0d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1151,6 +1151,14 @@
<!-- Allows activities to be launched on a long press on power during device setup. -->
<bool name="config_allowStartActivityForLongPressOnPowerInSetup">false</bool>
+ <!-- Control the behavior when the user short presses the settings button.
+ 0 - Nothing
+ 1 - Launch notification panel
+ This needs to match the constants in
+ com/android/server/policy/PhoneWindowManager.java
+ -->
+ <integer name="config_shortPressOnSettingsBehavior">0</integer>
+
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
1 - Go to sleep (doze)
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7f3069542306..643f4b148d74 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1816,6 +1816,7 @@
<java-symbol type="integer" name="config_lidNavigationAccessibility" />
<java-symbol type="integer" name="config_lidOpenRotation" />
<java-symbol type="integer" name="config_longPressOnHomeBehavior" />
+ <java-symbol type="integer" name="config_shortPressOnSettingsBehavior" />
<java-symbol type="layout" name="global_actions" />
<java-symbol type="layout" name="global_actions_item" />
<java-symbol type="layout" name="global_actions_silent_mode" />
diff --git a/core/tests/BroadcastRadioTests/Android.bp b/core/tests/BroadcastRadioTests/Android.bp
index 85d54e02d318..054d10c336e6 100644
--- a/core/tests/BroadcastRadioTests/Android.bp
+++ b/core/tests/BroadcastRadioTests/Android.bp
@@ -38,7 +38,7 @@ android_test {
static_libs: [
"services.core",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
"testng",
"mockito-target-extended",
],
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index a1952282dd0b..824f5910f96c 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -16,20 +16,20 @@
package com.android.server.broadcastradio.aidl;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.after;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertThrows;
-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.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.app.compat.CompatChanges;
import android.graphics.Bitmap;
@@ -81,8 +81,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
- private static final VerificationWithTimeout CALLBACK_TIMEOUT =
- timeout(/* millis= */ 200);
+ private static final int CALLBACK_TIMEOUT_MS = 200;
+ private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(CALLBACK_TIMEOUT_MS);
private static final int SIGNAL_QUALITY = 90;
private static final long AM_FM_FREQUENCY_SPACING = 500;
private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100};
@@ -166,12 +166,12 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Before
public void setup() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doReturn(true).when(() -> CompatChanges.isChangeEnabled(
eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
+ doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier();
+ doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
mRadioModule = new RadioModule(mBroadcastRadioMock,
AidlTestUtils.makeDefaultModuleProperties());
@@ -222,7 +222,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
return Result.OK;
}).when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean());
- when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(null);
+ doReturn(null).when(mBroadcastRadioMock).getImage(anyInt());
doAnswer(invocation -> {
int configFlag = (int) invocation.getArguments()[0];
@@ -275,7 +275,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onConfigurationChanged(FM_BAND_CONFIG);
}
@@ -446,26 +446,11 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].tune(initialSel);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(tuneInfo);
}
@Test
- public void tune_forSystemUser() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
- ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
- RadioManager.ProgramInfo tuneInfo =
- AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
- openAidlClients(/* numClients= */ 1);
-
- mTunerSessions[0].tune(initialSel);
-
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
- }
-
- @Test
public void tune_withUnknownErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
@@ -525,7 +510,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
@@ -604,7 +589,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(seekUpInfo);
}
@@ -638,6 +623,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
mTunerSessions[0].tune(initialSel);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(any());
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].cancel();
@@ -686,8 +672,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
public void getImage_whenHalThrowsException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.getImage(anyInt()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock)
+ .getImage(anyInt());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getImage(/* id= */ 1);
@@ -713,7 +699,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].startBackgroundScan();
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete();
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
+ .onBackgroundScanComplete();
}
@Test
@@ -905,7 +892,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onProgramListUpdated(any());
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
+ .onProgramListUpdated(any());
}
@Test
@@ -1160,8 +1148,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.setParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock)
+ .setParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].setParameters(parametersSet);
@@ -1186,8 +1174,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
List<String> parameterKeys = List.of("mockKey1", "mockKey2");
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.getParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock)
+ .getParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getParameters(parameterKeys);
@@ -1198,7 +1186,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
}
@Test
- public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
+ public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
@@ -1206,7 +1194,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo(
AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index fac9eaafe94c..3ec44d14b409 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -16,22 +16,22 @@
package com.android.server.broadcastradio.hal2;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.after;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
-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.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.V2_0.Constants;
@@ -78,8 +78,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
- private static final VerificationWithTimeout CALLBACK_TIMEOUT =
- timeout(/* millis= */ 200);
+ private static final int CALLBACK_TIMEOUT_MS = 200;
+ private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(CALLBACK_TIMEOUT_MS);
private static final int SIGNAL_QUALITY = 1;
private static final long AM_FM_FREQUENCY_SPACING = 500;
private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100};
@@ -113,7 +113,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
@Before
public void setup() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
+ doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier();
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
@@ -170,7 +170,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
return Result.OK;
}).when(mHalTunerSessionMock).scan(anyBoolean(), anyBoolean());
- when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(new ArrayList<Byte>(0));
+ doReturn(new ArrayList<Byte>(0)).when(mBroadcastRadioMock).getImage(anyInt());
doAnswer(invocation -> {
int configFlag = (int) invocation.getArguments()[0];
@@ -227,7 +227,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onConfigurationChanged(FM_BAND_CONFIG);
}
@@ -379,7 +379,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].tune(initialSel);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(tuneInfo);
}
@@ -398,20 +398,6 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
}
@Test
- public void tune_forSystemUser() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
- ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
- RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
- openAidlClients(/* numClients= */ 1);
-
- mTunerSessions[0].tune(initialSel);
-
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
- }
-
- @Test
public void step_withDirectionUp() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[1];
ProgramSelector initialSel = TestUtils.makeFmSelector(initFreq);
@@ -455,7 +441,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
@@ -533,7 +519,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(seekUpInfo);
}
@@ -563,22 +549,11 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
}
@Test
- public void cancel_forNonCurrentUser() throws Exception {
- openAidlClients(/* numClients= */ 1);
- ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
- mTunerSessions[0].tune(initialSel);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
-
- mTunerSessions[0].cancel();
-
- verify(mHalTunerSessionMock, never()).cancel();
- }
-
- @Test
public void cancel_forNonCurrentUser_doesNotCancel() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
mTunerSessions[0].tune(initialSel);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(any());
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].cancel();
@@ -627,8 +602,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
public void getImage_whenHalThrowsException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.getImage(anyInt()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock).getImage(anyInt());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getImage(/* id= */ 1);
@@ -654,7 +628,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].startBackgroundScan();
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete();
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
+ .onBackgroundScanComplete();
}
@Test
@@ -845,8 +820,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
String exceptionMessage = "HAL service died.";
- when(mHalTunerSessionMock.setParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mHalTunerSessionMock)
+ .setParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].setParameters(parametersSet);
@@ -871,8 +846,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
List<String> parameterKeys = List.of("mockKey1", "mockKey2");
String exceptionMessage = "HAL service died.";
- when(mHalTunerSessionMock.getParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mHalTunerSessionMock)
+ .getParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getParameters(parameterKeys);
@@ -883,7 +858,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
}
@Test
- public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
+ public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
@@ -891,7 +866,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo(
TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp
index 8c5d6d5a76a1..0e3bc6562edb 100644
--- a/core/tests/GameManagerTests/Android.bp
+++ b/core/tests/GameManagerTests/Android.bp
@@ -30,7 +30,7 @@ android_test {
"frameworks-base-testutils",
"junit",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/PackageInstallerSessions/Android.bp b/core/tests/PackageInstallerSessions/Android.bp
index 6f2366e32574..b631df1fcf57 100644
--- a/core/tests/PackageInstallerSessions/Android.bp
+++ b/core/tests/PackageInstallerSessions/Android.bp
@@ -35,7 +35,7 @@ android_test {
"frameworks-base-testutils",
"platform-test-annotations",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
index 52608351775c..1fb5f2c0789b 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
@@ -18,7 +18,7 @@ android_test {
"platform-test-annotations",
"platformprotosnano",
"statsdprotolite",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index 2b34ee2646f3..7c1ac487bfdb 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -32,7 +32,7 @@ android_test {
static_libs: [
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
- "truth-prebuilt",
+ "truth",
],
test_suites: ["general-tests"],
sdk_version: "test_current",
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 04622fda75df..2993a0e63228 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -58,12 +58,13 @@ android_test {
"androidx.test.uiautomator_uiautomator",
"platform-test-annotations",
"platform-compat-test-rules",
- "truth-prebuilt",
+ "truth",
"print-test-util-lib",
"testng",
"servicestests-utils",
"device-time-shell-utils",
"testables",
+ "com.android.text.flags-aconfig-java",
],
libs: [
@@ -149,7 +150,7 @@ android_library {
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: [
diff --git a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
index a8a5059eea20..3f78396e3a70 100644
--- a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
+++ b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
@@ -16,6 +16,8 @@
package android.graphics;
+import static com.android.text.flags.Flags.FLAG_CUSTOM_LOCALE_FALLBACK;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -30,6 +32,9 @@ import android.graphics.fonts.FontFamily;
import android.graphics.fonts.SystemFonts;
import android.graphics.text.PositionedGlyphs;
import android.graphics.text.TextRunShaper;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.text.FontConfig;
import android.util.ArrayMap;
@@ -39,6 +44,7 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParserException;
@@ -107,6 +113,10 @@ public class TypefaceSystemFallbackTest {
GLYPH_2EM_WIDTH = paint.measureText("a");
}
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() {
final AssetManager am =
@@ -877,6 +887,130 @@ public class TypefaceSystemFallbackTest {
assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
}
+ private static void assertA3emFontIsUsed(Typeface typeface) {
+ final Paint paint = new Paint();
+ assertNotNull(typeface);
+ paint.setTypeface(typeface);
+ assertTrue("a3em font must be used", GLYPH_3EM_WIDTH == paint.measureText("a")
+ && GLYPH_1EM_WIDTH == paint.measureText("b")
+ && GLYPH_1EM_WIDTH == paint.measureText("c"));
+ }
+
+ private static void assertB3emFontIsUsed(Typeface typeface) {
+ final Paint paint = new Paint();
+ assertNotNull(typeface);
+ paint.setTypeface(typeface);
+ assertTrue("b3em font must be used", GLYPH_1EM_WIDTH == paint.measureText("a")
+ && GLYPH_3EM_WIDTH == paint.measureText("b")
+ && GLYPH_1EM_WIDTH == paint.measureText("c"));
+ }
+
+ private static String getBaseXml(String font, String lang) {
+ final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<familyset>"
+ + " <family>"
+ + " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ + " </family>"
+ + " <family name='named-family'>"
+ + " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ + " </family>"
+ + " <family lang='%s'>"
+ + " <font weight='400' style='normal'>%s</font>"
+ + " </family>"
+ + "</familyset>";
+ return String.format(xml, lang, font);
+ }
+
+ private static String getCustomizationXml(String font, String op, String lang) {
+ final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<fonts-modification version='1'>"
+ + " <family customizationType='new-locale-family' operation='%s' lang='%s'>"
+ + " <font weight='400' style='normal' fallbackFor='named-family'>%s</font>"
+ + " </family>"
+ + "</fonts-modification>";
+ return String.format(xml, op, lang, font);
+ }
+
+ @RequiresFlagsEnabled(FLAG_CUSTOM_LOCALE_FALLBACK)
+ @Test
+ public void testBuildSystemFallback__Customization_locale_prepend() {
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+
+ buildSystemFallback(
+ getBaseXml("a3em.ttf", "ja-JP"),
+ getCustomizationXml("b3em.ttf", "prepend", "ja-JP"),
+ fontMap, fallbackMap);
+ Typeface typeface = fontMap.get("named-family");
+
+ // operation "prepend" places font before the original font, thus b3em is used.
+ assertB3emFontIsUsed(typeface);
+ }
+
+ @RequiresFlagsEnabled(FLAG_CUSTOM_LOCALE_FALLBACK)
+ @Test
+ public void testBuildSystemFallback__Customization_locale_replace() {
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+
+ buildSystemFallback(
+ getBaseXml("a3em.ttf", "ja-JP"),
+ getCustomizationXml("b3em.ttf", "replace", "ja-JP"),
+ fontMap, fallbackMap);
+ Typeface typeface = fontMap.get("named-family");
+
+ // operation "replace" removes the original font, thus b3em font is used.
+ assertB3emFontIsUsed(typeface);
+ }
+
+ @RequiresFlagsEnabled(FLAG_CUSTOM_LOCALE_FALLBACK)
+ @Test
+ public void testBuildSystemFallback__Customization_locale_append() {
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+
+ buildSystemFallback(
+ getBaseXml("a3em.ttf", "ja-JP"),
+ getCustomizationXml("b3em.ttf", "append", "ja-JP"),
+ fontMap, fallbackMap);
+ Typeface typeface = fontMap.get("named-family");
+
+ // operation "append" comes next to the original font, so the original "a3em" is used.
+ assertA3emFontIsUsed(typeface);
+ }
+
+ @RequiresFlagsEnabled(FLAG_CUSTOM_LOCALE_FALLBACK)
+ @Test
+ public void testBuildSystemFallback__Customization_locale_ScriptMismatch() {
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+
+ buildSystemFallback(
+ getBaseXml("a3em.ttf", "ja-JP"),
+ getCustomizationXml("b3em.ttf", "replace", "ko-KR"),
+ fontMap, fallbackMap);
+ Typeface typeface = fontMap.get("named-family");
+
+ // Since the script doesn't match, the customization is ignored.
+ assertA3emFontIsUsed(typeface);
+ }
+
+ @RequiresFlagsEnabled(FLAG_CUSTOM_LOCALE_FALLBACK)
+ @Test
+ public void testBuildSystemFallback__Customization_locale_SubscriptMatch() {
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+
+ buildSystemFallback(
+ getBaseXml("a3em.ttf", "ja-JP"),
+ getCustomizationXml("b3em.ttf", "replace", "ko-Hani-KR"),
+ fontMap, fallbackMap);
+ Typeface typeface = fontMap.get("named-family");
+
+ // Hani script is supported by Japanese, Jpan.
+ assertB3emFontIsUsed(typeface);
+ }
+
@Test(expected = IllegalArgumentException.class)
public void testBuildSystemFallback__Customization_new_named_family_no_name_exception() {
final String oemXml = "<?xml version='1.0' encoding='UTF-8'?>"
@@ -902,7 +1036,6 @@ public class TypefaceSystemFallbackTest {
readFontCustomization(oemXml);
}
-
@Test
public void testBuildSystemFallback_UpdatableFont() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
diff --git a/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java b/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
index 55ded9c8813d..bfdb15b7f7c8 100644
--- a/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
+++ b/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
@@ -16,6 +16,10 @@
package android.service.notification;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
+
import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.RANKING_UPDATE_ASHMEM;
import static junit.framework.Assert.assertEquals;
@@ -24,20 +28,38 @@ import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Mockito.spy;
+
+import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.os.Bundle;
import android.os.Parcel;
+import android.os.SharedMemory;
+import android.testing.TestableContext;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import java.util.ArrayList;
+import java.util.List;
+
@SmallTest
@RunWith(Parameterized.class)
public class NotificationRankingUpdateTest {
@@ -56,6 +78,345 @@ public class NotificationRankingUpdateTest {
@Parameterized.Parameter
public boolean mRankingUpdateAshmem;
+ @Rule
+ public TestableContext mContext =
+ spy(new TestableContext(InstrumentationRegistry.getContext(), null));
+
+ protected TestableContext getContext() {
+ return mContext;
+ }
+
+ public static String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
+
+ /**
+ * Creates a NotificationRankingUpdate with prepopulated Ranking entries
+ * @param context A testable context, used for PendingIntent creation
+ * @return The NotificationRankingUpdate to be used as test data
+ */
+ public static NotificationRankingUpdate generateUpdate(TestableContext context) {
+ NotificationListenerService.Ranking[] rankings =
+ new NotificationListenerService.Ranking[mKeys.length];
+ for (int i = 0; i < mKeys.length; i++) {
+ final String key = mKeys[i];
+ NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking();
+ ranking.populate(
+ key,
+ i,
+ !isIntercepted(i),
+ getVisibilityOverride(i),
+ getSuppressedVisualEffects(i),
+ getImportance(i),
+ getExplanation(key),
+ getOverrideGroupKey(key),
+ getChannel(key, i),
+ getPeople(key, i),
+ getSnoozeCriteria(key, i),
+ getShowBadge(i),
+ getUserSentiment(i),
+ getHidden(i),
+ lastAudiblyAlerted(i),
+ getNoisy(i),
+ getSmartActions(key, i, context),
+ getSmartReplies(key, i),
+ canBubble(i),
+ isTextChanged(i),
+ isConversation(i),
+ getShortcutInfo(i),
+ getRankingAdjustment(i),
+ isBubble(i),
+ getProposedImportance(i),
+ hasSensitiveContent(i)
+ );
+ rankings[i] = ranking;
+ }
+ return new NotificationRankingUpdate(rankings);
+ }
+
+ /**
+ * Produces a visibility override value based on the provided index.
+ */
+ public static int getVisibilityOverride(int index) {
+ return index * 9;
+ }
+
+ /**
+ * Produces a group key based on the provided key.
+ */
+ public static String getOverrideGroupKey(String key) {
+ return key + key;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent isIntercepted, based on the provided index.
+ */
+ public static boolean isIntercepted(int index) {
+ return index % 2 == 0;
+ }
+
+ /**
+ * Produces a suppressed visual effects value based on the provided index
+ */
+ public static int getSuppressedVisualEffects(int index) {
+ return index * 2;
+ }
+
+ /**
+ * Produces an importance value, based on the provided index
+ */
+ public static int getImportance(int index) {
+ return index;
+ }
+
+ /**
+ * Produces an explanation value, based on the provided key
+ */
+ public static String getExplanation(String key) {
+ return key + "explain";
+ }
+
+ /**
+ * Produces a notification channel, based on the provided key and index
+ */
+ public static NotificationChannel getChannel(String key, int index) {
+ return new NotificationChannel(key, key, getImportance(index));
+ }
+
+ /**
+ * Produces a boolean that can be used to represent showBadge, based on the provided index
+ */
+ public static boolean getShowBadge(int index) {
+ return index % 3 == 0;
+ }
+
+ /**
+ * Produces a user sentiment value, based on the provided index
+ */
+ public static int getUserSentiment(int index) {
+ switch(index % 3) {
+ case 0:
+ return USER_SENTIMENT_NEGATIVE;
+ case 1:
+ return USER_SENTIMENT_NEUTRAL;
+ case 2:
+ return USER_SENTIMENT_POSITIVE;
+ }
+ return USER_SENTIMENT_NEUTRAL;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent "hidden," based on the provided index.
+ */
+ public static boolean getHidden(int index) {
+ return index % 2 == 0;
+ }
+
+ /**
+ * Produces a long to represent lastAudiblyAlerted based on the provided index.
+ */
+ public static long lastAudiblyAlerted(int index) {
+ return index * 2000L;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent "noisy," based on the provided index.
+ */
+ public static boolean getNoisy(int index) {
+ return index < 1;
+ }
+
+ /**
+ * Produces strings that can be used to represent people, based on the provided key and index.
+ */
+ public static ArrayList<String> getPeople(String key, int index) {
+ ArrayList<String> people = new ArrayList<>();
+ for (int i = 0; i < index; i++) {
+ people.add(i + key);
+ }
+ return people;
+ }
+
+ /**
+ * Produces a number of snoozeCriteria, based on the provided key and index.
+ */
+ public static ArrayList<SnoozeCriterion> getSnoozeCriteria(String key, int index) {
+ ArrayList<SnoozeCriterion> snooze = new ArrayList<>();
+ for (int i = 0; i < index; i++) {
+ snooze.add(new SnoozeCriterion(key + i, getExplanation(key), key));
+ }
+ return snooze;
+ }
+
+ /**
+ * Produces a list of Actions which can be used to represent smartActions.
+ * These actions are built from pending intents with intent titles based on the provided
+ * key, and ids based on the provided index.
+ */
+ public static ArrayList<Notification.Action> getSmartActions(String key,
+ int index,
+ TestableContext context) {
+ ArrayList<Notification.Action> actions = new ArrayList<>();
+ for (int i = 0; i < index; i++) {
+ PendingIntent intent = PendingIntent.getBroadcast(
+ context,
+ index /*requestCode*/,
+ new Intent("ACTION_" + key),
+ PendingIntent.FLAG_IMMUTABLE /*flags*/);
+ actions.add(new Notification.Action.Builder(null /*icon*/, key, intent).build());
+ }
+ return actions;
+ }
+
+ /**
+ * Produces index number of "smart replies," all based on the provided key and index
+ */
+ public static ArrayList<CharSequence> getSmartReplies(String key, int index) {
+ ArrayList<CharSequence> choices = new ArrayList<>();
+ for (int i = 0; i < index; i++) {
+ choices.add("choice_" + key + "_" + i);
+ }
+ return choices;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent canBubble, based on the provided index
+ */
+ public static boolean canBubble(int index) {
+ return index % 4 == 0;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent isTextChanged, based on the provided index.
+ */
+ public static boolean isTextChanged(int index) {
+ return index % 4 == 0;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent isConversation, based on the provided index.
+ */
+ public static boolean isConversation(int index) {
+ return index % 4 == 0;
+ }
+
+ /**
+ * Produces a ShortcutInfo value based on the provided index.
+ */
+ public static ShortcutInfo getShortcutInfo(int index) {
+ ShortcutInfo si = new ShortcutInfo(
+ index, String.valueOf(index), "packageName", new ComponentName("1", "1"), null,
+ "title", 0, "titleResName", "text", 0, "textResName",
+ "disabledMessage", 0, "disabledMessageResName",
+ null, null, 0, null, 0, 0,
+ 0, "iconResName", "bitmapPath", null, 0,
+ null, null, null, null);
+ return si;
+ }
+
+ /**
+ * Produces a rankingAdjustment value, based on the provided index.
+ */
+ public static int getRankingAdjustment(int index) {
+ return index % 3 - 1;
+ }
+
+ /**
+ * Produces a proposedImportance, based on the provided index.
+ */
+ public static int getProposedImportance(int index) {
+ return index % 5 - 1;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent hasSensitiveContent, based on the provided
+ * index.
+ */
+ public static boolean hasSensitiveContent(int index) {
+ return index % 3 == 0;
+ }
+
+ /**
+ * Produces a boolean that can be used to represent isBubble, based on the provided index.
+ */
+ public static boolean isBubble(int index) {
+ return index % 4 == 0;
+ }
+
+ /**
+ * Checks that each of the pairs of actions in the two provided lists has identical titles,
+ * and that the lists have the same number of elements.
+ */
+ public void assertActionsEqual(
+ List<Notification.Action> expecteds, List<Notification.Action> actuals) {
+ Assert.assertEquals(expecteds.size(), actuals.size());
+ for (int i = 0; i < expecteds.size(); i++) {
+ Notification.Action expected = expecteds.get(i);
+ Notification.Action actual = actuals.get(i);
+ Assert.assertEquals(expected.title.toString(), actual.title.toString());
+ }
+ }
+
+ /**
+ * Checks that all subelements of the provided NotificationRankingUpdates are equal.
+ */
+ public void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
+ detailedAssertEquals(a.getRankingMap(), b.getRankingMap());
+ }
+
+ /**
+ * Checks that all subelements of the provided Ranking objects are equal.
+ */
+ public void detailedAssertEquals(String comment, NotificationListenerService.Ranking a,
+ NotificationListenerService.Ranking b) {
+ Assert.assertEquals(comment, a.getKey(), b.getKey());
+ Assert.assertEquals(comment, a.getRank(), b.getRank());
+ Assert.assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
+ Assert.assertEquals(comment, a.getLockscreenVisibilityOverride(),
+ b.getLockscreenVisibilityOverride());
+ Assert.assertEquals(comment, a.getSuppressedVisualEffects(),
+ b.getSuppressedVisualEffects());
+ Assert.assertEquals(comment, a.getImportance(), b.getImportance());
+ Assert.assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
+ Assert.assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
+ Assert.assertEquals(comment, a.getChannel().toString(), b.getChannel().toString());
+ Assert.assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
+ Assert.assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
+ Assert.assertEquals(comment, a.canShowBadge(), b.canShowBadge());
+ Assert.assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
+ Assert.assertEquals(comment, a.isSuspended(), b.isSuspended());
+ Assert.assertEquals(comment, a.getLastAudiblyAlertedMillis(),
+ b.getLastAudiblyAlertedMillis());
+ Assert.assertEquals(comment, a.isNoisy(), b.isNoisy());
+ Assert.assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
+ Assert.assertEquals(comment, a.canBubble(), b.canBubble());
+ Assert.assertEquals(comment, a.isConversation(), b.isConversation());
+ if (a.getConversationShortcutInfo() != null && b.getConversationShortcutInfo() != null) {
+ Assert.assertEquals(comment, a.getConversationShortcutInfo().getId(),
+ b.getConversationShortcutInfo().getId());
+ } else {
+ // One or both must be null, so we can check for equality.
+ Assert.assertEquals(a.getConversationShortcutInfo(), b.getConversationShortcutInfo());
+ }
+ assertActionsEqual(a.getSmartActions(), b.getSmartActions());
+ Assert.assertEquals(a.getProposedImportance(), b.getProposedImportance());
+ Assert.assertEquals(a.hasSensitiveContent(), b.hasSensitiveContent());
+ }
+
+ /**
+ * Checks that the two RankingMaps have identical keys, and that each Ranking object for
+ * each of those keys is identical.
+ */
+ public void detailedAssertEquals(NotificationListenerService.RankingMap a,
+ NotificationListenerService.RankingMap b) {
+ NotificationListenerService.Ranking arank = new NotificationListenerService.Ranking();
+ NotificationListenerService.Ranking brank = new NotificationListenerService.Ranking();
+ assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
+ for (String key : a.getOrderedKeys()) {
+ a.getRanking(key, arank);
+ b.getRanking(key, brank);
+ detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
+ }
+ }
+
@Before
public void setUp() {
mNotificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "test channel",
@@ -74,8 +435,13 @@ public class NotificationRankingUpdateTest {
SystemUiSystemPropertiesFlags.TEST_RESOLVER = null;
}
- public NotificationListenerService.Ranking createTestRanking(String key, int rank) {
+ /**
+ * Creates a mostly empty Test Ranking object with the specified key, rank, and smartActions.
+ */
+ public NotificationListenerService.Ranking createEmptyTestRanking(
+ String key, int rank, ArrayList<Notification.Action> actions) {
NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking();
+
ranking.populate(
/* key= */ key,
/* rank= */ rank,
@@ -93,7 +459,7 @@ public class NotificationRankingUpdateTest {
/* hidden= */ false,
/* lastAudiblyAlertedMs= */ -1,
/* noisy= */ false,
- /* smartActions= */ null,
+ /* smartActions= */ actions,
/* smartReplies= */ null,
/* canBubble= */ false,
/* isTextChanged= */ false,
@@ -107,54 +473,111 @@ public class NotificationRankingUpdateTest {
return ranking;
}
+ // Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking.
@Test
- public void testRankingUpdate_rankingConstructor() {
- NotificationListenerService.Ranking ranking = createTestRanking(TEST_KEY, 123);
- NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
- new NotificationListenerService.Ranking[]{ranking});
+ public void testRankingUpdate_parcel() {
+ NotificationRankingUpdate nru = generateUpdate(getContext());
+ Parcel parcel = Parcel.obtain();
+ nru.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel);
+ // The rankingUpdate file descriptor is only non-null in the new path.
+ if (SystemUiSystemPropertiesFlags.getResolver().isEnabled(
+ SystemUiSystemPropertiesFlags.NotificationFlags.RANKING_UPDATE_ASHMEM)) {
+ assertTrue(nru1.isFdNotNullAndClosed());
+ }
+ detailedAssertEquals(nru, nru1);
+ parcel.recycle();
+ }
+
+ // Tests parceling of RankingMap and RankingMap.equals
+ @Test
+ public void testRankingMap_parcel() {
+ NotificationListenerService.RankingMap rmap = generateUpdate(getContext()).getRankingMap();
+ Parcel parcel = Parcel.obtain();
+ rmap.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ NotificationListenerService.RankingMap rmap1 =
+ NotificationListenerService.RankingMap.CREATOR.createFromParcel(parcel);
- NotificationListenerService.RankingMap retrievedRankings = rankingUpdate.getRankingMap();
- NotificationListenerService.Ranking retrievedRanking =
- new NotificationListenerService.Ranking();
- assertTrue(retrievedRankings.getRanking(TEST_KEY, retrievedRanking));
- assertEquals(123, retrievedRanking.getRank());
+ detailedAssertEquals(rmap, rmap1);
+ Assert.assertEquals(rmap, rmap1);
+ parcel.recycle();
}
+ // Tests parceling of Ranking and Ranking.equals
@Test
- public void testRankingUpdate_parcelConstructor() {
- NotificationListenerService.Ranking ranking = createTestRanking(TEST_KEY, 123);
- NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
- new NotificationListenerService.Ranking[]{ranking});
+ public void testRanking_parcel() {
+ NotificationListenerService.Ranking ranking =
+ generateUpdate(getContext()).getRankingMap().getRawRankingObject(mKeys[0]);
+ Parcel parcel = Parcel.obtain();
+ ranking.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ NotificationListenerService.Ranking ranking1 =
+ new NotificationListenerService.Ranking(parcel);
+ detailedAssertEquals("rankings differ: ", ranking, ranking1);
+ Assert.assertEquals(ranking, ranking1);
+ parcel.recycle();
+ }
- Parcel parceledRankingUpdate = Parcel.obtain();
- rankingUpdate.writeToParcel(parceledRankingUpdate, 0);
- parceledRankingUpdate.setDataPosition(0);
+ // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking.
+ @Test
+ public void testRankingUpdate_equals_legacy() {
+ NotificationRankingUpdate nru = generateUpdate(getContext());
+ NotificationRankingUpdate nru2 = generateUpdate(getContext());
+ detailedAssertEquals(nru, nru2);
+ Assert.assertEquals(nru, nru2);
+ NotificationListenerService.Ranking tweak =
+ nru2.getRankingMap().getRawRankingObject(mKeys[0]);
+ tweak.populate(
+ tweak.getKey(),
+ tweak.getRank(),
+ !tweak.matchesInterruptionFilter(), // note the inversion here!
+ tweak.getLockscreenVisibilityOverride(),
+ tweak.getSuppressedVisualEffects(),
+ tweak.getImportance(),
+ tweak.getImportanceExplanation(),
+ tweak.getOverrideGroupKey(),
+ tweak.getChannel(),
+ (ArrayList) tweak.getAdditionalPeople(),
+ (ArrayList) tweak.getSnoozeCriteria(),
+ tweak.canShowBadge(),
+ tweak.getUserSentiment(),
+ tweak.isSuspended(),
+ tweak.getLastAudiblyAlertedMillis(),
+ tweak.isNoisy(),
+ (ArrayList) tweak.getSmartActions(),
+ (ArrayList) tweak.getSmartReplies(),
+ tweak.canBubble(),
+ tweak.isTextChanged(),
+ tweak.isConversation(),
+ tweak.getConversationShortcutInfo(),
+ tweak.getRankingAdjustment(),
+ tweak.isBubble(),
+ tweak.getProposedImportance(),
+ tweak.hasSensitiveContent()
+ );
+ assertNotEquals(nru, nru2);
+ }
- NotificationRankingUpdate retrievedRankingUpdate = new NotificationRankingUpdate(
- parceledRankingUpdate);
+ @Test
+ public void testRankingUpdate_rankingConstructor() {
+ NotificationRankingUpdate nru = generateUpdate(getContext());
+ NotificationRankingUpdate constructedNru = new NotificationRankingUpdate(
+ new NotificationListenerService.Ranking[]{
+ nru.getRankingMap().getRawRankingObject(mKeys[0]),
+ nru.getRankingMap().getRawRankingObject(mKeys[1]),
+ nru.getRankingMap().getRawRankingObject(mKeys[2]),
+ nru.getRankingMap().getRawRankingObject(mKeys[3]),
+ nru.getRankingMap().getRawRankingObject(mKeys[4])
+ });
- NotificationListenerService.RankingMap retrievedRankings =
- retrievedRankingUpdate.getRankingMap();
- assertNotNull(retrievedRankings);
- // The rankingUpdate file descriptor is only non-null in the new path.
- if (SystemUiSystemPropertiesFlags.getResolver().isEnabled(
- SystemUiSystemPropertiesFlags.NotificationFlags.RANKING_UPDATE_ASHMEM)) {
- assertTrue(retrievedRankingUpdate.isFdNotNullAndClosed());
- }
- NotificationListenerService.Ranking retrievedRanking =
- new NotificationListenerService.Ranking();
- assertTrue(retrievedRankings.getRanking(TEST_KEY, retrievedRanking));
- assertEquals(123, retrievedRanking.getRank());
- assertTrue(retrievedRankingUpdate.equals(rankingUpdate));
- parceledRankingUpdate.recycle();
+ detailedAssertEquals(nru, constructedNru);
}
@Test
public void testRankingUpdate_emptyParcelInCheck() {
- NotificationListenerService.Ranking ranking = createTestRanking(TEST_KEY, 123);
- NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
- new NotificationListenerService.Ranking[]{ranking});
-
+ NotificationRankingUpdate rankingUpdate = generateUpdate(getContext());
Parcel parceledRankingUpdate = Parcel.obtain();
rankingUpdate.writeToParcel(parceledRankingUpdate, 0);
@@ -163,37 +586,119 @@ public class NotificationRankingUpdateTest {
NotificationRankingUpdate retrievedRankingUpdate = new NotificationRankingUpdate(
parceledRankingUpdate);
assertNull(retrievedRankingUpdate.getRankingMap());
+ parceledRankingUpdate.recycle();
}
@Test
public void testRankingUpdate_describeContents() {
- NotificationListenerService.Ranking ranking = createTestRanking(TEST_KEY, 123);
- NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
- new NotificationListenerService.Ranking[]{ranking});
+ NotificationRankingUpdate rankingUpdate = generateUpdate(getContext());
assertEquals(0, rankingUpdate.describeContents());
}
@Test
public void testRankingUpdate_equals() {
- NotificationListenerService.Ranking ranking = createTestRanking(TEST_KEY, 123);
+ NotificationListenerService.Ranking ranking = createEmptyTestRanking(TEST_KEY, 123, null);
NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
new NotificationListenerService.Ranking[]{ranking});
- // Reflexive equality.
- assertTrue(rankingUpdate.equals(rankingUpdate));
- // Null or wrong class inequality.
+ // Reflexive equality, including handling nulls properly
+ detailedAssertEquals(rankingUpdate, rankingUpdate);
+ // Null or wrong class inequality
assertFalse(rankingUpdate.equals(null));
assertFalse(rankingUpdate.equals(ranking));
- // Different ranking contents inequality.
- NotificationListenerService.Ranking ranking2 = createTestRanking(TEST_KEY, 456);
+ // Different rank inequality
+ NotificationListenerService.Ranking ranking2 = createEmptyTestRanking(TEST_KEY, 456, null);
NotificationRankingUpdate rankingUpdate2 = new NotificationRankingUpdate(
new NotificationListenerService.Ranking[]{ranking2});
assertFalse(rankingUpdate.equals(rankingUpdate2));
- // Same ranking contents equality.
- ranking2 = createTestRanking(TEST_KEY, 123);
+ // Different key inequality
+ ranking2 = createEmptyTestRanking(TEST_KEY + "DIFFERENT", 123, null);
rankingUpdate2 = new NotificationRankingUpdate(
new NotificationListenerService.Ranking[]{ranking2});
- assertTrue(rankingUpdate.equals(rankingUpdate2));
+ assertFalse(rankingUpdate.equals(rankingUpdate2));
+ }
+
+ @Test
+ public void testRankingUpdate_writesSmartActionToParcel() {
+ if (!mRankingUpdateAshmem) {
+ return;
+ }
+ ArrayList<Notification.Action> actions = new ArrayList<>();
+ PendingIntent intent = PendingIntent.getBroadcast(
+ getContext(),
+ 0 /*requestCode*/,
+ new Intent("ACTION_" + TEST_KEY),
+ PendingIntent.FLAG_IMMUTABLE /*flags*/);
+ actions.add(new Notification.Action.Builder(null /*icon*/, TEST_KEY, intent).build());
+
+ NotificationListenerService.Ranking ranking =
+ createEmptyTestRanking(TEST_KEY, 123, actions);
+ NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
+ new NotificationListenerService.Ranking[]{ranking});
+
+ Parcel parcel = Parcel.obtain();
+ rankingUpdate.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ SharedMemory fd = parcel.readParcelable(getClass().getClassLoader(), SharedMemory.class);
+ Bundle smartActionsBundle = parcel.readBundle(getClass().getClassLoader());
+
+ // Assert the file descriptor is valid
+ assertNotNull(fd);
+ assertFalse(fd.getFd() == -1);
+
+ // Assert that the smart action is in the parcel
+ assertNotNull(smartActionsBundle);
+ ArrayList<Notification.Action> recoveredActions =
+ smartActionsBundle.getParcelableArrayList(TEST_KEY, Notification.Action.class);
+ assertNotNull(recoveredActions);
+ assertEquals(actions.size(), recoveredActions.size());
+ assertEquals(actions.get(0).title.toString(), recoveredActions.get(0).title.toString());
+ parcel.recycle();
+ }
+
+ @Test
+ public void testRankingUpdate_handlesEmptySmartActionList() {
+ if (!mRankingUpdateAshmem) {
+ return;
+ }
+ ArrayList<Notification.Action> actions = new ArrayList<>();
+ NotificationListenerService.Ranking ranking =
+ createEmptyTestRanking(TEST_KEY, 123, actions);
+ NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
+ new NotificationListenerService.Ranking[]{ranking});
+
+ Parcel parcel = Parcel.obtain();
+ rankingUpdate.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ // Ensure that despite an empty actions list, we can still unparcel the update.
+ NotificationRankingUpdate newRankingUpdate = new NotificationRankingUpdate(parcel);
+ assertNotNull(newRankingUpdate);
+ assertNotNull(newRankingUpdate.getRankingMap());
+ detailedAssertEquals(rankingUpdate, newRankingUpdate);
+ parcel.recycle();
+ }
+
+ @Test
+ public void testRankingUpdate_handlesNullSmartActionList() {
+ if (!mRankingUpdateAshmem) {
+ return;
+ }
+ NotificationListenerService.Ranking ranking =
+ createEmptyTestRanking(TEST_KEY, 123, null);
+ NotificationRankingUpdate rankingUpdate = new NotificationRankingUpdate(
+ new NotificationListenerService.Ranking[]{ranking});
+
+ Parcel parcel = Parcel.obtain();
+ rankingUpdate.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ // Ensure that despite an empty actions list, we can still unparcel the update.
+ NotificationRankingUpdate newRankingUpdate = new NotificationRankingUpdate(parcel);
+ assertNotNull(newRankingUpdate);
+ assertNotNull(newRankingUpdate.getRankingMap());
+ detailedAssertEquals(rankingUpdate, newRankingUpdate);
+ parcel.recycle();
}
}
diff --git a/core/tests/coretests/src/android/widget/DifferentialMotionFlingHelperTest.java b/core/tests/coretests/src/android/widget/DifferentialMotionFlingHelperTest.java
index 51c8bc06e878..cce2faf71897 100644
--- a/core/tests/coretests/src/android/widget/DifferentialMotionFlingHelperTest.java
+++ b/core/tests/coretests/src/android/widget/DifferentialMotionFlingHelperTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import android.view.MotionEvent;
+import android.widget.flags.FakeFeatureFlagsImpl;
+import android.widget.flags.Flags;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -54,6 +56,8 @@ public class DifferentialMotionFlingHelperTest {
private final TestDifferentialMotionFlingTarget mFlingTarget =
new TestDifferentialMotionFlingTarget();
+ private final FakeFeatureFlagsImpl mFakeWidgetFeatureFlags = new FakeFeatureFlagsImpl();
+
private DifferentialMotionFlingHelper mFlingHelper;
@Before
@@ -62,7 +66,10 @@ public class DifferentialMotionFlingHelperTest {
ApplicationProvider.getApplicationContext(),
mFlingTarget,
mVelocityThresholdCalculator,
- mVelocityProvider);
+ mVelocityProvider,
+ mFakeWidgetFeatureFlags);
+ mFakeWidgetFeatureFlags.setFlag(
+ Flags.FLAG_ENABLE_PLATFORM_WIDGET_DIFFERENTIAL_MOTION_FLING, true);
}
@Test
@@ -139,6 +146,18 @@ public class DifferentialMotionFlingHelperTest {
}
@Test
+ public void flingFeatureFlagDisabled_noFlingCalculation() {
+ mFakeWidgetFeatureFlags.setFlag(
+ Flags.FLAG_ENABLE_PLATFORM_WIDGET_DIFFERENTIAL_MOTION_FLING, false);
+ mMinVelocity = 50;
+ mMaxVelocity = 100;
+ deliverEventWithVelocity(createPointerEvent(), MotionEvent.AXIS_VSCROLL, 60);
+
+ assertFalse(mVelocityCalculated);
+ assertEquals(0, mFlingTarget.mLastFlingVelocity, /* delta= */ 0);
+ }
+
+ @Test
public void negativeFlingVelocityAboveMaximum_velocityClamped() {
mMinVelocity = 50;
mMaxVelocity = 100;
diff --git a/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java b/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java
index 25f5819fb671..263e563bc224 100644
--- a/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java
+++ b/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java
@@ -18,6 +18,8 @@ package android.window;
import static android.os.PerformanceHintManager.Session.CPU_LOAD_RESET;
import static android.os.PerformanceHintManager.Session.CPU_LOAD_UP;
+import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
+import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN;
import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF;
import static android.window.SystemPerformanceHinter.HINT_ADPF;
@@ -150,7 +152,10 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
- verify(mTransaction).apply();
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_HIGH));
+ verify(mTransaction).applyAsyncUnsafe();
}
@Test
@@ -164,7 +169,10 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
- verify(mTransaction).apply();
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_DEFAULT));
+ verify(mTransaction).applyAsyncUnsafe();
}
@Test
@@ -177,7 +185,7 @@ public class SystemPerformanceHinterTests {
// Verify we call SF
verify(mTransaction).setEarlyWakeupStart();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
}
@Test
@@ -189,7 +197,7 @@ public class SystemPerformanceHinterTests {
// Verify we call SF
verify(mTransaction).setEarlyWakeupEnd();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
}
@Test
@@ -231,8 +239,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_HIGH));
verify(mTransaction).setEarlyWakeupStart();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_UP));
}
@@ -248,8 +259,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_DEFAULT));
verify(mTransaction).setEarlyWakeupEnd();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
}
@@ -265,8 +279,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_DEFAULT));
verify(mTransaction).setEarlyWakeupEnd();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
}
}
@@ -280,8 +297,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_HIGH));
verify(mTransaction).setEarlyWakeupStart();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_UP));
reset(mTransaction);
reset(mAdpfSession);
@@ -290,15 +310,17 @@ public class SystemPerformanceHinterTests {
mHinter.startSession(HINT_ALL, DEFAULT_DISPLAY_ID, TEST_OTHER_REASON);
// Verify we never call SF and perf manager since session1 is already running
verify(mTransaction, never()).setFrameRateSelectionStrategy(any(), anyInt());
+ verify(mTransaction, never()).setFrameRateCategory(any(), anyInt());
verify(mTransaction, never()).setEarlyWakeupEnd();
- verify(mTransaction, never()).apply();
+ verify(mTransaction, never()).applyAsyncUnsafe();
verify(mAdpfSession, never()).sendHint(anyInt());
session2.close();
// Verify we have not cleaned up because session1 is still running
verify(mTransaction, never()).setFrameRateSelectionStrategy(any(), anyInt());
+ verify(mTransaction, never()).setFrameRateCategory(any(), anyInt());
verify(mTransaction, never()).setEarlyWakeupEnd();
- verify(mTransaction, never()).apply();
+ verify(mTransaction, never()).applyAsyncUnsafe();
verify(mAdpfSession, never()).sendHint(anyInt());
session1.close();
@@ -306,8 +328,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_DEFAULT));
verify(mTransaction).setEarlyWakeupEnd();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
}
@@ -321,8 +346,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_HIGH));
verify(mTransaction).setEarlyWakeupStart();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_UP));
reset(mTransaction);
reset(mAdpfSession);
@@ -333,8 +361,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mSecondaryDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mSecondaryDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_HIGH));
verify(mTransaction, never()).setEarlyWakeupStart();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession, never()).sendHint(anyInt());
reset(mTransaction);
reset(mAdpfSession);
@@ -345,11 +376,17 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mDefaultDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mDefaultDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_DEFAULT));
verify(mTransaction, never()).setFrameRateSelectionStrategy(
eq(mSecondaryDisplayRoot),
anyInt());
+ verify(mTransaction, never()).setFrameRateCategory(
+ eq(mSecondaryDisplayRoot),
+ anyInt());
verify(mTransaction, never()).setEarlyWakeupEnd();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession, never()).sendHint(anyInt());
reset(mTransaction);
reset(mAdpfSession);
@@ -362,8 +399,11 @@ public class SystemPerformanceHinterTests {
verify(mTransaction).setFrameRateSelectionStrategy(
eq(mSecondaryDisplayRoot),
eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+ verify(mTransaction).setFrameRateCategory(
+ eq(mSecondaryDisplayRoot),
+ eq(FRAME_RATE_CATEGORY_DEFAULT));
verify(mTransaction).setEarlyWakeupEnd();
- verify(mTransaction).apply();
+ verify(mTransaction).applyAsyncUnsafe();
verify(mAdpfSession).sendHint(eq(CPU_LOAD_RESET));
}
diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp
index 3d04937c9195..5f6eaf96a846 100644
--- a/core/tests/hdmitests/Android.bp
+++ b/core/tests/hdmitests/Android.bp
@@ -30,7 +30,7 @@ android_test {
"frameworks-base-testutils",
"guava-android-testlib",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp
index fde7c08715c7..2d778b1218d2 100644
--- a/core/tests/mockingcoretests/Android.bp
+++ b/core/tests/mockingcoretests/Android.bp
@@ -38,7 +38,7 @@ android_test {
"androidx.test.ext.junit",
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
"testables",
],
diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp
index c74600bbab22..f81be494ad18 100644
--- a/core/tests/nfctests/Android.bp
+++ b/core/tests/nfctests/Android.bp
@@ -27,7 +27,7 @@ android_test {
"androidx.test.ext.junit",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.runner",
diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp
index 063c5694ab5b..931eac515e31 100644
--- a/core/tests/overlaytests/device_self_targeting/Android.bp
+++ b/core/tests/overlaytests/device_self_targeting/Android.bp
@@ -30,7 +30,7 @@ android_test {
"androidx.test.runner",
"androidx.test.ext.junit",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
optimize: {
diff --git a/core/tests/packagemonitortests/Android.bp b/core/tests/packagemonitortests/Android.bp
index 7b5d7dff0a85..b08850e90d28 100644
--- a/core/tests/packagemonitortests/Android.bp
+++ b/core/tests/packagemonitortests/Android.bp
@@ -32,7 +32,7 @@ android_test {
"compatibility-device-util-axt",
"frameworks-base-testutils",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp
index bc3dd810be8c..4e24cd5d91cb 100644
--- a/core/tests/privacytests/Android.bp
+++ b/core/tests/privacytests/Android.bp
@@ -14,7 +14,7 @@ android_test {
"junit",
"rappor-tests",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp
index 3798da592cd5..580e73c331a1 100644
--- a/core/tests/utiltests/Android.bp
+++ b/core/tests/utiltests/Android.bp
@@ -33,7 +33,7 @@ android_test {
"frameworks-base-testutils",
"mockito-target-minus-junit4",
"androidx.test.ext.junit",
- "truth-prebuilt",
+ "truth",
"servicestests-utils",
],
diff --git a/core/tests/vibrator/Android.bp b/core/tests/vibrator/Android.bp
index 829409a36986..09608e9bf507 100644
--- a/core/tests/vibrator/Android.bp
+++ b/core/tests/vibrator/Android.bp
@@ -18,7 +18,7 @@ android_test {
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
"testng",
],
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index ad08026622d1..c1d2235e3324 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -41,7 +41,7 @@ java_test_host {
java_resource_dirs: ["tests/res"],
java_resources: [":error_prone_android_framework_testdata"],
static_libs: [
- "truth-prebuilt",
+ "truth",
"kxml2-2.3.0",
"compile-testing-prebuilt",
"error_prone_android_framework_lib",
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index e7814cbd67e7..d1aceafc4e2c 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -114,6 +114,7 @@ public class Canvas extends BaseCanvas {
throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
}
throwIfCannotDraw(bitmap);
+ bitmap.setGainmap(null);
mNativeCanvasWrapper = nInitRaster(bitmap.getNativeInstance());
mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
this, mNativeCanvasWrapper);
@@ -178,7 +179,7 @@ public class Canvas extends BaseCanvas {
throw new IllegalStateException();
}
throwIfCannotDraw(bitmap);
-
+ bitmap.setGainmap(null);
nSetBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance());
mDensity = bitmap.mDensity;
}
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 735bc180c015..52b0b95d3e76 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -236,7 +236,9 @@ public class FontListParser {
}
}
- return new FontConfig(families, filtered, resultNamedFamilies, lastModifiedDate,
+ return new FontConfig(families, filtered, resultNamedFamilies,
+ customization.getLocaleFamilyCustomizations(),
+ lastModifiedDate,
configVersion);
}
diff --git a/graphics/java/android/graphics/fonts/FontCustomizationParser.java b/graphics/java/android/graphics/fonts/FontCustomizationParser.java
index b458dd9021d0..6e04a2f5e405 100644
--- a/graphics/java/android/graphics/fonts/FontCustomizationParser.java
+++ b/graphics/java/android/graphics/fonts/FontCustomizationParser.java
@@ -22,6 +22,7 @@ import static android.text.FontConfig.NamedFamilyList;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.FontListParser;
+import android.text.FontConfig;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
@@ -34,6 +35,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
/**
@@ -52,14 +54,19 @@ public class FontCustomizationParser {
private final List<Alias> mAdditionalAliases;
+ private final List<FontConfig.Customization.LocaleFallback> mLocaleFamilyCustomizations;
+
public Result() {
mAdditionalNamedFamilies = Collections.emptyMap();
+ mLocaleFamilyCustomizations = Collections.emptyList();
mAdditionalAliases = Collections.emptyList();
}
public Result(Map<String, NamedFamilyList> additionalNamedFamilies,
+ List<FontConfig.Customization.LocaleFallback> localeFamilyCustomizations,
List<Alias> additionalAliases) {
mAdditionalNamedFamilies = additionalNamedFamilies;
+ mLocaleFamilyCustomizations = localeFamilyCustomizations;
mAdditionalAliases = additionalAliases;
}
@@ -70,6 +77,10 @@ public class FontCustomizationParser {
public List<Alias> getAdditionalAliases() {
return mAdditionalAliases;
}
+
+ public List<FontConfig.Customization.LocaleFallback> getLocaleFamilyCustomizations() {
+ return mLocaleFamilyCustomizations;
+ }
}
/**
@@ -89,7 +100,9 @@ public class FontCustomizationParser {
}
private static Result validateAndTransformToResult(
- List<NamedFamilyList> families, List<Alias> aliases) {
+ List<NamedFamilyList> families,
+ List<FontConfig.Customization.LocaleFallback> outLocaleFamilies,
+ List<Alias> aliases) {
HashMap<String, NamedFamilyList> namedFamily = new HashMap<>();
for (int i = 0; i < families.size(); ++i) {
final NamedFamilyList family = families.get(i);
@@ -105,7 +118,7 @@ public class FontCustomizationParser {
+ "requires fallackTarget attribute");
}
}
- return new Result(namedFamily, aliases);
+ return new Result(namedFamily, outLocaleFamilies, aliases);
}
private static Result readFamilies(
@@ -115,12 +128,13 @@ public class FontCustomizationParser {
) throws XmlPullParserException, IOException {
List<NamedFamilyList> families = new ArrayList<>();
List<Alias> aliases = new ArrayList<>();
+ List<FontConfig.Customization.LocaleFallback> outLocaleFamilies = new ArrayList<>();
parser.require(XmlPullParser.START_TAG, null, "fonts-modification");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
String tag = parser.getName();
if (tag.equals("family")) {
- readFamily(parser, fontDir, families, updatableFontMap);
+ readFamily(parser, fontDir, families, outLocaleFamilies, updatableFontMap);
} else if (tag.equals("family-list")) {
readFamilyList(parser, fontDir, families, updatableFontMap);
} else if (tag.equals("alias")) {
@@ -129,13 +143,14 @@ public class FontCustomizationParser {
FontListParser.skip(parser);
}
}
- return validateAndTransformToResult(families, aliases);
+ return validateAndTransformToResult(families, outLocaleFamilies, aliases);
}
private static void readFamily(
@NonNull XmlPullParser parser,
@NonNull String fontDir,
@NonNull List<NamedFamilyList> out,
+ @NonNull List<FontConfig.Customization.LocaleFallback> outCustomization,
@Nullable Map<String, File> updatableFontMap)
throws XmlPullParserException, IOException {
final String customizationType = parser.getAttributeValue(null, "customizationType");
@@ -148,6 +163,29 @@ public class FontCustomizationParser {
if (fontFamily != null) {
out.add(fontFamily);
}
+ } else if (customizationType.equals("new-locale-family")) {
+ final String lang = parser.getAttributeValue(null, "lang");
+ final String op = parser.getAttributeValue(null, "operation");
+ final int intOp;
+ if (op.equals("append")) {
+ intOp = FontConfig.Customization.LocaleFallback.OPERATION_APPEND;
+ } else if (op.equals("prepend")) {
+ intOp = FontConfig.Customization.LocaleFallback.OPERATION_PREPEND;
+ } else if (op.equals("replace")) {
+ intOp = FontConfig.Customization.LocaleFallback.OPERATION_REPLACE;
+ } else {
+ throw new IllegalArgumentException("Unknown operation=" + op);
+ }
+
+ final FontConfig.FontFamily family = FontListParser.readFamily(
+ parser, fontDir, updatableFontMap, false);
+
+ // For ignoring the customization, consume the new-locale-family element but don't
+ // register any customizations.
+ if (com.android.text.flags.Flags.customLocaleFallback()) {
+ outCustomization.add(new FontConfig.Customization.LocaleFallback(
+ Locale.forLanguageTag(lang), intOp, family));
+ }
} else {
throw new IllegalArgumentException("Unknown customizationType=" + customizationType);
}
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index d4e35b30c8d0..618aa5b5019c 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -16,10 +16,15 @@
package android.graphics.fonts;
+import static android.text.FontConfig.Customization.LocaleFallback.OPERATION_APPEND;
+import static android.text.FontConfig.Customization.LocaleFallback.OPERATION_PREPEND;
+import static android.text.FontConfig.Customization.LocaleFallback.OPERATION_REPLACE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.FontListParser;
import android.graphics.Typeface;
+import android.os.LocaleList;
import android.text.FontConfig;
import android.util.ArrayMap;
import android.util.Log;
@@ -38,6 +43,7 @@ import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -119,7 +125,6 @@ public final class SystemFonts {
}
}
-
final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily(
defaultFonts, languageTags, variant, xmlFamily.getVariableFontFamilyType(), false,
cache);
@@ -300,11 +305,11 @@ public final class SystemFonts {
} catch (IOException e) {
Log.e(TAG, "Failed to open/read system font configurations.", e);
return new FontConfig(Collections.emptyList(), Collections.emptyList(),
- Collections.emptyList(), 0, 0);
+ Collections.emptyList(), Collections.emptyList(), 0, 0);
} catch (XmlPullParserException e) {
Log.e(TAG, "Failed to parse the system font configuration.", e);
return new FontConfig(Collections.emptyList(), Collections.emptyList(),
- Collections.emptyList(), 0, 0);
+ Collections.emptyList(), Collections.emptyList(), 0, 0);
}
}
@@ -328,6 +333,8 @@ public final class SystemFonts {
ArrayMap<String, ByteBuffer> outBufferCache) {
final ArrayMap<String, NativeFamilyListSet> fallbackListMap = new ArrayMap<>();
+ final List<FontConfig.Customization.LocaleFallback> localeFallbacks =
+ fontConfig.getLocaleFallbackCustomizations();
final List<FontConfig.NamedFamilyList> namedFamilies = fontConfig.getNamedFamilyLists();
for (int i = 0; i < namedFamilies.size(); ++i) {
@@ -336,10 +343,54 @@ public final class SystemFonts {
}
// Then, add fallback fonts to the fallback map.
+ final List<FontConfig.Customization.LocaleFallback> customizations = new ArrayList<>();
final List<FontConfig.FontFamily> xmlFamilies = fontConfig.getFontFamilies();
+ final SparseIntArray seenCustomization = new SparseIntArray();
for (int i = 0; i < xmlFamilies.size(); i++) {
final FontConfig.FontFamily xmlFamily = xmlFamilies.get(i);
- pushFamilyToFallback(xmlFamily, fallbackListMap, outBufferCache);
+
+ customizations.clear();
+ for (int j = 0; j < localeFallbacks.size(); ++j) {
+ if (seenCustomization.get(j, -1) != -1) {
+ continue; // The customization is already applied.
+ }
+ FontConfig.Customization.LocaleFallback localeFallback = localeFallbacks.get(j);
+ if (scriptMatch(xmlFamily.getLocaleList(), localeFallback.getScript())) {
+ customizations.add(localeFallback);
+ seenCustomization.put(j, 1);
+ }
+ }
+
+ if (customizations.isEmpty()) {
+ pushFamilyToFallback(xmlFamily, fallbackListMap, outBufferCache);
+ } else {
+ for (int j = 0; j < customizations.size(); ++j) {
+ FontConfig.Customization.LocaleFallback localeFallback = customizations.get(j);
+ if (localeFallback.getOperation() == OPERATION_PREPEND) {
+ pushFamilyToFallback(localeFallback.getFamily(), fallbackListMap,
+ outBufferCache);
+ }
+ }
+ boolean isReplaced = false;
+ for (int j = 0; j < customizations.size(); ++j) {
+ FontConfig.Customization.LocaleFallback localeFallback = customizations.get(j);
+ if (localeFallback.getOperation() == OPERATION_REPLACE) {
+ pushFamilyToFallback(localeFallback.getFamily(), fallbackListMap,
+ outBufferCache);
+ isReplaced = true;
+ }
+ }
+ if (!isReplaced) { // If nothing is replaced, push the original one.
+ pushFamilyToFallback(xmlFamily, fallbackListMap, outBufferCache);
+ }
+ for (int j = 0; j < customizations.size(); ++j) {
+ FontConfig.Customization.LocaleFallback localeFallback = customizations.get(j);
+ if (localeFallback.getOperation() == OPERATION_APPEND) {
+ pushFamilyToFallback(localeFallback.getFamily(), fallbackListMap,
+ outBufferCache);
+ }
+ }
+ }
}
// Build the font map and fallback map.
@@ -365,4 +416,42 @@ public final class SystemFonts {
Typeface.initSystemDefaultTypefaces(fallbackMap, fontConfig.getAliases(), result);
return result;
}
+
+ private static boolean scriptMatch(LocaleList localeList, String targetScript) {
+ if (localeList == null || localeList.isEmpty()) {
+ return false;
+ }
+ for (int i = 0; i < localeList.size(); ++i) {
+ Locale locale = localeList.get(i);
+ if (locale == null) {
+ continue;
+ }
+ String baseScript = FontConfig.resolveScript(locale);
+ if (baseScript.equals(targetScript)) {
+ return true;
+ }
+
+ // Subtag match
+ if (targetScript.equals("Bopo") && baseScript.equals("Hanb")) {
+ // Hanb is Han with Bopomofo.
+ return true;
+ } else if (targetScript.equals("Hani")) {
+ if (baseScript.equals("Hanb") || baseScript.equals("Hans")
+ || baseScript.equals("Hant") || baseScript.equals("Kore")
+ || baseScript.equals("Jpan")) {
+ // Han id suppoted by Taiwanese, Traditional Chinese, Simplified Chinese, Korean
+ // and Japanese.
+ return true;
+ }
+ } else if (targetScript.equals("Hira") || targetScript.equals("Hrkt")
+ || targetScript.equals("Kana")) {
+ if (baseScript.equals("Jpan") || baseScript.equals("Hrkt")) {
+ // Hiragana, Hiragana-Katakana, Katakana is supported by Japanese and
+ // Hiragana-Katakana script.
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/graphics/java/android/graphics/text/LineBreakConfig.java b/graphics/java/android/graphics/text/LineBreakConfig.java
index e81525fb7d60..f5e5803d4796 100644
--- a/graphics/java/android/graphics/text/LineBreakConfig.java
+++ b/graphics/java/android/graphics/text/LineBreakConfig.java
@@ -134,10 +134,25 @@ public final class LineBreakConfig {
*/
public static final int LINE_BREAK_STYLE_STRICT = 3;
+ /**
+ * The line break style that used for preventing automatic line breaking.
+ *
+ * This is useful when you want to preserve some words in the same line by using
+ * {@link android.text.style.LineBreakConfigSpan} or
+ * {@link android.text.style.LineBreakConfigSpan.NoBreakSpan} as a shorthand.
+ * Note that even if this style is specified, the grapheme based line break is still performed
+ * for preventing clipping text.
+ *
+ * @see android.text.style.LineBreakConfigSpan
+ * @see android.text.style.LineBreakConfigSpan.NoBreakSpan
+ */
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ public static final int LINE_BREAK_STYLE_NO_BREAK = 4;
+
/** @hide */
@IntDef(prefix = { "LINE_BREAK_STYLE_" }, value = {
LINE_BREAK_STYLE_NONE, LINE_BREAK_STYLE_LOOSE, LINE_BREAK_STYLE_NORMAL,
- LINE_BREAK_STYLE_STRICT, LINE_BREAK_STYLE_UNSPECIFIED
+ LINE_BREAK_STYLE_STRICT, LINE_BREAK_STYLE_UNSPECIFIED, LINE_BREAK_STYLE_NO_BREAK
})
@Retention(RetentionPolicy.SOURCE)
public @interface LineBreakStyle {}
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 0f3488bbe8d1..31c2eb2efaed 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -28,8 +28,8 @@ import android.system.keystore2.ResponseCode;
import android.util.Log;
/**
- * @hide This is the client side for IKeystoreUserManager AIDL.
- * It shall only be used by the LockSettingsService.
+ * @hide This is the client side for IKeystoreMaintenance AIDL.
+ * It is used mainly by LockSettingsService.
*/
public class AndroidKeyStoreMaintenance {
private static final String TAG = "AndroidKeyStoreMaintenance";
@@ -66,7 +66,7 @@ public class AndroidKeyStoreMaintenance {
}
/**
- * Informs Keystore 2.0 about removing a usergit mer
+ * Informs Keystore 2.0 about removing a user
*
* @param userId - Android user id of the user being removed
* @return 0 if successful or a {@code ResponseCode}
@@ -91,7 +91,7 @@ public class AndroidKeyStoreMaintenance {
*
* @param userId - Android user id of the user
* @param password - a secret derived from the synthetic password provided by the
- * LockSettingService
+ * LockSettingsService
* @return 0 if successful or a {@code ResponseCode}
* @hide
*/
@@ -110,7 +110,7 @@ public class AndroidKeyStoreMaintenance {
}
/**
- * Informs Keystore 2.0 that an app was uninstalled and the corresponding namspace is to
+ * Informs Keystore 2.0 that an app was uninstalled and the corresponding namespace is to
* be cleared.
*/
public static int clearNamespace(@Domain int domain, long namespace) {
@@ -172,10 +172,10 @@ public class AndroidKeyStoreMaintenance {
* namespace.
*
* @return * 0 on success
- * * KEY_NOT_FOUND if the source did not exists.
+ * * KEY_NOT_FOUND if the source did not exist.
* * PERMISSION_DENIED if any of the required permissions was missing.
* * INVALID_ARGUMENT if the destination was occupied or any domain value other than
- * the allowed once were specified.
+ * the allowed ones was specified.
* * SYSTEM_ERROR if an unexpected error occurred.
*/
public static int migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination) {
diff --git a/libs/WindowManager/Jetpack/tests/unittest/Android.bp b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
index b6e743a2b7e1..ed2ff2de245b 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/Android.bp
+++ b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
@@ -37,7 +37,7 @@ android_test {
"androidx.test.rules",
"androidx.test.ext.junit",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
"testables",
"platform-test-annotations",
],
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 7a309f5758a0..1f6f7aeadd45 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -143,7 +143,9 @@
<dimen name="bubble_expanded_view_padding">16dp</dimen>
<!-- Padding for the edge of the expanded view that is closest to the edge of the screen used
when displaying in landscape on a large screen. -->
- <dimen name="bubble_expanded_view_largescreen_landscape_padding">128dp</dimen>
+ <dimen name="bubble_expanded_view_largescreen_landscape_padding">102dp</dimen>
+ <!-- The width of the expanded view on large screens. -->
+ <dimen name="bubble_expanded_view_largescreen_width">540dp</dimen>
<!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
a slight touch slop around the expanded view. -->
<dimen name="bubble_expanded_view_slop">8dp</dimen>
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 ea7053d8ee49..17e06e93b3a8 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
@@ -54,10 +54,6 @@ public class BubblePositioner {
public static final float FLYOUT_MAX_WIDTH_PERCENT_LARGE_SCREEN = 0.3f;
/** The max percent of screen width to use for the flyout on phone. */
public static final float FLYOUT_MAX_WIDTH_PERCENT = 0.6f;
- /** The percent of screen width for the expanded view on a large screen. **/
- private static final float EXPANDED_VIEW_LARGE_SCREEN_LANDSCAPE_WIDTH_PERCENT = 0.48f;
- /** The percent of screen width for the expanded view on a large screen. **/
- private static final float EXPANDED_VIEW_LARGE_SCREEN_PORTRAIT_WIDTH_PERCENT = 0.70f;
/** The percent of screen width for the expanded view on a small tablet. **/
private static final float EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT = 0.72f;
/** The percent of screen width for the expanded view when shown in the bubble bar. **/
@@ -95,6 +91,7 @@ public class BubblePositioner {
private int mPointerWidth;
private int mPointerHeight;
private int mPointerOverlap;
+ private int mManageButtonHeightIncludingMargins;
private int mManageButtonHeight;
private int mOverflowHeight;
private int mMinimumFlyoutWidthLargeScreen;
@@ -176,21 +173,20 @@ public class BubblePositioner {
mExpandedViewLargeScreenWidth = (int) (bounds.width()
* EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT);
} else {
- mExpandedViewLargeScreenWidth = isLandscape()
- ? (int) (bounds.width() * EXPANDED_VIEW_LARGE_SCREEN_LANDSCAPE_WIDTH_PERCENT)
- : (int) (bounds.width() * EXPANDED_VIEW_LARGE_SCREEN_PORTRAIT_WIDTH_PERCENT);
+ mExpandedViewLargeScreenWidth =
+ res.getDimensionPixelSize(R.dimen.bubble_expanded_view_largescreen_width);
}
if (mIsLargeScreen) {
- if (isLandscape() && !mIsSmallTablet) {
+ if (mIsSmallTablet) {
+ final int centeredInset = (bounds.width() - mExpandedViewLargeScreenWidth) / 2;
+ mExpandedViewLargeScreenInsetClosestEdge = centeredInset;
+ mExpandedViewLargeScreenInsetFurthestEdge = centeredInset;
+ } else {
mExpandedViewLargeScreenInsetClosestEdge = res.getDimensionPixelSize(
R.dimen.bubble_expanded_view_largescreen_landscape_padding);
mExpandedViewLargeScreenInsetFurthestEdge = bounds.width()
- mExpandedViewLargeScreenInsetClosestEdge
- mExpandedViewLargeScreenWidth;
- } else {
- final int centeredInset = (bounds.width() - mExpandedViewLargeScreenWidth) / 2;
- mExpandedViewLargeScreenInsetClosestEdge = centeredInset;
- mExpandedViewLargeScreenInsetFurthestEdge = centeredInset;
}
} else {
mExpandedViewLargeScreenInsetClosestEdge = mExpandedViewPadding;
@@ -202,7 +198,9 @@ public class BubblePositioner {
mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
mPointerOverlap = res.getDimensionPixelSize(R.dimen.bubble_pointer_overlap);
- mManageButtonHeight = res.getDimensionPixelSize(R.dimen.bubble_manage_button_total_height);
+ mManageButtonHeightIncludingMargins =
+ res.getDimensionPixelSize(R.dimen.bubble_manage_button_total_height);
+ mManageButtonHeight = res.getDimensionPixelSize(R.dimen.bubble_manage_button_height);
mExpandedViewMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height);
mOverflowHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height);
mMinimumFlyoutWidthLargeScreen = res.getDimensionPixelSize(
@@ -420,7 +418,7 @@ public class BubblePositioner {
int pointerSize = showBubblesVertically()
? mPointerWidth
: (mPointerHeight + mPointerMargin);
- int bottomPadding = isOverflow ? mExpandedViewPadding : mManageButtonHeight;
+ int bottomPadding = isOverflow ? mExpandedViewPadding : mManageButtonHeightIncludingMargins;
return getAvailableRect().height()
- expandedContainerY
- paddingTop
@@ -438,6 +436,15 @@ public class BubblePositioner {
// overflow in landscape on phone is max
return MAX_HEIGHT;
}
+
+ if (mIsLargeScreen && !mIsSmallTablet && !isOverflow) {
+ // the expanded view height on large tablets is calculated based on the shortest screen
+ // size and is the same in both portrait and landscape
+ int maxVerticalInset = Math.max(mInsets.top, mInsets.bottom);
+ int shortestScreenSide = Math.min(mScreenRect.height(), mScreenRect.width());
+ return shortestScreenSide - 2 * maxVerticalInset - mManageButtonHeight;
+ }
+
float desiredHeight = isOverflow
? mOverflowHeight
: ((Bubble) bubble).getDesiredHeight(mContext);
@@ -466,7 +473,8 @@ public class BubblePositioner {
return topAlignment;
}
// If we're here, we're showing vertically & developer has made height less than maximum.
- int manageButtonHeight = isOverflow ? mExpandedViewPadding : mManageButtonHeight;
+ int manageButtonHeight =
+ isOverflow ? mExpandedViewPadding : mManageButtonHeightIncludingMargins;
float pointerPosition = getPointerPosition(bubblePosition);
float bottomIfCentered = pointerPosition + (expandedViewHeight / 2) + manageButtonHeight;
float topIfCentered = pointerPosition - (expandedViewHeight / 2);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java
index 931cf0cee28c..c6c9b3562308 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TvWindowMenuActionButton.java
@@ -94,6 +94,10 @@ public class TvWindowMenuActionButton extends RelativeLayout {
mCurrentIcon = icon;
// Remove old image while waiting for the new one to load.
mIconImageView.setImageDrawable(null);
+ if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {
+ // Disallow loading icon from content URI
+ return;
+ }
icon.loadDrawableAsync(mContext, d -> {
// The image hasn't been set any other way and the drawable belongs to the most
// recently set Icon.
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 11aa054676cb..5dfba5e7ff1d 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
@@ -494,13 +494,14 @@ public abstract class WMShellModule {
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
@DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
LaunchAdjacentController launchAdjacentController,
+ RecentsTransitionHandler recentsTransitionHandler,
@ShellMainThread ShellExecutor mainExecutor
) {
return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
transitions, enterDesktopTransitionHandler, exitDesktopTransitionHandler,
toggleResizeDesktopTaskTransitionHandler, desktopModeTaskRepository,
- launchAdjacentController, mainExecutor);
+ launchAdjacentController, recentsTransitionHandler, mainExecutor);
}
@WMSingleton
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 09ba4f79326e..412a5b5a6997 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
@@ -60,6 +60,8 @@ import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.TO_DESKTOP_INDICATOR
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.splitscreen.SplitScreenController
import com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ENTER_DESKTOP
import com.android.wm.shell.sysui.ShellCommandHandler
@@ -68,7 +70,6 @@ import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.sysui.ShellSharedConstants
import com.android.wm.shell.transition.OneShotRemoteHandler
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TransitionHandler
import com.android.wm.shell.util.KtProtoLog
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
@@ -93,6 +94,7 @@ class DesktopTasksController(
ToggleResizeDesktopTaskTransitionHandler,
private val desktopModeTaskRepository: DesktopModeTaskRepository,
private val launchAdjacentController: LaunchAdjacentController,
+ private val recentsTransitionHandler: RecentsTransitionHandler,
@ShellMainThread private val mainExecutor: ShellExecutor
) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler {
@@ -119,6 +121,8 @@ class DesktopTasksController(
com.android.wm.shell.R.dimen.desktop_mode_transition_area_width
)
+ private var recentsAnimationRunning = false
+
// This is public to avoid cyclic dependency; it is set by SplitScreenController
lateinit var splitScreenController: SplitScreenController
@@ -139,6 +143,19 @@ class DesktopTasksController(
)
transitions.addHandler(this)
desktopModeTaskRepository.addVisibleTasksListener(taskVisibilityListener, mainExecutor)
+
+ recentsTransitionHandler.addTransitionStateListener(
+ object : RecentsTransitionStateListener {
+ override fun onAnimationStateChanged(running: Boolean) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: recents animation state changed running=%b",
+ running
+ )
+ recentsAnimationRunning = running
+ }
+ }
+ )
}
/** Show all tasks, that are part of the desktop, on top of launcher */
@@ -644,6 +661,10 @@ class DesktopTasksController(
val triggerTask = request.triggerTask
val shouldHandleRequest =
when {
+ recentsAnimationRunning -> {
+ reason = "recents animation is running"
+ false
+ }
// Only handle open or to front transitions
request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> {
reason = "transition type not handled (${request.type})"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index ead2f9cbd1ad..d31476c63890 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -54,6 +54,7 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -279,7 +280,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mDeathHandler = () -> {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.DeathRecipient: binder died", mInstanceId);
- finish(mWillFinishToHome, false /* leaveHint */);
+ finish(mWillFinishToHome, false /* leaveHint */, null /* finishCb */);
};
try {
mListener.asBinder().linkToDeath(mDeathHandler, 0 /* flags */);
@@ -313,7 +314,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
}
if (mFinishCB != null) {
- finishInner(toHome, false /* userLeave */);
+ finishInner(toHome, false /* userLeave */, null /* finishCb */);
} else {
cleanUp();
}
@@ -670,7 +671,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// now and let it do its animation (since recents is going to be occluded).
sendCancelWithSnapshots();
mExecutor.executeDelayed(
- () -> finishInner(true /* toHome */, false /* userLeaveHint */), 0);
+ () -> finishInner(true /* toHome */, false /* userLeaveHint */,
+ null /* finishCb */), 0);
return;
}
if (recentsOpening != null) {
@@ -899,11 +901,12 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
@Override
@SuppressLint("NewApi")
- public void finish(boolean toHome, boolean sendUserLeaveHint) {
- mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint));
+ public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) {
+ mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint, finishCb));
}
- private void finishInner(boolean toHome, boolean sendUserLeaveHint) {
+ private void finishInner(boolean toHome, boolean sendUserLeaveHint,
+ IResultReceiver runnerFinishCb) {
if (mFinishCB == null) {
Slog.e(TAG, "Duplicate call to finish");
return;
@@ -993,6 +996,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
cleanUp();
finishCB.onTransitionFinished(wct.isEmpty() ? null : wct);
+ if (runnerFinishCb != null) {
+ try {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ "[%d] RecentsController.finishInner: calling finish callback",
+ mInstanceId);
+ runnerFinishCb.send(0, null);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to report transition finished", e);
+ }
+ }
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 5e2c61b9d3cd..b2948667f9e6 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
@@ -143,6 +143,8 @@ import com.android.wm.shell.util.SplitBounds;
import com.android.wm.shell.util.TransitionUtil;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
@@ -3109,6 +3111,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null /* taskInfo */, false /* allowEnterPip */, TYPE_DOCK_DIVIDER);
}
+ @NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 83dc7fa5e869..e828eedc275c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -23,6 +23,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
+
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
@@ -693,9 +694,19 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
+ Transitions.TransitionFinishCallback finishCB = wct -> {
+ mixed.mInFlightSubAnimations--;
+ if (mixed.mInFlightSubAnimations == 0) {
+ mActiveTransitions.remove(mixed);
+ finishCallback.onTransitionFinished(wct);
+ }
+ };
+
+ mixed.mInFlightSubAnimations++;
boolean consumed = mRecentsHandler.startAnimation(
- mixed.mTransition, info, startTransaction, finishTransaction, finishCallback);
+ mixed.mTransition, info, startTransaction, finishTransaction, finishCB);
if (!consumed) {
+ mixed.mInFlightSubAnimations--;
return false;
}
if (mDesktopTasksController != null) {
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 6062e34cd601..335a5886ba28 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
@@ -44,6 +44,7 @@ import android.window.WindowContainerTransaction;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.desktopmode.DesktopModeStatus;
import java.util.function.Supplier;
@@ -283,10 +284,6 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
// Task surface itself
float shadowRadius = loadDimension(resources, params.mShadowRadiusId);
- int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
- mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
- mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
- mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
final Point taskPosition = mTaskInfo.positionInParent;
if (isFullscreen) {
// Setting the task crop to the width/height stops input events from being sent to
@@ -302,13 +299,22 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
finishT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
}
startT.setShadowRadius(mTaskSurface, shadowRadius)
- .setColor(mTaskSurface, mTmpColor)
.show(mTaskSurface);
finishT.setPosition(mTaskSurface, taskPosition.x, taskPosition.y)
.setShadowRadius(mTaskSurface, shadowRadius);
if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ if (!DesktopModeStatus.isVeiledResizeEnabled()) {
+ // When fluid resize is enabled, add a background to freeform tasks
+ int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
+ mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
+ mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
+ mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
+ startT.setColor(mTaskSurface, mTmpColor);
+ }
startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+ } else if (!DesktopModeStatus.isVeiledResizeEnabled()) {
+ startT.unsetColor(mTaskSurface);
}
if (mCaptionWindowManager == null) {
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 54f94986d90c..d09a90cd7dc7 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -45,7 +45,7 @@ android_test {
"kotlinx-coroutines-core",
"mockito-kotlin2",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
"testables",
"platform-test-annotations",
"servicestests-utils",
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java
index 58d9a6486ff2..287a97c9b5b0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java
@@ -22,20 +22,24 @@ import static android.view.View.LAYOUT_DIRECTION_LTR;
import static android.view.View.LAYOUT_DIRECTION_RTL;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
+import android.util.DisplayMetrics;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
@@ -257,6 +261,27 @@ public class BubblePositionerTest extends ShellTestCase {
assertThat(mPositioner.hasUserModifiedDefaultPosition()).isTrue();
}
+ @Test
+ public void testExpandedViewHeight_onLargeTablet() {
+ Insets insets = Insets.of(10, 20, 5, 15);
+ Rect screenBounds = new Rect(0, 0, 1800, 2600);
+
+ new WindowManagerConfig()
+ .setLargeScreen()
+ .setInsets(insets)
+ .setScreenBounds(screenBounds)
+ .setUpConfig();
+ mPositioner.update();
+
+ Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
+ Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
+
+ int manageButtonHeight =
+ mContext.getResources().getDimensionPixelSize(R.dimen.bubble_manage_button_height);
+ float expectedHeight = 1800 - 2 * 20 - manageButtonHeight;
+ assertThat(mPositioner.getExpandedViewHeight(bubble)).isWithin(0.1f).of(expectedHeight);
+ }
+
/**
* Calculates the Y position bubbles should be placed based on the config. Based on
* the calculations in {@link BubblePositioner#getDefaultStartPosition()} and
@@ -323,6 +348,8 @@ public class BubblePositionerTest extends ShellTestCase {
? MIN_WIDTH_FOR_TABLET
: MIN_WIDTH_FOR_TABLET - 1;
mConfiguration.orientation = mOrientation;
+ mConfiguration.screenWidthDp = pxToDp(mScreenBounds.width());
+ mConfiguration.screenHeightDp = pxToDp(mScreenBounds.height());
when(mConfiguration.getLayoutDirection()).thenReturn(mLayoutDirection);
WindowInsets windowInsets = mock(WindowInsets.class);
@@ -331,5 +358,11 @@ public class BubblePositionerTest extends ShellTestCase {
when(mWindowMetrics.getBounds()).thenReturn(mScreenBounds);
when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics);
}
+
+ private int pxToDp(float px) {
+ int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
+ float dp = px / ((float) dpi / DisplayMetrics.DENSITY_DEFAULT);
+ return (int) dp;
+ }
}
}
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 dea161786da2..ebcb6407a6fd 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
@@ -54,6 +54,8 @@ import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreef
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSplitScreenTask
+import com.android.wm.shell.recents.RecentsTransitionHandler
+import com.android.wm.shell.recents.RecentsTransitionStateListener
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellController
@@ -101,11 +103,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Mock lateinit var launchAdjacentController: LaunchAdjacentController
@Mock lateinit var desktopModeWindowDecoration: DesktopModeWindowDecoration
@Mock lateinit var splitScreenController: SplitScreenController
+ @Mock lateinit var recentsTransitionHandler: RecentsTransitionHandler
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var controller: DesktopTasksController
private lateinit var shellInit: ShellInit
private lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
+ private lateinit var recentsTransitionStateListener: RecentsTransitionStateListener
private val shellExecutor = TestShellExecutor()
// Mock running tasks are registered here so we can get the list from mock shell task organizer
@@ -126,6 +130,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.splitScreenController = splitScreenController
shellInit.init()
+
+ val captor = ArgumentCaptor.forClass(RecentsTransitionStateListener::class.java)
+ verify(recentsTransitionHandler).addTransitionStateListener(captor.capture())
+ recentsTransitionStateListener = captor.value
}
private fun createController(): DesktopTasksController {
@@ -144,6 +152,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
mToggleResizeDesktopTaskTransitionHandler,
desktopModeTaskRepository,
launchAdjacentController,
+ recentsTransitionHandler,
shellExecutor
)
}
@@ -355,7 +364,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Test
fun moveToDesktop_splitTaskExitsSplit() {
- var task = setUpSplitScreenTask()
+ val task = setUpSplitScreenTask()
controller.moveToDesktop(desktopModeWindowDecoration, task)
val wct = getLatestMoveToDesktopWct()
assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
@@ -367,7 +376,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Test
fun moveToDesktop_fullscreenTaskDoesNotExitSplit() {
- var task = setUpFullscreenTask()
+ val task = setUpFullscreenTask()
controller.moveToDesktop(desktopModeWindowDecoration, task)
val wct = getLatestMoveToDesktopWct()
assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
@@ -666,6 +675,20 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun handleRequest_recentsAnimationRunning_returnNull() {
+ // Set up a visible freeform task so a fullscreen task should be converted to freeform
+ val freeformTask = setUpFreeformTask()
+ markTaskVisible(freeformTask)
+
+ // Mark recents animation running
+ recentsTransitionStateListener.onAnimationStateChanged(true)
+
+ // Open a fullscreen task, check that it does not result in a WCT with changes to it
+ val fullscreenTask = createFullscreenTask()
+ assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull()
+ }
+
+ @Test
fun stashDesktopApps_stateUpdates() {
whenever(DesktopModeStatus.isStashingEnabled()).thenReturn(true)
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 966a99eea925..fcb7863429d6 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
@@ -17,7 +17,9 @@
package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlBuilder;
import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
@@ -36,6 +38,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.quality.Strictness.LENIENT;
import android.app.ActivityManager;
import android.content.Context;
@@ -59,10 +62,12 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.tests.R;
import org.junit.Before;
@@ -201,12 +206,8 @@ public class WindowDecorationTests extends ShellTestCase {
createMockSurfaceControlBuilder(captionContainerSurface);
mMockSurfaceControlBuilders.add(captionContainerSurfaceBuilder);
- final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
- new ActivityManager.TaskDescription.Builder()
- .setBackgroundColor(Color.YELLOW);
final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
.setDisplayId(Display.DEFAULT_DISPLAY)
- .setTaskDescriptionBuilder(taskDescriptionBuilder)
.setBounds(TASK_BOUNDS)
.setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
.setVisible(true)
@@ -255,8 +256,6 @@ public class WindowDecorationTests extends ShellTestCase {
verify(mMockSurfaceControlFinishT).setCornerRadius(taskSurface, CORNER_RADIUS);
verify(mMockSurfaceControlStartT)
.show(taskSurface);
- verify(mMockSurfaceControlStartT)
- .setColor(taskSurface, new float[] {1.f, 1.f, 0.f});
verify(mMockSurfaceControlStartT).setShadowRadius(taskSurface, 10);
assertEquals(300, mRelayoutResult.mWidth);
@@ -502,6 +501,86 @@ public class WindowDecorationTests extends ShellTestCase {
verify(mMockRootSurfaceControl).applyTransactionOnDraw(mMockSurfaceControlStartT);
}
+ @Test
+ public void testRelayout_fluidResizeEnabled_freeformTask_setTaskSurfaceColor() {
+ StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
+ DesktopModeStatus.class).strictness(
+ LENIENT).startMocking();
+ when(DesktopModeStatus.isVeiledResizeEnabled()).thenReturn(false);
+
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+
+ final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder decorContainerSurfaceBuilder =
+ createMockSurfaceControlBuilder(decorContainerSurface);
+ mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
+ final SurfaceControl captionContainerSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder captionContainerSurfaceBuilder =
+ createMockSurfaceControlBuilder(captionContainerSurface);
+ mMockSurfaceControlBuilders.add(captionContainerSurfaceBuilder);
+
+ final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
+ new ActivityManager.TaskDescription.Builder()
+ .setBackgroundColor(Color.YELLOW);
+
+ final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .setTaskDescriptionBuilder(taskDescriptionBuilder)
+ .setVisible(true)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .build();
+ taskInfo.isFocused = true;
+ final SurfaceControl taskSurface = mock(SurfaceControl.class);
+ final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
+
+ windowDecor.relayout(taskInfo);
+
+ verify(mMockSurfaceControlStartT).setColor(taskSurface, new float[] {1.f, 1.f, 0.f});
+
+ mockitoSession.finishMocking();
+ }
+
+ @Test
+ public void testRelayout_fluidResizeEnabled_fullscreenTask_clearTaskSurfaceColor() {
+ StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
+ DesktopModeStatus.class).strictness(LENIENT).startMocking();
+ when(DesktopModeStatus.isVeiledResizeEnabled()).thenReturn(false);
+
+ final Display defaultDisplay = mock(Display.class);
+ doReturn(defaultDisplay).when(mMockDisplayController)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+
+ final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder decorContainerSurfaceBuilder =
+ createMockSurfaceControlBuilder(decorContainerSurface);
+ mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
+ final SurfaceControl captionContainerSurface = mock(SurfaceControl.class);
+ final SurfaceControl.Builder captionContainerSurfaceBuilder =
+ createMockSurfaceControlBuilder(captionContainerSurface);
+ mMockSurfaceControlBuilders.add(captionContainerSurfaceBuilder);
+
+ final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
+ new ActivityManager.TaskDescription.Builder()
+ .setBackgroundColor(Color.YELLOW);
+ final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+ .setDisplayId(Display.DEFAULT_DISPLAY)
+ .setTaskDescriptionBuilder(taskDescriptionBuilder)
+ .setVisible(true)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .build();
+ taskInfo.isFocused = true;
+ final SurfaceControl taskSurface = mock(SurfaceControl.class);
+ final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
+
+ windowDecor.relayout(taskInfo);
+
+ verify(mMockSurfaceControlStartT).unsetColor(taskSurface);
+
+ mockitoSession.finishMocking();
+ }
+
private TestWindowDecoration createWindowDecoration(
ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
diff --git a/libs/dream/lowlight/tests/Android.bp b/libs/dream/lowlight/tests/Android.bp
index 64b53cbb5c5a..4dafd0aa6df4 100644
--- a/libs/dream/lowlight/tests/Android.bp
+++ b/libs/dream/lowlight/tests/Android.bp
@@ -34,7 +34,7 @@ android_test {
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
"testables",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/libs/securebox/tests/Android.bp b/libs/securebox/tests/Android.bp
index 7df546ae0ff6..80b501da1aa5 100644
--- a/libs/securebox/tests/Android.bp
+++ b/libs/securebox/tests/Android.bp
@@ -32,7 +32,7 @@ android_test {
"platform-test-annotations",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/media/java/android/media/RingtoneSelection.java b/media/java/android/media/RingtoneSelection.java
index 74f72767c3f8..b74b6a3dbac9 100644
--- a/media/java/android/media/RingtoneSelection.java
+++ b/media/java/android/media/RingtoneSelection.java
@@ -18,16 +18,23 @@ package android.media;
import static java.util.Objects.requireNonNull;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.net.Uri;
+import android.os.UserHandle;
+import android.os.vibrator.Flags;
import android.provider.MediaStore;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
/**
* Immutable representation a desired ringtone, usually originating from a user preference.
@@ -46,7 +53,7 @@ import java.lang.annotation.RetentionPolicy;
* to be internally consistent and reflect effective values - with the exception of not verifying
* the actual URI content. For example, loading a selection Uri that sets a sound source to
* {@link #SOUND_SOURCE_URI}, but doesn't also have a sound Uri set, will result in this class
- * instead returning {@link #SOUND_SOURCE_DEFAULT} from {@link #getSoundSource}.
+ * instead returning {@link #SOUND_SOURCE_UNSPECIFIED} from {@link #getSoundSource}.
*
* <h2>Storing preferences</h2>
*
@@ -57,6 +64,7 @@ import java.lang.annotation.RetentionPolicy;
* @hide
*/
@TestApi
+@FlaggedApi(Flags.FLAG_HAPTICS_CUSTOMIZATION_ENABLED)
public final class RingtoneSelection {
/**
@@ -70,7 +78,7 @@ public final class RingtoneSelection {
* The sound source is not explicitly specified, so it can follow default behavior for its
* context.
*/
- public static final int SOUND_SOURCE_DEFAULT = 0;
+ public static final int SOUND_SOURCE_UNSPECIFIED = 0;
/**
* Sound is explicitly disabled, such as the user having selected "Silent" in the sound picker.
@@ -83,15 +91,25 @@ public final class RingtoneSelection {
public static final int SOUND_SOURCE_URI = 2;
/**
+ * The sound should explicitly use the system default.
+ *
+ * <p>This value isn't valid within the system default itself.
+ */
+ public static final int SOUND_SOURCE_SYSTEM_DEFAULT = 3;
+
+ // Note: Value 4 reserved for possibility of SOURCE_SOURCE_APPLICATION_DEFAULT.
+
+ /**
* Directive for how to make sound.
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "SOUND_SOURCE_", value = {
SOUND_SOURCE_UNKNOWN,
- SOUND_SOURCE_DEFAULT,
+ SOUND_SOURCE_UNSPECIFIED,
SOUND_SOURCE_OFF,
SOUND_SOURCE_URI,
+ SOUND_SOURCE_SYSTEM_DEFAULT,
})
public @interface SoundSource {}
@@ -106,9 +124,9 @@ public final class RingtoneSelection {
/**
* Vibration source is not explicitly specified. If vibration is enabled, this will use the
* first available of {@link #VIBRATION_SOURCE_AUDIO_CHANNEL},
- * {@link #VIBRATION_SOURCE_APPLICATION_PROVIDED}, or system default vibration.
+ * {@link #VIBRATION_SOURCE_APPLICATION_DEFAULT}, or {@link #VIBRATION_SOURCE_SYSTEM_DEFAULT}.
*/
- public static final int VIBRATION_SOURCE_DEFAULT = 0;
+ public static final int VIBRATION_SOURCE_UNSPECIFIED = 0;
/** Specifies that vibration is explicitly disabled for this ringtone. */
public static final int VIBRATION_SOURCE_OFF = 1;
@@ -117,22 +135,31 @@ public final class RingtoneSelection {
public static final int VIBRATION_SOURCE_URI = 2;
/**
+ * The vibration should explicitly use the system default.
+ *
+ * <p>This value isn't valid within the system default itself.
+ */
+ public static final int VIBRATION_SOURCE_SYSTEM_DEFAULT = 3;
+
+ /**
* Specifies that vibration should use the vibration provided by the application. This is
* typically the application's own default for the use-case, provided via
* {@link Ringtone.Builder#setVibrationEffect}. For notification channels, this is the vibration
* effect saved on the notification channel.
*
* <p>If no vibration is specified by the application, this value behaves if the source was
- * {@link #VIBRATION_SOURCE_DEFAULT}.
+ * {@link #VIBRATION_SOURCE_UNSPECIFIED}.
+ *
+ * <p>This value isn't valid within the system default.
*/
- public static final int VIBRATION_SOURCE_APPLICATION_PROVIDED = 3;
+ public static final int VIBRATION_SOURCE_APPLICATION_DEFAULT = 4;
/**
* Specifies that vibration should use haptic audio channels from the
* sound Uri. If the sound URI doesn't have haptic channels, then reverts to the order specified
- * by {@link #VIBRATION_SOURCE_DEFAULT}.
+ * by {@link #VIBRATION_SOURCE_UNSPECIFIED}.
*/
- // Numeric gap from VIBRATION_SOURCE_APPLICATION_PROVIDED in case we want other common elements.
+ // Numeric gap from VIBRATION_SOURCE_APPLICATION_DEFAULT in case we want other common elements.
public static final int VIBRATION_SOURCE_AUDIO_CHANNEL = 10;
/**
@@ -151,10 +178,10 @@ public final class RingtoneSelection {
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "VIBRATION_SOURCE_", value = {
VIBRATION_SOURCE_UNKNOWN,
- VIBRATION_SOURCE_DEFAULT,
+ VIBRATION_SOURCE_UNSPECIFIED,
VIBRATION_SOURCE_OFF,
VIBRATION_SOURCE_URI,
- VIBRATION_SOURCE_APPLICATION_PROVIDED,
+ VIBRATION_SOURCE_APPLICATION_DEFAULT,
VIBRATION_SOURCE_AUDIO_CHANNEL,
VIBRATION_SOURCE_HAPTIC_GENERATOR,
})
@@ -162,9 +189,12 @@ public final class RingtoneSelection {
/**
* Configures {@link #RingtoneSelection#fromUri} to treat an unrecognized Uri as the sound Uri
- * for the returned {@link RingtoneSelection}, with null meaning {@link #SOUND_SOURCE_OFF}.
- * This behavior is particularly suited to loading values from older settings that may contain
- * a raw sound Uri or null for silent.
+ * for the returned {@link RingtoneSelection}, with null meaning {@link #SOUND_SOURCE_OFF},
+ * and symbolic default URIs ({@link RingtoneManager#getDefaultUri}) meaning
+ * {@link #SOUND_SOURCE_SYSTEM_DEFAULT}.
+ *
+ * <p>This behavior is particularly suited to loading values from older settings that may
+ * contain a raw sound Uri or null for silent.
*
* <p>An unrecognized Uri is one for which {@link #isRingtoneSelectionUri(Uri)} returns false.
*/
@@ -173,7 +203,8 @@ public final class RingtoneSelection {
/**
* Configures {@link #RingtoneSelection#fromUri} to treat an unrecognized Uri as the vibration
* Uri for the returned {@link RingtoneSelection}, with null meaning
- * {@link #VIBRATION_SOURCE_OFF}.
+ * {@link #VIBRATION_SOURCE_OFF} and symbolic default URIs
+ * ({@link RingtoneManager#getDefaultUri}) meaning {@link #VIBRATION_SOURCE_SYSTEM_DEFAULT}.
*
* <p>An unrecognized Uri is one for which {@link #isRingtoneSelectionUri(Uri)} returns false.
*/
@@ -182,7 +213,9 @@ public final class RingtoneSelection {
/**
* Configures {@link #RingtoneSelection#fromUri} to treat an unrecognized Uri as an invalid
* value. Null or an invalid values will revert to default behavior correspnoding to
- * {@link #DEFAULT_SELECTION_URI_STRING}.
+ * {@link #DEFAULT_SELECTION_URI_STRING}. Symbolic default URIs
+ * ({@link RingtoneManager#getDefaultUri}) will set both
+ * {@link #SOUND_SOURCE_SYSTEM_DEFAULT} and {@link #VIBRATION_SOURCE_SYSTEM_DEFAULT}.
*
* <p>An unrecognized Uri is one for which {@link #isRingtoneSelectionUri(Uri)} returns false,
* which include {@code null}.
@@ -218,10 +251,11 @@ public final class RingtoneSelection {
/* Common param values */
private static final String SOURCE_OFF_STRING = "off";
+ private static final String SOURCE_SYSTEM_DEFAULT_STRING = "sys";
/* Vibration source param values. */
private static final String VIBRATION_SOURCE_AUDIO_CHANNEL_STRING = "ac";
- private static final String VIBRATION_SOURCE_APPLICATION_PROVIDED_STRING = "app";
+ private static final String VIBRATION_SOURCE_APPLICATION_DEFAULT_STRING = "app";
private static final String VIBRATION_SOURCE_HAPTIC_GENERATOR_STRING = "hg";
@Nullable
@@ -236,53 +270,45 @@ public final class RingtoneSelection {
private RingtoneSelection(@Nullable Uri soundUri, @SoundSource int soundSource,
@Nullable Uri vibrationUri, @VibrationSource int vibrationSource) {
- // Enforce guarantees on the source values: revert to unset if they depend on something
- // that's not set.
- switch (soundSource) {
- case SOUND_SOURCE_URI:
- case SOUND_SOURCE_UNKNOWN: // Allow unknown to revert to URI before default.
- mSoundSource = soundUri != null ? SOUND_SOURCE_URI : SOUND_SOURCE_DEFAULT;
- break;
- default:
- mSoundSource = soundSource;
- break;
- }
- switch (vibrationSource) {
- case VIBRATION_SOURCE_AUDIO_CHANNEL:
- case VIBRATION_SOURCE_HAPTIC_GENERATOR:
- mVibrationSource = soundUri != null ? vibrationSource : VIBRATION_SOURCE_DEFAULT;
- break;
- case VIBRATION_SOURCE_URI:
- case VIBRATION_SOURCE_UNKNOWN: // Allow unknown to revert to URI.
- mVibrationSource =
- vibrationUri != null ? VIBRATION_SOURCE_URI : VIBRATION_SOURCE_DEFAULT;
- break;
- default:
- mVibrationSource = vibrationSource;
- break;
- }
+ // Enforce guarantees on the source values: revert to unspecified if they depend on
+ // something that's not set.
+ //
+ // The non-public "unknown" value can't appear in a getter result, it's just a reserved
+ // "null" value and should be treated the same as an unrecognized value. This can be seen
+ // in Uri parsing. For this and other unrecognized values, we either revert them to the URI
+ // source, if a Uri was included, or the "unspecified" source otherwise. This can be
+ // seen in action in the Uri parsing.
+ //
+ // The "unspecified" source is a public value meaning that there is no specific
+ // behavior indicated, and the defaults and fallbacks should be applied. For example, an
+ // vibration source value of "system default" means to explicitly use the system default
+ // vibration. However, an "unspecified" vibration source will first see if audio coupled
+ // or application-default vibrations are available.
+ mSoundSource = switch (soundSource) {
+ // Supported explicit values that don't have a Uri.
+ case SOUND_SOURCE_OFF, SOUND_SOURCE_UNSPECIFIED, SOUND_SOURCE_SYSTEM_DEFAULT ->
+ soundSource;
+ // Uri and unknown/unrecognized values: use a Uri if one is present, else revert to
+ // unspecified.
+ default ->
+ soundUri != null ? SOUND_SOURCE_URI : SOUND_SOURCE_UNSPECIFIED;
+ };
+ mVibrationSource = switch (vibrationSource) {
+ // Enforce vibration sources that require a sound Uri.
+ case VIBRATION_SOURCE_AUDIO_CHANNEL, VIBRATION_SOURCE_HAPTIC_GENERATOR ->
+ soundUri != null ? vibrationSource : VIBRATION_SOURCE_UNSPECIFIED;
+ // Supported explicit values that don't rely on any Uri.
+ case VIBRATION_SOURCE_OFF, VIBRATION_SOURCE_UNSPECIFIED,
+ VIBRATION_SOURCE_SYSTEM_DEFAULT, VIBRATION_SOURCE_APPLICATION_DEFAULT ->
+ vibrationSource;
+ // Uri and unknown/unrecognized values: use a Uri if one is present, else revert to
+ // unspecified.
+ default ->
+ vibrationUri != null ? VIBRATION_SOURCE_URI : VIBRATION_SOURCE_UNSPECIFIED;
+ };
// Clear Uri values if they're un-used by the source.
- switch (mSoundSource) {
- case SOUND_SOURCE_OFF:
- mSoundUri = null;
- break;
- default:
- // Unset case isn't handled here: the defaulting behavior is left to the player.
- mSoundUri = soundUri;
- break;
- }
- switch (mVibrationSource) {
- case VIBRATION_SOURCE_OFF:
- case VIBRATION_SOURCE_APPLICATION_PROVIDED:
- case VIBRATION_SOURCE_AUDIO_CHANNEL:
- case VIBRATION_SOURCE_HAPTIC_GENERATOR:
- mVibrationUri = null;
- break;
- default:
- // Unset case isn't handled here: the defaulting behavior is left to the player.
- mVibrationUri = vibrationUri;
- break;
- }
+ mSoundUri = mSoundSource == SOUND_SOURCE_URI ? soundUri : null;
+ mVibrationUri = mVibrationSource == VIBRATION_SOURCE_URI ? vibrationUri : null;
}
/**
@@ -360,18 +386,83 @@ public final class RingtoneSelection {
}
// Any URI content://media/ringtone
return ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())
- && MediaStore.AUTHORITY.equals(uri.getAuthority())
+ && MediaStore.AUTHORITY.equals(
+ ContentProvider.getAuthorityWithoutUserId(uri.getAuthority()))
&& MEDIA_URI_RINGTONE_PATH.equals(uri.getPath());
}
+ /**
+ * Strip the specified userId from internal Uris. Non-stripped userIds will typically be
+ * for work profiles referencing system ringtones from the host user.
+ *
+ * This is only for use in RingtoneManager.
+ * @hide
+ */
+ @VisibleForTesting
+ public RingtoneSelection getWithoutUserId(int userIdToStrip) {
+ if (mSoundSource != SOUND_SOURCE_URI && mVibrationSource != VIBRATION_SOURCE_URI) {
+ return this;
+ }
+ // Ok if uri is null. We only replace explicit references to the specified (current) userId.
+ int soundUserId = ContentProvider.getUserIdFromUri(mSoundUri, UserHandle.USER_NULL);
+ int vibrationUserId = ContentProvider.getUserIdFromUri(mVibrationUri, UserHandle.USER_NULL);
+ boolean needToChangeSound =
+ soundUserId != UserHandle.USER_NULL && soundUserId == userIdToStrip;
+ boolean needToChangeVibration =
+ vibrationUserId != UserHandle.USER_NULL && vibrationUserId == userIdToStrip;
+
+ // Anything to do?
+ if (!needToChangeSound && !needToChangeVibration) {
+ return this;
+ }
+
+ RingtoneSelection.Builder updated = new Builder(this);
+ // The relevant uris can't be null, because they contain userIdToStrip.
+ if (needToChangeSound) {
+ // mSoundUri is not null, so the result of getUriWithoutUserId won't be null.
+ updated.setSoundSource(ContentProvider.getUriWithoutUserId(mSoundUri));
+ }
+ if (needToChangeVibration) {
+ updated.setVibrationSource(ContentProvider.getUriWithoutUserId(mVibrationUri));
+ }
+ return updated.build();
+ }
+
+ @Override
+ public String toString() {
+ return toUri().toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof RingtoneSelection other)) {
+ return false;
+ }
+ return this.mSoundSource == other.mSoundSource
+ && this.mVibrationSource == other.mVibrationSource
+ && Objects.equals(this.mSoundUri, other.mSoundUri)
+ && Objects.equals(this.mVibrationUri, other.mVibrationUri);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSoundSource, mVibrationSource, mSoundUri, mVibrationUri);
+ }
/**
* Converts a Uri into a RingtoneSelection.
*
- * <p>Null values and Uris that {@link #isRingtoneSelectionUri(Uri)} returns false will be
- * treated according to the behaviour specified by the {@code unrecognizedValueBehavior}
- * parameter.
+ * <p>Null values, Uris that {@link #isRingtoneSelectionUri(Uri)} returns false (except for
+ * old-style symbolic default Uris {@link RingtoneManager#getDefaultUri}) will be treated
+ * according to the behaviour specified by the {@code unrecognizedValueBehavior} parameter.
+ *
+ * <p>Symbolic default Uris (where {@link RingtoneManager#getDefaultType(Uri)} returns -1,
+ * will map sources to {@link #SOUND_SOURCE_SYSTEM_DEFAULT} and
+ * {@link #VIBRATION_SOURCE_SYSTEM_DEFAULT}.
*
* @param uri The Uri to convert, potentially null.
* @param unrecognizedValueBehavior indicates how to treat values for which
@@ -384,21 +475,35 @@ public final class RingtoneSelection {
if (isRingtoneSelectionUri(uri)) {
return parseRingtoneSelectionUri(uri);
}
+ // Old symbolic default URIs map to the sources suggested by the unrecognized behavior.
+ // It doesn't always map to both sources because the app may have its own default behavior
+ // to apply, so non-primary sources are left as unspecified, which will revert to the
+ // system default in the absence of an app default.
+ boolean isDefaultUri = RingtoneManager.getDefaultType(uri) > 0;
RingtoneSelection.Builder builder = new RingtoneSelection.Builder();
switch (unrecognizedValueBehavior) {
case FROM_URI_RINGTONE_SELECTION_ONLY:
- // Always return use-defaults for unrecognized ringtone selection Uris.
+ if (isDefaultUri) {
+ builder.setSoundSource(SOUND_SOURCE_SYSTEM_DEFAULT);
+ builder.setVibrationSource(VIBRATION_SOURCE_SYSTEM_DEFAULT);
+ }
+ // Always return unspecified (defaults) for unrecognized ringtone selection Uris.
return builder.build();
case FROM_URI_RINGTONE_SELECTION_OR_SOUND:
if (uri == null) {
return builder.setSoundSource(SOUND_SOURCE_OFF).build();
+ } else if (isDefaultUri) {
+ return builder.setSoundSource(SOUND_SOURCE_SYSTEM_DEFAULT).build();
} else {
return builder.setSoundSource(uri).build();
}
case FROM_URI_RINGTONE_SELECTION_OR_VIBRATION:
if (uri == null) {
return builder.setVibrationSource(VIBRATION_SOURCE_OFF).build();
+ } else if (isDefaultUri) {
+ return builder.setVibrationSource(VIBRATION_SOURCE_SYSTEM_DEFAULT).build();
} else {
+ // Unlike sound, there's no legacy settings alias uri for the default.
return builder.setVibrationSource(uri).build();
}
default:
@@ -407,7 +512,12 @@ public final class RingtoneSelection {
}
}
- /** Parses the Uri, which has already been checked for {@link #isRingtoneSelectionUri(Uri)}. */
+ /**
+ * Parses the Uri, which has already been checked for {@link #isRingtoneSelectionUri(Uri)}.
+ * As a special case to be more compatible, if the RingtoneSelection has a userId specified in
+ * the authority, then this is pushed down into the sound and vibration Uri, as the selection
+ * itself is agnostic.
+ */
@NonNull
private static RingtoneSelection parseRingtoneSelectionUri(@NonNull Uri uri) {
RingtoneSelection.Builder builder = new RingtoneSelection.Builder();
@@ -416,19 +526,39 @@ public final class RingtoneSelection {
uri.getQueryParameter(URI_PARAM_VIBRATION_SOURCE));
Uri soundUri = getParamAsUri(uri, URI_PARAM_SOUND_URI);
Uri vibrationUri = getParamAsUri(uri, URI_PARAM_VIBRATION_URI);
+
+ // Add userId if necessary. This won't override an existing one in the sound/vib Uris.
+ int userIdFromAuthority = ContentProvider.getUserIdFromAuthority(
+ uri.getAuthority(), UserHandle.USER_NULL);
+ if (userIdFromAuthority != UserHandle.USER_NULL) {
+ // Won't override existing user id.
+ if (soundUri != null) {
+ soundUri = ContentProvider.maybeAddUserId(soundUri, userIdFromAuthority);
+ }
+ if (vibrationUri != null) {
+ vibrationUri = ContentProvider.maybeAddUserId(vibrationUri, userIdFromAuthority);
+ }
+ }
+
+ // Set sound uri if present, but map system default Uris to the system default source.
if (soundUri != null) {
- builder.setSoundSource(soundUri);
+ if (RingtoneManager.getDefaultType(uri) >= 0) {
+ builder.setSoundSource(SOUND_SOURCE_SYSTEM_DEFAULT);
+ } else {
+ builder.setSoundSource(soundUri);
+ }
}
if (vibrationUri != null) {
builder.setVibrationSource(vibrationUri);
}
+
// Don't set the source if there's a URI and the source is default, because that will
// override the Uri source set above. In effect, we prioritise "explicit" sources over
// an implicit Uri source - except for "default", which isn't really explicit.
- if (soundSource != SOUND_SOURCE_DEFAULT || soundUri == null) {
+ if (soundSource != SOUND_SOURCE_UNSPECIFIED || soundUri == null) {
builder.setSoundSource(soundSource);
}
- if (vibrationSource != VIBRATION_SOURCE_DEFAULT || vibrationUri == null) {
+ if (vibrationSource != VIBRATION_SOURCE_UNSPECIFIED || vibrationUri == null) {
builder.setVibrationSource(vibrationSource);
}
return builder.build();
@@ -450,26 +580,28 @@ public final class RingtoneSelection {
*/
@Nullable
private static String soundSourceToString(@SoundSource int soundSource) {
- switch (soundSource) {
- case SOUND_SOURCE_OFF: return SOURCE_OFF_STRING;
- default: return null;
- }
+ return switch (soundSource) {
+ case SOUND_SOURCE_OFF -> SOURCE_OFF_STRING;
+ case SOUND_SOURCE_SYSTEM_DEFAULT -> SOURCE_SYSTEM_DEFAULT_STRING;
+ default -> null;
+ };
}
/**
* Returns the sound source int corresponding to the query string value. Returns
* {@link #SOUND_SOURCE_UNKNOWN} if the value isn't recognised, and
- * {@link #SOUND_SOURCE_DEFAULT} if the value is {@code null} (not in the Uri).
+ * {@link #SOUND_SOURCE_UNSPECIFIED} if the value is {@code null} (not in the Uri).
*/
@SoundSource
private static int stringToSoundSource(@Nullable String soundSource) {
if (soundSource == null) {
- return SOUND_SOURCE_DEFAULT;
- }
- switch (soundSource) {
- case SOURCE_OFF_STRING: return SOUND_SOURCE_OFF;
- default: return SOUND_SOURCE_UNKNOWN;
+ return SOUND_SOURCE_UNSPECIFIED;
}
+ return switch (soundSource) {
+ case SOURCE_OFF_STRING -> SOUND_SOURCE_OFF;
+ case SOURCE_SYSTEM_DEFAULT_STRING -> SOUND_SOURCE_SYSTEM_DEFAULT;
+ default -> SOUND_SOURCE_UNKNOWN;
+ };
}
/**
@@ -478,30 +610,31 @@ public final class RingtoneSelection {
*/
@Nullable
private static String vibrationSourceToString(@VibrationSource int vibrationSource) {
- switch (vibrationSource) {
- case VIBRATION_SOURCE_OFF: return SOURCE_OFF_STRING;
- case VIBRATION_SOURCE_AUDIO_CHANNEL: return VIBRATION_SOURCE_AUDIO_CHANNEL_STRING;
- case VIBRATION_SOURCE_HAPTIC_GENERATOR:
- return VIBRATION_SOURCE_HAPTIC_GENERATOR_STRING;
- case VIBRATION_SOURCE_APPLICATION_PROVIDED:
- return VIBRATION_SOURCE_APPLICATION_PROVIDED_STRING;
- default: return null;
- }
+ return switch (vibrationSource) {
+ case VIBRATION_SOURCE_OFF -> SOURCE_OFF_STRING;
+ case VIBRATION_SOURCE_AUDIO_CHANNEL -> VIBRATION_SOURCE_AUDIO_CHANNEL_STRING;
+ case VIBRATION_SOURCE_HAPTIC_GENERATOR -> VIBRATION_SOURCE_HAPTIC_GENERATOR_STRING;
+ case VIBRATION_SOURCE_APPLICATION_DEFAULT ->
+ VIBRATION_SOURCE_APPLICATION_DEFAULT_STRING;
+ case VIBRATION_SOURCE_SYSTEM_DEFAULT -> SOURCE_SYSTEM_DEFAULT_STRING;
+ default -> null;
+ };
}
@VibrationSource
private static int stringToVibrationSource(@Nullable String vibrationSource) {
if (vibrationSource == null) {
- return VIBRATION_SOURCE_DEFAULT;
- }
- switch (vibrationSource) {
- case SOURCE_OFF_STRING: return VIBRATION_SOURCE_OFF;
- case VIBRATION_SOURCE_AUDIO_CHANNEL_STRING: return VIBRATION_SOURCE_AUDIO_CHANNEL;
- case VIBRATION_SOURCE_HAPTIC_GENERATOR_STRING: return VIBRATION_SOURCE_HAPTIC_GENERATOR;
- case VIBRATION_SOURCE_APPLICATION_PROVIDED_STRING:
- return VIBRATION_SOURCE_APPLICATION_PROVIDED;
- default: return VIBRATION_SOURCE_UNKNOWN;
+ return VIBRATION_SOURCE_UNSPECIFIED;
}
+ return switch (vibrationSource) {
+ case SOURCE_OFF_STRING -> VIBRATION_SOURCE_OFF;
+ case SOURCE_SYSTEM_DEFAULT_STRING -> VIBRATION_SOURCE_SYSTEM_DEFAULT;
+ case VIBRATION_SOURCE_AUDIO_CHANNEL_STRING -> VIBRATION_SOURCE_AUDIO_CHANNEL;
+ case VIBRATION_SOURCE_HAPTIC_GENERATOR_STRING -> VIBRATION_SOURCE_HAPTIC_GENERATOR;
+ case VIBRATION_SOURCE_APPLICATION_DEFAULT_STRING ->
+ VIBRATION_SOURCE_APPLICATION_DEFAULT;
+ default -> VIBRATION_SOURCE_UNKNOWN;
+ };
}
/**
@@ -512,12 +645,13 @@ public final class RingtoneSelection {
public static final class Builder {
private Uri mSoundUri;
private Uri mVibrationUri;
- @SoundSource private int mSoundSource = SOUND_SOURCE_DEFAULT;
- @VibrationSource private int mVibrationSource = VIBRATION_SOURCE_DEFAULT;
+ @SoundSource private int mSoundSource = SOUND_SOURCE_UNSPECIFIED;
+ @VibrationSource private int mVibrationSource = VIBRATION_SOURCE_UNSPECIFIED;
/**
* Creates a new {@link RingtoneSelection} builder. A default ringtone selection has its
- * sound and vibration source unset, which means they would fall back to system defaults.
+ * sound and vibration source unspecified, which means they would fall back to app/system
+ * defaults.
*/
public Builder() {}
@@ -559,7 +693,9 @@ public final class RingtoneSelection {
*/
@NonNull
public Builder setSoundSource(@NonNull Uri soundUri) {
- mSoundUri = requireNonNull(soundUri);
+ // getCanonicalUri shouldn't return null. If it somehow did, then the
+ // RingtoneSelection constructor will revert this to unspecified.
+ mSoundUri = requireNonNull(soundUri).getCanonicalUri();
mSoundSource = SOUND_SOURCE_URI;
return this;
}
@@ -587,7 +723,9 @@ public final class RingtoneSelection {
*/
@NonNull
public Builder setVibrationSource(@NonNull Uri vibrationUri) {
- mVibrationUri = requireNonNull(vibrationUri);
+ // getCanonicalUri shouldn't return null. If it somehow did, then the
+ // RingtoneSelection constructor will revert this to unspecified.
+ mVibrationUri = requireNonNull(vibrationUri).getCanonicalUri();
mVibrationSource = VIBRATION_SOURCE_URI;
return this;
}
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 83d2b613f80a..a354f9180e09 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -15,8 +15,15 @@ flag {
}
flag {
- namespace: "media_solutions"
- name: "enable_audio_policies_device_and_bluetooth_controller"
- description: "Use Audio Policies implementation for device and Bluetooth route controllers."
- bug: "280576228"
+ namespace: "media_solutions"
+ name: "enable_audio_policies_device_and_bluetooth_controller"
+ description: "Use Audio Policies implementation for device and Bluetooth route controllers."
+ bug: "280576228"
+}
+
+flag {
+ namespace: "media_solutions"
+ name: "disable_screen_off_broadcast_receiver"
+ description: "Disables the broadcast receiver that prevents scanning when the screen is off."
+ bug: "304234628"
}
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index ca20225e8885..bdd7afeb2f65 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -22,7 +22,7 @@ android_test {
"android-ex-camera2",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
"libdexmakerjvmtiagent",
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index 4cccf8972798..61b18c88e734 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -24,7 +24,7 @@ android_test {
"compatibility-device-util-axt",
"mockito-target-minus-junit4",
"testng",
- "truth-prebuilt",
+ "truth",
],
test_suites: ["general-tests"],
platform_apis: true,
diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp
index e313c46d1973..48cd8b69ade8 100644
--- a/media/tests/projection/Android.bp
+++ b/media/tests/projection/Android.bp
@@ -30,7 +30,7 @@ android_test {
"platform-test-annotations",
"testng",
"testables",
- "truth-prebuilt",
+ "truth",
"platform-compat-test-rules",
],
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index ba88484518aa..2318bb95dabb 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -18,21 +18,23 @@ package com.android.credentialmanager.autofill
import android.app.assist.AssistStructure
import android.content.Context
-import android.credentials.GetCredentialRequest
import android.credentials.CredentialManager
-import android.credentials.GetCandidateCredentialsResponse
import android.credentials.CredentialOption
import android.credentials.GetCandidateCredentialsException
+import android.credentials.GetCandidateCredentialsResponse
+import android.credentials.GetCredentialRequest
import android.os.Bundle
import android.os.CancellationSignal
import android.os.OutcomeReceiver
-import android.service.autofill.FillRequest
import android.service.autofill.AutofillService
-import android.service.autofill.FillResponse
import android.service.autofill.FillCallback
-import android.service.autofill.SaveRequest
+import android.service.autofill.FillRequest
+import android.service.autofill.FillResponse
import android.service.autofill.SaveCallback
+import android.service.autofill.SaveRequest
+import android.service.credentials.CredentialProviderService
import android.util.Log
+import android.view.autofill.AutofillId
import org.json.JSONObject
import java.util.concurrent.Executors
@@ -129,27 +131,31 @@ class CredentialAutofillService : AutofillService() {
}
private fun traverseNode(
- viewNode: AssistStructure.ViewNode?,
+ viewNode: AssistStructure.ViewNode,
cmRequests: MutableList<CredentialOption>
) {
- val options = getCredentialOptionsFromViewNode(viewNode)
- cmRequests.addAll(options)
+ viewNode.autofillId?.let {
+ val options = getCredentialOptionsFromViewNode(viewNode, it)
+ cmRequests.addAll(options)
+ }
- val children: List<AssistStructure.ViewNode>? =
- viewNode?.run {
+ val children: List<AssistStructure.ViewNode> =
+ viewNode.run {
(0 until childCount).map { getChildAt(it) }
}
- children?.forEach { childNode: AssistStructure.ViewNode ->
+ children.forEach { childNode: AssistStructure.ViewNode ->
traverseNode(childNode, cmRequests)
}
}
- private fun getCredentialOptionsFromViewNode(viewNode: AssistStructure.ViewNode?):
- List<CredentialOption> {
+ private fun getCredentialOptionsFromViewNode(
+ viewNode: AssistStructure.ViewNode,
+ autofillId: AutofillId
+ ): List<CredentialOption> {
// TODO(b/293945193) Replace with isCredential check from viewNode
val credentialHints: MutableList<String> = mutableListOf()
- if (viewNode != null && viewNode.autofillHints != null) {
+ if (viewNode.autofillHints != null) {
for (hint in viewNode.autofillHints!!) {
if (hint.startsWith(CRED_HINT_PREFIX)) {
credentialHints.add(hint.substringAfter(CRED_HINT_PREFIX))
@@ -159,12 +165,14 @@ class CredentialAutofillService : AutofillService() {
val credentialOptions: MutableList<CredentialOption> = mutableListOf()
for (credentialHint in credentialHints) {
- convertJsonToCredentialOption(credentialHint).let { credentialOptions.addAll(it) }
+ convertJsonToCredentialOption(credentialHint, autofillId)
+ .let { credentialOptions.addAll(it) }
}
return credentialOptions
}
- private fun convertJsonToCredentialOption(jsonString: String): List<CredentialOption> {
+ private fun convertJsonToCredentialOption(jsonString: String, autofillId: AutofillId):
+ List<CredentialOption> {
// TODO(b/302000646) Move this logic to jetpack so that is consistent
// with building the json
val credentialOptions: MutableList<CredentialOption> = mutableListOf()
@@ -173,11 +181,14 @@ class CredentialAutofillService : AutofillService() {
val options = json.getJSONArray(CRED_OPTIONS_KEY)
for (i in 0 until options.length()) {
val option = options.getJSONObject(i)
-
+ val candidateBundle = convertJsonToBundle(option.getJSONObject(CANDIDATE_DATA_KEY))
+ candidateBundle.putParcelable(
+ CredentialProviderService.EXTRA_AUTOFILL_ID,
+ autofillId)
credentialOptions.add(CredentialOption(
option.getString(TYPE_KEY),
convertJsonToBundle(option.getJSONObject(REQUEST_DATA_KEY)),
- convertJsonToBundle(option.getJSONObject(CANDIDATE_DATA_KEY)),
+ candidateBundle,
option.getBoolean(SYS_PROVIDER_REQ_KEY),
))
}
diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp
index 633f18610921..86c62ef299e4 100644
--- a/packages/ExternalStorageProvider/tests/Android.bp
+++ b/packages/ExternalStorageProvider/tests/Android.bp
@@ -25,7 +25,7 @@ android_test {
static_libs: [
"androidx.test.rules",
"mockito-target",
- "truth-prebuilt",
+ "truth",
],
certificate: "platform",
diff --git a/packages/FusedLocation/Android.bp b/packages/FusedLocation/Android.bp
index 64b4c54e74ad..61a82701d155 100644
--- a/packages/FusedLocation/Android.bp
+++ b/packages/FusedLocation/Android.bp
@@ -47,7 +47,7 @@ android_test {
test_config: "test/AndroidTest.xml",
srcs: [
"test/src/**/*.java",
- "src/**/*.java", // include real sources because we're forced to test this directly
+ "src/**/*.java", // include real sources because we're forced to test this directly
],
libs: [
"android.test.base",
@@ -60,9 +60,9 @@ android_test {
"androidx.test.ext.junit",
"androidx.test.ext.truth",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
platform_apis: true,
certificate: "platform",
- test_suites: ["device-tests"]
+ test_suites: ["device-tests"],
}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_brazilian.kcm b/packages/InputDevices/res/raw/keyboard_layout_brazilian.kcm
index ad3199ff2dc8..d9338b1fdab7 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_brazilian.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_brazilian.kcm
@@ -337,7 +337,7 @@ key M {
label: 'M'
base: 'm'
shift, capslock: 'M'
- shift+capslock: 'n'
+ shift+capslock: 'm'
}
key COMMA {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_persian.kcm b/packages/InputDevices/res/raw/keyboard_layout_persian.kcm
index 67449220b189..fc53cbad91db 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_persian.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_persian.kcm
@@ -12,9 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-
-type FULL
+type OVERLAY
### Basic QWERTY keys ###
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 88bb30b34ede..7f23f747090b 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -227,13 +227,6 @@
android:label="@string/keyboard_layout_turkish"
android:keyboardLayout="@raw/keyboard_layout_turkish"
android:keyboardLocale="tr-Latn"
- android:keyboardLayoutType="qwerty" />
-
- <keyboard-layout
- android:name="keyboard_layout_turkish"
- android:label="@string/keyboard_layout_turkish"
- android:keyboardLayout="@raw/keyboard_layout_turkish"
- android:keyboardLocale="tr-Latn"
android:keyboardLayoutType="turkish_q" />
<keyboard-layout
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt
index d0a61882593c..0757df347d68 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt
@@ -29,8 +29,8 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
@@ -46,6 +46,7 @@ import com.android.settingslib.spa.framework.theme.SettingsTheme
fun SettingsTextFieldPassword(
value: String,
label: String,
+ enabled: Boolean = true,
onTextChange: (String) -> Unit,
) {
var visibility by remember { mutableStateOf(false) }
@@ -60,6 +61,7 @@ fun SettingsTextFieldPassword(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Send
),
+ enabled = enabled,
trailingIcon = {
Icon(
imageVector = if (visibility) Icons.Outlined.VisibilityOff
diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp
index 4031cd7f7a6f..639d1a7a7f55 100644
--- a/packages/SettingsLib/Spa/testutils/Android.bp
+++ b/packages/SettingsLib/Spa/testutils/Android.bp
@@ -31,7 +31,7 @@ android_library {
"androidx.compose.ui_ui-test-manifest",
"androidx.lifecycle_lifecycle-runtime-testing",
"mockito-kotlin2",
- "truth-prebuilt",
+ "truth",
],
kotlincflags: [
"-Xjvm-default=all",
diff --git a/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig b/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig
index d1bcb5746414..4936f882f91e 100644
--- a/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig
@@ -5,4 +5,11 @@ flag {
namespace: "media_solutions"
description: "Gates whether to use a MediaRouter2-based implementation of InfoMediaManager, instead of the legacy MediaRouter2Manager-based implementation."
bug: "192657812"
+}
+
+flag {
+ name: "enable_tv_media_output_dialog"
+ namespace: "tv_system_ui"
+ description: "Gates all the changes for the tv specific media output dialog"
+ bug: "303205631"
} \ No newline at end of file
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 53db19207947..afdb92b1bbab 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi twee stawe."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi drie stawe."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi-sein vol."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Gekoppel aan jou toestel."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Oop netwerk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Veilige netwerk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android-bedryfstelsel"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 77c9a970ce43..ea8491b2138c 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"ሁለት የWiFi አሞሌዎች።"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"ሦስት የWiFi አሞሌዎች።"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"የWiFi ምልክት ሙሉ ነው።"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"ከመሣሪያዎ ጋር ተገናኝቷል።"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"አውታረ መረብ ክፈት"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ደህንነቱ የተጠበቀ አውታረ መረብ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android ስርዓተ ክወና"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 30d011aa2b58..c29e6911396b 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"‏إشارة Wi-Fi تتكون من شريطين."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"‏إشارة Wi-Fi تتكون من ثلاثة أشرطة."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"‏إشارة Wi-Fi كاملة."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"تم الاتصال بجهازك."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"شبكة مفتوحة"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"شبكة محمية بكلمة مرور"</string>
<string name="process_kernel_label" msgid="950292573930336765">"‏نظام التشغيل Android"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 31aff6a136f6..8eff4f6eba44 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"ৱাই-ফাইৰ দুডাল দণ্ড।"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"ৱাই-ফাইৰ তিনিডাল দণ্ড।"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"ৱাই-ফাই সংকেত সৰ্বোচ্চ।"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"আপোনাৰ ডিভাইচটোৰ সৈতে সংযোগ কৰা আছে।"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"মুক্ত নেটৱৰ্ক"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"সুৰক্ষিত নেটৱৰ্ক"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index c675ce797984..dfd1b7b83204 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi iki xətdir."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi üç xətdir."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi siqnalı tamdır."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Cihaza qoşuldu."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Açıq şəbəkə"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Təhlükəsiz şəbəkə"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index f7be60fe8be2..528e96e4c747 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi signal ima dve crte."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi signal ima tri crte."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi signal je najjači."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Povezano je sa uređajem."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorena mreža"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Bezbedna mreža"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index d2f2851f58a0..52614b7df160 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Два слупкi Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Тры слупкi Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Поўны сігнал Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Устаноўлена падключэнне да прылады."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Адкрытая сетка"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Бяспечная сетка"</string>
<string name="process_kernel_label" msgid="950292573930336765">"АС Android"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2540c129dd53..b28ae6742f68 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi е с две чертички."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi е с три чертички."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Сигналът за Wi-Fi е пълен."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Установена е връзка с устройството ви."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Отворена мрежа"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Защитена мрежа"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android (ОС)"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 745b9446a1ab..c91f14ca2fad 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"ওয়াই ফাই এ দুইটি দণ্ড৷"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"ওয়াই ফাই এ তিনটি দণ্ড৷"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"ওয়াই ফাই এ সম্পূর্ণ সিগন্যাল৷"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"আপনার ডিভাইসের সাথে কানেক্ট করা হয়েছে।"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"খোলা নেটওয়ার্ক"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"সুরক্ষিত নেটওয়ার্ক"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index cab0841dd423..aa1073d74d40 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi signal ima dvije crte."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi signal ima tri crte."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi signal je pun."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Povezani ste s uređajem."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorena mreža"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sigurna mreža"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index a65b9c2b60d8..ab6393a7d407 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Senyal Wi-Fi: dues barres."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Senyal Wi-Fi: tres barres."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Senyal Wi-Fi: complet."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"S\'ha connectat al teu dispositiu."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Xarxa oberta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Xarxa segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 96c02aed1a65..e7d524317bae 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi – dvě čárky."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi – tři čárky."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi – plný signál."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Připojeno k vašemu zařízení."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Nezabezpečená síť"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Zabezpečená síť"</string>
<string name="process_kernel_label" msgid="950292573930336765">"OS Android"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 1e4c7b7b04fb..1612ac030205 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi har to bjælker."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi har tre bjælker."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi har fuldt signal."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Der er oprettet forbindelse til din enhed."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Åbent netværk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sikkert netværk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 37f7e5aa732a..73a44f140cbf 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WLAN: zwei Balken"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WLAN: drei Balken"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WLAN: volle Signalstärke"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Mit deinem Gerät verbunden."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Offenes Netzwerk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sicheres Netzwerk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 84b8bf221c40..7dfd679ffacf 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Δύο γραμμές Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Τρεις γραμμές Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Άριστο σήμα Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Συνδέθηκε στη συσκευή σας."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Ανοικτό δίκτυο"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Ασφαλές δίκτυο"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Λειτουργικό σύστημα Android"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 7298c022e702..aead40d12072 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi two bars."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi three bars."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi signal full."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Connected to your device."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Open network"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Secure network"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 7298c022e702..aead40d12072 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi two bars."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi three bars."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi signal full."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Connected to your device."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Open network"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Secure network"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 7298c022e702..aead40d12072 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi two bars."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi three bars."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi signal full."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Connected to your device."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Open network"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Secure network"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 86541fd5b294..291a68bc14fc 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Dos barras de Wi-Fi"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Tres barras de Wi-Fi"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Señal de Wi-Fi excelente"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Se estableció conexión con el dispositivo."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Red abierta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Red segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"SO Android"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ef9cc03421d2..b4bc31913902 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Dos barras de Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Tres barras de Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Señal de Wi-Fi al máximo."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Conectado a tu dispositivo."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Red abierta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Red segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"SO Android"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index c8d806b21bd4..e5cbaf61fbb5 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi: kaks pulka."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi: kolm pulka."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi-signaal on tugev."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Seadmega ühendatud."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Avatud võrk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Turvaline võrk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 95adf968af12..00f43a3bf51b 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -264,7 +264,7 @@
<string-array name="debug_hw_overdraw_entries">
<item msgid="1968128556747588800">"Desaktibatuta"</item>
<item msgid="3033215374382962216">"Erakutsi gainidatzi diren eremuak"</item>
- <item msgid="3474333938380896988">"Erakutsi daltonismorako eremuak"</item>
+ <item msgid="3474333938380896988">"Erakutsi deuteranomaliarako eremuak"</item>
</string-array>
<string-array name="app_process_limit_entries">
<item msgid="794656271086646068">"Muga estandarra"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 7d76514f2ef0..90d45eb44fdc 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi sarearen bi barra."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi sarearen hiru barra."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi sarearen seinalea osoa."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Gailura konektatuta."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Sare irekia"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sare segurua"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android sistema eragilea"</string>
@@ -368,7 +367,7 @@
<string name="debug_hw_overdraw" msgid="8944851091008756796">"Araztu GPU gainidazketa"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Desgaitu HW gainjartzeak"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"Erabili beti GPUa pantaila-muntaietarako"</string>
- <string name="simulate_color_space" msgid="1206503300335835151">"Simulatu kolore-eremua"</string>
+ <string name="simulate_color_space" msgid="1206503300335835151">"Simulatu kolore-espazioa"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Gaitu OpenGL aztarnak"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Desgaitu USB bidez audioa bideratzeko aukera"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Desgaitu USB bidezko audio-gailuetara automatikoki bideratzeko aukera"</string>
@@ -441,7 +440,7 @@
<string name="picture_color_mode_desc" msgid="151780973768136200">"Erabili sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desgaituta"</string>
<string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Ikusmen-monokromia"</string>
- <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Daltonismoa (gorri-berdeak)"</string>
+ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomalia (gorri-berdeak)"</string>
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanopia (gorri-berdeak)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (urdin-horia)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Koloreen zuzenketa"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index beb0b968b338..f3f97c460780 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"‏دو نوار برای Wi‑Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"‏سه نوار برای Wi‑Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"‏قدرت سیگنال Wi‑Fi کامل است."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"به دستگاهتان متصل شد."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"شبکه باز"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"شبکه ایمن"</string>
<string name="process_kernel_label" msgid="950292573930336765">"‏سیستم‌عامل Android"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 88723162ae7d..7f3d0f286695 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi-signaali – kaksi palkkia"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi-signaali – kolme palkkia"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Vahva Wi-Fi-signaali"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Yhdistetty laitteeseesi."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Avoin verkko"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Suojattu verkko"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android-käyttöjärjestelmä"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 98e3753376e3..b7c3a81b47cd 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi : deux barres."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi : trois barres."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi : signal complet."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Connecté à votre appareil."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Réseau ouvert"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Réseau sécurisé"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Système d\'exploitation Android"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 4a64041192a3..a9e0c6a5ccb5 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Signal Wi-Fi moyen"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Signal Wi-Fi bon"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Signal Wi-Fi excellent"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Connecté à votre appareil."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Réseau ouvert"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Réseau sécurisé"</string>
<string name="process_kernel_label" msgid="950292573930336765">"OS Android"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 26738e6f54e7..09c2969bac2d 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Dúas barras de wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Tres barras de wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Sinal completo de wifi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Conexión establecida co teu dispositivo."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rede aberta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rede segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"SO Android"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index b620d4184b8e..575c67510e89 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi બે બાર."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi ત્રણ બાર."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"પૂર્ણ Wifi સિગ્નલ."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"તમારા ડિવાઇસ સાથે કનેક્ટેડ છે."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"નેટવર્ક ખોલો"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"સુરક્ષિત નેટવર્ક"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 3811167c9c49..655fac041c9b 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"वाई-फ़ाई की दो पट्टी मिल रही हैं."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"वाई-फ़ाई की एक पट्टी मिल रही है."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"पूरे वाई-फ़ाई सिग्नल मिल रहे हैं."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"आपके डिवाइस से कनेक्ट हो गया है."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"खुला नेटवर्क"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"सुरक्षित नेटवर्क"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
@@ -598,7 +597,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"प्रोफ़ाइल की जानकारी"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"इससे पहले कि आप कोई प्रतिबंधित प्रोफ़ाइल बनाएं, आपको अपने ऐप्लिकेशन और व्यक्तिगत डेटा की सुरक्षा करने के लिए एक स्क्रीन लॉक सेट करना होगा."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"लॉक सेट करें"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> पर जाएं"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g> पर स्विच करें"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नए उपयोगकर्ता को जोड़ा जा रहा है…"</string>
<string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"नया मेहमान खाता बनाया जा रहा है…"</string>
<string name="add_user_failed" msgid="4809887794313944872">"नया उपयोगकर्ता जोड़ा नहीं जा सका"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 71a2daeb901c..f0e16a47346f 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi signal ima dva stupca."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi signal ima tri stupca."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi signal je pun."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Povezano s vašim uređajem."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorena mreža"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sigurna mreža"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
@@ -619,7 +618,7 @@
<string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time će se izbrisati aplikacije i podaci iz trenutačne gostujuće sesije."</string>
<string name="grant_admin" msgid="4323199171790522574">"Da, dodijeli status administratora"</string>
<string name="not_grant_admin" msgid="3557849576157702485">"Ne, nemoj dodijeliti status administratora"</string>
- <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izlaz"</string>
+ <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izađi"</string>
<string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Želite li spremiti aktivnosti gosta?"</string>
<string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete spremiti aktivnosti iz ove sesije ili izbrisati sve aplikacije i podatke"</string>
<string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 5fac75da75ab..420e0e969fd9 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi-jel: két sáv."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi-jel: három sáv."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi-jel: teljes."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Csatlakoztatva az eszközhöz."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Nyílt hálózat"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Biztonságos hálózat"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index e40c5e164110..705fcf6637b2 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi-ի ուժգնությունը՝ երկու գիծ:"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi-ի ուժգնությունը՝ երեք գիծ:"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi-ի ազդանշանը ուժեղ է:"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Միացած է ձեր սարքին։"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Բաց ցանց"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Անվտանգ ցանց"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index ca1b6be5b478..e33dd05264c3 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi dua baris"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi tiga baris."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Sinyal Wi-Fi penuh."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Terhubung ke perangkat Anda."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Jaringan terbuka"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Jaringan aman"</string>
<string name="process_kernel_label" msgid="950292573930336765">"OS Android"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 1f2dcfb7c790..e1fb248604c2 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi: Tvö strik."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: Þrjú strik."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Fullur Wi-Fi sendistyrkur."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Tengt við tækið þitt."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Opið net"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Öruggt net"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android stýrikerfið"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index e255c85a7d69..b2cfd371fe25 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi: due barre."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: tre barre."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Segnale Wi-Fi completo."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Connessione al dispositivo effettuata."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rete aperta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rete protetta"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Sistema operativo Android"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index edcac10e8f24..9ca74778d978 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"‏שני פסים של Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"‏שלושה פסים של Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"‏אות Wi-Fi מלא."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"מחובר למכשיר שלך."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"רשת פתוחה"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"רשת מאובטחת"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index bf21de291e6a..dcce2b4436aa 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fiはレベル2です。"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fiはレベル3です。"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fiの電波はフルです。"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"デバイスに接続しました。"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"オープンネットワーク"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"保護されたネットワーク"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 9000de4c990b..eb32e1ce2a8d 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi სიგნალი ორ ზოლზეა."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi სიგნალი სამ ზოლზეა."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi სიგნალი სრულია."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"დაკავშირებულია თქვენს მოწყობილობასთან."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ღია ქსელი"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"დაცული ქსელი"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 610fed1f6550..73a8efde7a97 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi сигналы — екі жолақ."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi сигналы — үш жолақ."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi сигналы толық."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Құрылғыңызға жалғанды."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Ашық желі"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Қауіпсіз желі"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index b7999c73f33a..1c32e626f1b6 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi ពីរកាំ"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi បីកាំ"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"សេវា Wifi ពេញ"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"បានភ្ជាប់ទៅឧបករណ៍របស់អ្នក។"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"បើក​បណ្ដាញ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"បណ្តាញ​ដែល​មានសុវត្ថិភាព"</string>
<string name="process_kernel_label" msgid="950292573930336765">"ប្រព័ន្ធ​ប្រតិបត្តិការ Android"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index c788dd5fc8bd..ede347db975f 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"ವೈಫೈ ಎರಡು ಪಟ್ಟಿಗಳು."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"ವೈಫೈ ಮೂರು ಪಟ್ಟಿಗಳು."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"ವೈಫೈ ಸಿಗ್ನಲ್‌‌ ಪೂರ್ತಿ ಇದೆ."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ನೆಟ್‌ವರ್ಕ್‌ ತೆರೆಯಿರಿ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ಸುರಕ್ಷಿತ ನೆಟ್‌ವರ್ಕ್"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 2c51d1f9edd1..78bd616dffe2 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi 신호 막대가 두 개입니다."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi 신호 막대가 세 개입니다."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi 신호가 강합니다."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"기기에 연결되었습니다."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"개방형 네트워크"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"보안 네트워크"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 14814f4ed6e8..a0b91230713d 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi: эки таякча."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi: үч таякча."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi: күчтүү сигнал."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Түзмөгүңүзгө туташты."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Ачык тармак"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Коопсуз тармак"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 6430a9889e1a..96b2dc1a27cb 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"ສັນຍານ Wi-Fi ສອງຂີດ."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi ສາມຂີດ."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"ສັນຍານ Wi-Fi ເຕັມ"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"ເຊື່ອມຕໍ່ກັບອຸປະກອນຂອງທ່ານແລ້ວ."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ເຄືອຂ່າຍເປີດ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ເຄືອຂ່າຍເຂົ້າລະຫັດ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3642a9091545..69630f436704 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Dvi „Wi-Fi“ signalo juostos."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Trys „Wi-Fi“ signalo juostos."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Stiprus „Wi-Fi“ signalas."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Prisijungta prie įrenginio."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Atviras tinklas"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Saugus tinklas"</string>
<string name="process_kernel_label" msgid="950292573930336765">"„Android“ OS"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index c3163b8efe1e..4f76ceeb2cca 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi: divas joslas"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: trīs joslas"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Pilna piekļuve Wi-Fi signālam"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Izveidots savienojums ar ierīci."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Atvērts tīkls"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Drošs tīkls"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 017fed7a5524..1c80c6502fc1 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Две црти на Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Три црти на Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Полн сигнал на Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Поврзано со уредот."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Отворена мрежа"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Заклучена мрежа"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Оперативен систем Android"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 3ef3f63d32b7..31e3c83fb32f 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"വൈഫൈ സിഗ്നൽ രണ്ട് ബാറുകൾ."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"വൈഫൈ സിഗ്നൽ മൂന്ന് ബാറുകൾ."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"വൈഫൈ മികച്ച സിഗ്‌നൽ."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"നിങ്ങളുടെ ഉപകരണത്തിലേക്ക് കണക്റ്റ് ചെയ്തു."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ഓപ്പൺ നെറ്റ്‍വര്‍ക്ക്"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"സുരക്ഷിത നെറ്റ്‍വര്‍ക്ക്"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index ccd1d4179ffb..5a636d9c8260 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi сүлжээний дохио хоёр баганатай байна."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi сүлжээний дохио гурван баганатай байна."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi-н дохио дүүрэн байна."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Таны төхөөрөмжид холбогдсон."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Нээлттэй сүлжээ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Аюулгүй сүлжээ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Андройд OS"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a34a9d327969..4d78e571b47d 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"वाय-फाय दोन बार."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"वाय-फाय तीन बार."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"वाय-फाय सिग्नल संपूर्ण आहे."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"तुमच्या डिव्हाइसशी कनेक्ट केले आहे."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"नेटवर्क उघडा"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"सुरक्षित नेटवर्क"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index b7d273409390..2ae69bdff241 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi dua bar."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi tiga bar."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Isyarat Wi-Fi penuh."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Disambungkan kepada peranti anda."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rangkaian terbuka"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rangkaian selamat"</string>
<string name="process_kernel_label" msgid="950292573930336765">"OS Android"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 0e43f6516f25..7d6f2a75ba5a 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi ၂ ဘား"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi ၃ ဘား"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi အပြည့်ရှိ"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"သင့်စက်သို့ ချိတ်ဆက်ထားသည်။"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"အများသုံး ကွန်ရက်"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"လုံခြုံသည့် ကွန်ရက်"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 43824c3ebc1a..9e550fb288e9 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi-signal med to stolper."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi-signal med tre stolper."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi-signalet er ved full styrke."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Koblet til enheten."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Åpent nettverk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sikkert nettverk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android-operativsystem"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index e879849f5f29..1f6ad5bb863c 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi दुई पट्टि।"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi तीन बारहरू।"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"पूर्ण Wi-Fi सिंग्नल।"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"तपाईंको डिभाइसमा कनेक्ट गरिएको छ।"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"खुला नेटवर्क"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"सुरक्षित नेटवर्क"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index dedacff6daf3..6a6f184f77d1 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi: twee streepjes."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi: drie streepjes."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifii-signaal is op volledige sterkte."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Verbonden met je apparaat."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Open netwerk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Beveiligd netwerk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android-besturingssysteem"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index cbd9ffd50771..980a37413f8b 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"ୱାଇ-ଫାଇର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"ୱାଇ-ଫାଇର ତିନୋଟି ବାର୍।"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"ୱାଇ-ଫାଇର ସଙ୍କେତ ସର୍ବୋଚ୍ଚ।"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"ଆପଣଙ୍କ ଡିଭାଇସ ସହ କନେକ୍ଟ କରାଯାଇଛି।"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ଖୋଲା ନେଟୱର୍କ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ସୁରକ୍ଷିତ ନେଟ୍‌ୱର୍କ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index e4814acdfb0c..dd3fa15440e1 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi ਦੋ ਬਾਰ।"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi ਤਿੰਨ ਬਾਰ।"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi ਸਿਗਨਲ ਪੂਰਾ।"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ਖੁੱਲ੍ਹਾ ਨੈੱਟਵਰਕ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index f5dc9cc7e202..f4ebd29b1276 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi: dwa paski."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: trzy paski."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi: pełna moc sygnału."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Połączono z urządzeniem."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Sieć otwarta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Sieć zabezpieczona"</string>
<string name="process_kernel_label" msgid="950292573930336765">"System operacyjny Android"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 4e96bc615c3d..bb6c7d85fe62 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Duas barras de Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Três barras de Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Sinal Wi-Fi cheio."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Conectado ao dispositivo."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rede aberta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rede segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Sistema operacional Android"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 0c4abdbefda2..6bd5c2abccda 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Duas barras de Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Três barras de Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Sinal de Wi-Fi completo."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Com ligação ao dispositivo."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rede aberta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rede segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"SO Android"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 4e96bc615c3d..bb6c7d85fe62 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Duas barras de Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Três barras de Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Sinal Wi-Fi cheio."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Conectado ao dispositivo."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rede aberta"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rede segura"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Sistema operacional Android"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 529a6c646979..f4399dc4e829 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Semnal Wi-Fi: două bare."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Semnal Wi-Fi: trei bare."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Semnal Wi-Fi: complet."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Conectată la dispozitiv."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rețea nesecurizată"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Securizează rețeaua"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Sistem de operare Android"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 87a81ee73faf..5d45e29ef9b6 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi: два деления"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: три деления"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi: надежный сигнал"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Подключено к точке доступа на вашем устройстве."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Открытая сеть"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Защищенная сеть"</string>
<string name="process_kernel_label" msgid="950292573930336765">"ОС Android"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 9015a428de38..996507d8c2f6 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi තීරු දෙකයි."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi තීරු තුනයි."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi සංඥාව පිරී ඇත."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"ඔබේ උපාංගයට සම්බන්ධයි."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"විවෘත ජාලය"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ආරක්ෂිත ජාලය"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 8c6bf4fcb887..a51acd4fb227 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Dve čiarky signálu Wi‑Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Tri čiarky signálu Wi‑Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Plný signál Wi‑Fi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Pripojené k vášmu zariadeniu."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Otvorená sieť"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Zabezpečená sieť"</string>
<string name="process_kernel_label" msgid="950292573930336765">"OS Android"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index cc19abe8be24..0d7188dcbc50 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Dve črtici signala Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Tri črtice signala Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Poln signal Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Povezava z napravo je vzpostavljena."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Odprto omrežje"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Varno omrežje"</string>
<string name="process_kernel_label" msgid="950292573930336765">"OS Android"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 43a2c4c19fd1..c2bcce79b061 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi ka dy vija."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: tre vija."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi ka sinjal të plotë."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Lidhur me pajisjen tënde"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Rrjet i hapur"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Rrjet i sigurt"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Sistemi operativ Android"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 00a98bca2383..09ff994477e1 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WiFi сигнал има две црте."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WiFi сигнал има три црте."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WiFi сигнал је најјачи."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Повезано је са уређајем."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Отворена мрежа"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Безбедна мрежа"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android ОС"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 01b462da0165..fdd9d8c17d57 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi: två staplar."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi: tre staplar."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Full signalstyrka för wifi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Ansluten till enheten."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Öppet nätverk"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Säkert nätverk"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Operativsystemet Android"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 9453e5f84c6c..bd4175289585 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Vipima mtandao viwili vya Wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Vipima mtandao vitatu vya Wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Nguvu kamili ya mtandao wa Wifi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Imeunganishwa kwenye kifaa chako."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Mtandao unaotumiwa na mtu yeyote"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Mtandao salama"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Mfumo wa Uendeshaji wa Android"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 836b4da9b8a7..fd379f0a80be 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"வைஃபை சிக்னல்: இரண்டு கோடுகள்."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"வைஃபை சிக்னல்: மூன்று கோடுகள்."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"வைஃபை சிக்னல் முழுமையாக உள்ளது."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"உங்கள் சாதனத்துடன் இணைக்கப்பட்டது."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"கடவுச்சொல் தேவைப்படாத திறந்த நெட்வொர்க்"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"கடவுச்சொல் தேவைப்படும் பாதுகாப்பான நெட்வொர்க்"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 34b826441dbc..3e9d8be3cc1b 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wifi సిగ్నల్ రెండు బార్‌లు ఉంది."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wifi సిగ్నల్ మూడు బార్‌లు ఉంది."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wifi సిగ్నల్ పూర్తిగా ఉంది."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"మీ పరికరానికి కనెక్ట్ చేయబడింది."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"ఓపెన్ నెట్‌వర్క్"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"సురక్షిత నెట్‌వర్క్"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index da3a5c5d09c6..e67f37172bd7 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"สัญญาณ Wi-Fi 2 ขีด"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"สัญญาณ Wi-Fi 3 ขีด"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"สัญญาณ Wi-Fi เต็ม"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"เชื่อมต่อกับอุปกรณ์แล้ว"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"เครือข่ายแบบเปิด"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"เครือข่ายที่ปลอดภัย"</string>
<string name="process_kernel_label" msgid="950292573930336765">"ระบบปฏิบัติการ Android"</string>
@@ -598,7 +597,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"ข้อมูลโปรไฟล์"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"ก่อนที่คุณจะสามารถสร้างโปรไฟล์ที่ถูกจำกัดได้ คุณจะต้องตั้งค่าล็อกหน้าจอเพื่อปกป้องแอปและข้อมูลส่วนตัวของคุณ"</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"ตั้งค่าล็อก"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"เปลี่ยนเป็น <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"เปลี่ยนเป็น<xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"กำลังสร้างผู้ใช้ใหม่…"</string>
<string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"กำลังสร้างผู้ใช้ชั่วคราวใหม่…"</string>
<string name="add_user_failed" msgid="4809887794313944872">"สร้างผู้ใช้ใหม่ไม่ได้"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index f6d2256c3e4e..440bbe768c05 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"May dalawang bar ang Wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"May tatlong bar ang Wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Puno ang signal ng Wifi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Nakakonekta sa iyong device."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Bukas na network"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Ligtas na network"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index acd3d00e56e6..b38012fbbd8c 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Kablosuz sinyal gücü iki çubuk."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Kablosuz sinyal gücü üç çubuk."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Kablosuz sinyal gücü tam."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Cihazınıza bağlandı."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Açık ağ"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Güvenli ağ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index dd5898adc3c5..4f0854790e92 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Дві смужки сигналу Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Три смужки сигналу Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Максимальний сигнал Wi-Fi."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Підключено до пристрою."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Відкрита мережа"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Захищена мережа"</string>
<string name="process_kernel_label" msgid="950292573930336765">"ОС Android"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 182bd0496527..ce67d1516273 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"‏Wifi دو بارز۔"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"‏Wifi تین بارز۔"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"‏Wifi سگنل پورا ہے۔"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"آپ کے آلے سے منسلک ہے۔"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"اوپن نیٹ ورک"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"محفوظ نیٹ ورک"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index b831a4b40bb9..77da981b29a9 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi: ikkita ustun"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi: uchta ustun"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi: signal to‘liq"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Qurilmaga ulandi."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Ochiq tarmoq"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Xavfsiz tarmoq"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 3e94593351a2..bf510f6522f3 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Tín hiệu Wi-Fi hai vạch."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Tín hiệu Wi-Fi ba vạch."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Tín hiệu Wi-Fi đủ."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Đã kết nối với thiết bị của bạn."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Mạng mở"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Mạng bảo mật"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Hệ điều hành Android"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 53389c790974..8e3145ace05a 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"WLAN 信号强度为两格。"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"WLAN 信号强度为三格。"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"WLAN 信号满格。"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"已连接到您的设备。"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"开放网络"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"安全网络"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android 操作系统"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index daedba67c378..aa9f21f28b91 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi 訊號兩格。"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi 訊號三格。"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi 訊號滿格。"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"已連接裝置。"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"開放式網絡"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"安全網絡"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android 作業系統"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 94ebd9852e85..3c65a4d7d5ee 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Wi-Fi 訊號強度兩格。"</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Wi-Fi 訊號強度三格。"</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Wi-Fi 訊號強度滿格。"</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"已連上裝置。"</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"開放式網路"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"安全網路"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android 作業系統"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 92a4b81e80f7..08b04cc4b1bf 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -157,8 +157,7 @@
<string name="accessibility_wifi_two_bars" msgid="687800024970972270">"Amabha amabili we-Wifi."</string>
<string name="accessibility_wifi_three_bars" msgid="779895671061950234">"Amabha amathathu we-Wifi."</string>
<string name="accessibility_wifi_signal_full" msgid="7165262794551355617">"Isiginali ye-Wifi igcwele."</string>
- <!-- no translation found for accessibility_wifi_other_device (2815627624555795918) -->
- <skip />
+ <string name="accessibility_wifi_other_device" msgid="2815627624555795918">"Ixhume kudivayisi yakho."</string>
<string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Vula inethiwekhi"</string>
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Inethiwekhi evikelekile"</string>
<string name="process_kernel_label" msgid="950292573930336765">"I-Android OS"</string>
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index b03c43cbdee5..4b4caf5a620e 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -52,7 +52,7 @@ android_test {
"flag-junit",
"mockito-target-minus-junit4",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
"SettingsLibDeviceStateRotationLock",
"SettingsLibSettingsSpinner",
"SettingsLibUsageProgressBarPreference",
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index dd9cb9cf7abe..2d875cf7244d 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -96,6 +96,6 @@ java_library {
libs: [
"Robolectric_all-target_upstream",
"mockito-robolectric-prebuilt",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp
index 19ab1c69e98c..6d6e2ff8e59b 100644
--- a/packages/SettingsLib/tests/unit/Android.bp
+++ b/packages/SettingsLib/tests/unit/Android.bp
@@ -31,6 +31,6 @@ android_test {
"SettingsLib",
"androidx.test.ext.junit",
"androidx.test.runner",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index 92ebe09fa441..f4ca260d4d89 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -64,7 +64,7 @@ android_test {
"SettingsLibDeviceStateRotationLock",
"SettingsLibDisplayUtils",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.base",
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 91d2d1bb58e5..96f3290d1c76 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -218,6 +218,7 @@ public class SecureSettings {
Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE,
Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED,
Settings.Secure.NOTIFICATION_BUBBLES,
Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
@@ -244,6 +245,9 @@ public class SecureSettings {
Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
Settings.Secure.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED,
Settings.Secure.SEARCH_LONG_PRESS_HOME_ENABLED,
- Settings.Secure.HUB_MODE_TUTORIAL_STATE
+ Settings.Secure.HUB_MODE_TUTORIAL_STATE,
+ Settings.Secure.STYLUS_BUTTONS_ENABLED,
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 248c60cb4fe9..f5d9475fb049 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -101,5 +101,7 @@ public class SystemSettings {
Settings.System.CAMERA_FLASH_NOTIFICATION,
Settings.System.SCREEN_FLASH_NOTIFICATION,
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
+ Settings.System.PEAK_REFRESH_RATE,
+ Settings.System.MIN_REFRESH_RATE,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index bec144766438..f48600db8735 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -308,6 +308,10 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE,
+ new InclusiveIntegerRangeValidator(
+ Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE_NONE,
+ Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE_ALL));
VALIDATORS.put(
Secure.ACCESSIBILITY_BUTTON_TARGETS,
ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
@@ -390,5 +394,9 @@ public class SecureSettingsValidators {
BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DND_CONFIGS_MIGRATED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.HUB_MODE_TUTORIAL_STATE, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.STYLUS_BUTTONS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.STYLUS_HANDWRITING_ENABLED,
+ new DiscreteValueValidator(new String[] {"-1", "0", "1"}));
+ VALIDATORS.put(Secure.DEFAULT_NOTE_TASK_PROFILE, NON_NEGATIVE_INTEGER_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 29f27f74bca4..410269f240e0 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -21,6 +21,7 @@ import static android.provider.settings.validators.SettingsValidators.ANY_STRING
import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.COMPONENT_NAME_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_FLOAT_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.URI_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.VIBRATION_INTENSITY_VALIDATOR;
@@ -236,5 +237,7 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.CAMERA_FLASH_NOTIFICATION, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SCREEN_FLASH_NOTIFICATION, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SCREEN_FLASH_NOTIFICATION_COLOR, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(System.PEAK_REFRESH_RATE, NON_NEGATIVE_FLOAT_VALIDATOR);
+ VALIDATORS.put(System.MIN_REFRESH_RATE, NON_NEGATIVE_FLOAT_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 3c8d4bca2394..f06b31c4e965 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1850,6 +1850,10 @@ class SettingsProtoDumpUtil {
SecureSettingsProto.Accessibility
.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED);
dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE,
+ SecureSettingsProto.Accessibility
+ .ACCESSIBILITY_MAGNIFICATION_GESTURE);
+ dumpSetting(s, p,
Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
SecureSettingsProto.Accessibility.HEARING_AID_RINGTONE_ROUTING);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 34d3d446530b..46cd725ad582 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -121,6 +121,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.display.RefreshRateSettingsUtils;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FrameworkStatsLog;
import com.android.providers.settings.SettingsState.Setting;
@@ -3878,7 +3879,7 @@ public class SettingsProvider extends ContentProvider {
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 222;
+ private static final int SETTINGS_VERSION = 223;
private final int mUserId;
@@ -5935,10 +5936,6 @@ public class SettingsProvider extends ContentProvider {
if (currentVersion == 218) {
// Version 219: Removed
- // TODO(b/211737588): Back up the Smooth Display setting
- // Future upgrades to the `peak_refresh_rate` and `min_refresh_rate` settings
- // should account for the database in a non-upgraded and upgraded (change id:
- // Ib2cb2dd100f06f5452083b7606109a486e795a0e) state.
currentVersion = 219;
}
@@ -6004,6 +6001,56 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 222;
}
+ // Version 222: Set peak refresh rate and min refresh rate to infinity if it's
+ // meant to be the highest possible refresh rate. This is needed so that we can
+ // back up and restore those settings on other devices. Other devices might have
+ // different highest possible refresh rates.
+ if (currentVersion == 222) {
+ final SettingsState systemSettings = getSystemSettingsLocked(userId);
+ final Setting peakRefreshRateSetting =
+ systemSettings.getSettingLocked(Settings.System.PEAK_REFRESH_RATE);
+ final Setting minRefreshRateSetting =
+ systemSettings.getSettingLocked(Settings.System.MIN_REFRESH_RATE);
+ float highestRefreshRate = RefreshRateSettingsUtils
+ .findHighestRefreshRateForDefaultDisplay(getContext());
+
+ if (!peakRefreshRateSetting.isNull()) {
+ try {
+ float peakRefreshRate =
+ Float.parseFloat(peakRefreshRateSetting.getValue());
+ if (Math.round(peakRefreshRate) == Math.round(highestRefreshRate)) {
+ systemSettings.insertSettingLocked(
+ Settings.System.PEAK_REFRESH_RATE,
+ String.valueOf(Float.POSITIVE_INFINITY),
+ /* tag= */ null,
+ /* makeDefault= */ false,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ } catch (NumberFormatException e) {
+ // Do nothing. Leave the value as is.
+ }
+ }
+
+ if (!minRefreshRateSetting.isNull()) {
+ try {
+ float minRefreshRate =
+ Float.parseFloat(minRefreshRateSetting.getValue());
+ if (Math.round(minRefreshRate) == Math.round(highestRefreshRate)) {
+ systemSettings.insertSettingLocked(
+ Settings.System.MIN_REFRESH_RATE,
+ String.valueOf(Float.POSITIVE_INFINITY),
+ /* tag= */ null,
+ /* makeDefault= */ false,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ } catch (NumberFormatException e) {
+ // Do nothing. Leave the value as is.
+ }
+ }
+
+ currentVersion = 223;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 9ddc976af7e2..7bca944033d9 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -98,8 +98,6 @@ public class SettingsBackupTest {
Settings.System.VOLUME_VOICE, // deprecated since API 2?
Settings.System.WHEN_TO_MAKE_WIFI_CALLS, // bug?
Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, // used for debugging only
- Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities
- Settings.System.PEAK_REFRESH_RATE, // depends on hardware capabilities
Settings.System.SCREEN_BRIGHTNESS_FLOAT,
Settings.System.SCREEN_BRIGHTNESS_FOR_ALS,
Settings.System.WEAR_ACCESSIBILITY_GESTURE_ENABLED_DURING_OOBE,
@@ -735,7 +733,6 @@ public class SettingsBackupTest {
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
Settings.Secure.CONTENT_CAPTURE_ENABLED,
Settings.Secure.DEFAULT_INPUT_METHOD,
- Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
Settings.Secure.DEVICE_PAIRED,
Settings.Secure.DIALER_DEFAULT_APPLICATION,
Settings.Secure.DISABLED_PRINT_SERVICES,
@@ -805,8 +802,6 @@ public class SettingsBackupTest {
Settings.Secure.SLEEP_TIMEOUT,
Settings.Secure.SMS_DEFAULT_APPLICATION,
Settings.Secure.SPELL_CHECKER_ENABLED, // Intentionally removed in Q
- Settings.Secure.STYLUS_BUTTONS_ENABLED,
- Settings.Secure.STYLUS_HANDWRITING_ENABLED,
Settings.Secure.TRUST_AGENTS_INITIALIZED,
Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED,
Settings.Secure.TV_APP_USES_NON_SYSTEM_INPUTS,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 3c5785275919..e40fcb2a633b 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -466,7 +466,7 @@ android_library {
"hamcrest-library",
"androidx.test.rules",
"testables",
- "truth-prebuilt",
+ "truth",
"monet",
"libmonet",
"dagger2",
@@ -583,7 +583,7 @@ android_robolectric_test {
"android.test.runner",
"android.test.base",
"android.test.mock",
- "truth-prebuilt",
+ "truth",
],
upstream: true,
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
index 538ecb3d438d..3fc351c32ec1 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
@@ -32,7 +32,7 @@ android_test {
"androidx.test.ext.junit",
"compatibility-device-util-axt",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
srcs: [
"src/**/*.java",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 0f2e4bace46d..4aac27932924 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -39,6 +39,7 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.view.animation.Interpolator
import android.view.animation.PathInterpolator
+import androidx.annotation.AnyThread
import androidx.annotation.BinderThread
import androidx.annotation.UiThread
import com.android.app.animation.Interpolators
@@ -149,6 +150,10 @@ class ActivityLaunchAnimator(
override fun onLaunchAnimationProgress(linearProgress: Float) {
listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
}
+
+ override fun onLaunchAnimationCancelled() {
+ listeners.forEach { it.onLaunchAnimationCancelled() }
+ }
}
/**
@@ -191,6 +196,7 @@ class ActivityLaunchAnimator(
"ActivityLaunchAnimator.callback must be set before using this animator"
)
val runner = createRunner(controller)
+ val runnerDelegate = runner.delegate!!
val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen
// Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the
@@ -241,12 +247,15 @@ class ActivityLaunchAnimator(
// If we expect an animation, post a timeout to cancel it in case the remote animation is
// never started.
if (willAnimate) {
- runner.delegate.postTimeout()
+ runnerDelegate.postTimeout()
// Hide the keyguard using the launch animation instead of the default unlock animation.
if (hideKeyguardWithAnimation) {
callback.hideKeyguardWithAnimation(runner)
}
+ } else {
+ // We need to make sure delegate references are dropped to avoid memory leaks.
+ runner.dispose()
}
}
@@ -344,6 +353,13 @@ class ActivityLaunchAnimator(
*/
fun onLaunchAnimationEnd() {}
+ /**
+ * The animation was cancelled. Note that [onLaunchAnimationEnd] will still be called after
+ * this if the animation was already started, i.e. if [onLaunchAnimationStart] was called
+ * before the cancellation.
+ */
+ fun onLaunchAnimationCancelled() {}
+
/** Called when an activity launch animation made progress. */
fun onLaunchAnimationProgress(linearProgress: Float) {}
}
@@ -426,6 +442,39 @@ class ActivityLaunchAnimator(
fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {}
}
+ /**
+ * Invokes [onAnimationComplete] when animation is either cancelled or completed. Delegates all
+ * events to the passed [delegate].
+ */
+ @VisibleForTesting
+ inner class DelegatingAnimationCompletionListener(
+ private val delegate: Listener?,
+ private val onAnimationComplete: () -> Unit
+ ) : Listener {
+ var cancelled = false
+
+ override fun onLaunchAnimationStart() {
+ delegate?.onLaunchAnimationStart()
+ }
+
+ override fun onLaunchAnimationProgress(linearProgress: Float) {
+ delegate?.onLaunchAnimationProgress(linearProgress)
+ }
+
+ override fun onLaunchAnimationEnd() {
+ delegate?.onLaunchAnimationEnd()
+ if (!cancelled) {
+ onAnimationComplete.invoke()
+ }
+ }
+
+ override fun onLaunchAnimationCancelled() {
+ cancelled = true
+ delegate?.onLaunchAnimationCancelled()
+ onAnimationComplete.invoke()
+ }
+ }
+
@VisibleForTesting
inner class Runner(
controller: Controller,
@@ -436,11 +485,21 @@ class ActivityLaunchAnimator(
listener: Listener? = null
) : IRemoteAnimationRunner.Stub() {
private val context = controller.launchContainer.context
- internal val delegate: AnimationDelegate
+
+ // This is being passed across IPC boundaries and cycles (through PendingIntentRecords,
+ // etc.) are possible. So we need to make sure we drop any references that might
+ // transitively cause leaks when we're done with animation.
+ @VisibleForTesting var delegate: AnimationDelegate?
init {
delegate =
- AnimationDelegate(controller, callback, listener, launchAnimator, disableWmTimeout)
+ AnimationDelegate(
+ controller,
+ callback,
+ DelegatingAnimationCompletionListener(listener, this::dispose),
+ launchAnimator,
+ disableWmTimeout
+ )
}
@BinderThread
@@ -451,14 +510,33 @@ class ActivityLaunchAnimator(
nonApps: Array<out RemoteAnimationTarget>?,
finishedCallback: IRemoteAnimationFinishedCallback?
) {
+ val delegate = delegate
context.mainExecutor.execute {
- delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback)
+ if (delegate == null) {
+ Log.i(TAG, "onAnimationStart called after completion")
+ // Animation started too late and timed out already. We need to still
+ // signal back that we're done with it.
+ finishedCallback?.onAnimationFinished()
+ } else {
+ delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback)
+ }
}
}
@BinderThread
override fun onAnimationCancelled() {
- context.mainExecutor.execute { delegate.onAnimationCancelled() }
+ val delegate = delegate
+ context.mainExecutor.execute {
+ delegate ?: Log.wtf(TAG, "onAnimationCancelled called after completion")
+ delegate?.onAnimationCancelled()
+ }
+ }
+
+ @AnyThread
+ fun dispose() {
+ // Drop references to animation controller once we're done with the animation
+ // to avoid leaking.
+ context.mainExecutor.execute { delegate = null }
}
}
@@ -584,6 +662,7 @@ class ActivityLaunchAnimator(
)
}
controller.onLaunchAnimationCancelled()
+ listener?.onLaunchAnimationCancelled()
return
}
@@ -821,6 +900,7 @@ class ActivityLaunchAnimator(
Log.d(TAG, "Calling controller.onLaunchAnimationCancelled() [animation timed out]")
}
controller.onLaunchAnimationCancelled()
+ listener?.onLaunchAnimationCancelled()
}
@UiThread
@@ -842,6 +922,7 @@ class ActivityLaunchAnimator(
)
}
controller.onLaunchAnimationCancelled()
+ listener?.onLaunchAnimationCancelled()
}
private fun IRemoteAnimationFinishedCallback.invoke() {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 39173d98538f..58c7bdbf3d71 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -130,10 +130,23 @@ interface SceneScope {
sealed interface UserAction
/** The user navigated back, either using a gesture or by triggering a KEYCODE_BACK event. */
-object Back : UserAction
+data object Back : UserAction
/** The user swiped on the container. */
-enum class Swipe : UserAction {
+data class Swipe(
+ val direction: SwipeDirection,
+ val pointerCount: Int = 1,
+ val fromEdge: Edge? = null,
+) : UserAction {
+ companion object {
+ val Left = Swipe(SwipeDirection.Left)
+ val Up = Swipe(SwipeDirection.Up)
+ val Right = Swipe(SwipeDirection.Right)
+ val Down = Swipe(SwipeDirection.Down)
+ }
+}
+
+enum class SwipeDirection {
Up,
Down,
Left,
diff --git a/packages/SystemUI/compose/core/tests/Android.bp b/packages/SystemUI/compose/core/tests/Android.bp
index 52c63854f62f..8e9c5864ce70 100644
--- a/packages/SystemUI/compose/core/tests/Android.bp
+++ b/packages/SystemUI/compose/core/tests/Android.bp
@@ -43,7 +43,7 @@ android_test {
"androidx.compose.ui_ui-test-junit4",
"androidx.compose.ui_ui-test-manifest",
- "truth-prebuilt",
+ "truth",
],
kotlincflags: ["-Xjvm-default=all"],
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index c3a3752db374..ee310ab41373 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -36,13 +36,14 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
import com.android.compose.animation.scene.SceneScope
-import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.qualifiers.KeyguardRootView
import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
+import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.Edge
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
@@ -99,7 +100,9 @@ constructor(
return buildMap {
up?.let { this[UserAction.Swipe(Direction.UP)] = SceneModel(up) }
left?.let { this[UserAction.Swipe(Direction.LEFT)] = SceneModel(left) }
- this[UserAction.Swipe(Direction.DOWN)] = SceneModel(SceneKey.Shade)
+ this[UserAction.Swipe(fromEdge = Edge.TOP, direction = Direction.DOWN)] =
+ SceneModel(SceneKey.QuickSettings)
+ this[UserAction.Swipe(direction = Direction.DOWN)] = SceneModel(SceneKey.Shade)
}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 2ee461fca042..f35ea8373db7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -22,6 +22,7 @@ import androidx.compose.ui.Modifier
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.Edge
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
@@ -41,7 +42,12 @@ class GoneScene @Inject constructor() : ComposableScene {
override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
- UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade),
+ UserAction.Swipe(
+ pointerCount = 2,
+ fromEdge = Edge.TOP,
+ direction = Direction.DOWN,
+ ) to SceneModel(SceneKey.QuickSettings),
+ UserAction.Swipe(direction = Direction.DOWN) to SceneModel(SceneKey.Shade),
)
)
.asStateFlow()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 6359ce60ae70..0da562bcb3bb 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -35,15 +35,18 @@ import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.motionEventSpy
import androidx.compose.ui.input.pointer.pointerInput
import com.android.compose.animation.scene.Back
+import com.android.compose.animation.scene.Edge as SceneTransitionEdge
import com.android.compose.animation.scene.ObservableTransitionState as SceneTransitionObservableTransitionState
import com.android.compose.animation.scene.SceneKey as SceneTransitionSceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.Swipe
+import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction as SceneTransitionUserAction
import com.android.compose.animation.scene.observableTransitionState
import com.android.systemui.ribbon.ui.composable.BottomRightCornerRibbon
import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.Edge
import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
@@ -181,12 +184,24 @@ private fun SceneTransitionSceneKey.toModel(): SceneModel {
private fun UserAction.toTransitionUserAction(): SceneTransitionUserAction {
return when (this) {
is UserAction.Swipe ->
- when (this.direction) {
- Direction.LEFT -> Swipe.Left
- Direction.UP -> Swipe.Up
- Direction.RIGHT -> Swipe.Right
- Direction.DOWN -> Swipe.Down
- }
+ Swipe(
+ pointerCount = pointerCount,
+ fromEdge =
+ when (this.fromEdge) {
+ null -> null
+ Edge.LEFT -> SceneTransitionEdge.Left
+ Edge.TOP -> SceneTransitionEdge.Top
+ Edge.RIGHT -> SceneTransitionEdge.Right
+ Edge.BOTTOM -> SceneTransitionEdge.Bottom
+ },
+ direction =
+ when (this.direction) {
+ Direction.LEFT -> SwipeDirection.Left
+ Direction.UP -> SwipeDirection.Up
+ Direction.RIGHT -> SwipeDirection.Right
+ Direction.DOWN -> SwipeDirection.Down
+ }
+ )
is UserAction.Back -> Back
}
}
diff --git a/packages/SystemUI/customization/res/values-af/strings.xml b/packages/SystemUI/customization/res/values-af/strings.xml
new file mode 100644
index 000000000000..4c2c6275e6d8
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-af/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Verstek vir digitaal"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-am/strings.xml b/packages/SystemUI/customization/res/values-am/strings.xml
new file mode 100644
index 000000000000..847d7a541c95
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-am/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ዲጂታል ነባሪ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ar/strings.xml b/packages/SystemUI/customization/res/values-ar/strings.xml
new file mode 100644
index 000000000000..57d1612b337d
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ar/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"رقمية تلقائية"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-as/strings.xml b/packages/SystemUI/customization/res/values-as/strings.xml
new file mode 100644
index 000000000000..2f3b64b9ceb6
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-as/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ডিজিটেল ডিফ’ল্ট"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-az/strings.xml b/packages/SystemUI/customization/res/values-az/strings.xml
new file mode 100644
index 000000000000..eb52f95a4525
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-az/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Rəqəmsal defolt"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 000000000000..90e6678bdcd6
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalni podrazumevani"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-be/strings.xml b/packages/SystemUI/customization/res/values-be/strings.xml
new file mode 100644
index 000000000000..f327da2a40a4
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-be/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"электронны, стандартны шрыфт"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-bg/strings.xml b/packages/SystemUI/customization/res/values-bg/strings.xml
new file mode 100644
index 000000000000..6e3754a62a29
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-bg/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Стандартно дигитално"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-bn/strings.xml b/packages/SystemUI/customization/res/values-bn/strings.xml
new file mode 100644
index 000000000000..adf1256b6c82
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-bn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ডিজিটাল ডিফল্ট"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-bs/strings.xml b/packages/SystemUI/customization/res/values-bs/strings.xml
new file mode 100644
index 000000000000..8de04ab06503
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-bs/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalno zadano"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ca/strings.xml b/packages/SystemUI/customization/res/values-ca/strings.xml
new file mode 100644
index 000000000000..967bb3f6d2f5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ca/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital predeterminat"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-cs/strings.xml b/packages/SystemUI/customization/res/values-cs/strings.xml
new file mode 100644
index 000000000000..45da4d759ad4
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-cs/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitální výchozí"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-da/strings.xml b/packages/SystemUI/customization/res/values-da/strings.xml
new file mode 100644
index 000000000000..3ffaa8b167c8
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-da/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Standard (digital)"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-de/strings.xml b/packages/SystemUI/customization/res/values-de/strings.xml
new file mode 100644
index 000000000000..64f95e05b245
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-de/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital (Standard)"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-el/strings.xml b/packages/SystemUI/customization/res/values-el/strings.xml
new file mode 100644
index 000000000000..57134b566d08
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-el/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Ψηφιακή προεπιλογή"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rAU/strings.xml b/packages/SystemUI/customization/res/values-en-rAU/strings.xml
new file mode 100644
index 000000000000..a6110d5d5b09
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rCA/strings.xml b/packages/SystemUI/customization/res/values-en-rCA/strings.xml
new file mode 100644
index 000000000000..79919c07d189
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for clock_default_description (5309401440896597541) -->
+ <skip />
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rGB/strings.xml b/packages/SystemUI/customization/res/values-en-rGB/strings.xml
new file mode 100644
index 000000000000..a6110d5d5b09
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rIN/strings.xml b/packages/SystemUI/customization/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000000..a6110d5d5b09
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rXC/strings.xml b/packages/SystemUI/customization/res/values-en-rXC/strings.xml
new file mode 100644
index 000000000000..7c540dab2cfe
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rXC/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎Digital default‎‏‎‎‏‎"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-es-rUS/strings.xml b/packages/SystemUI/customization/res/values-es-rUS/strings.xml
new file mode 100644
index 000000000000..59be786849e6
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-es-rUS/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Configuración predeterminada digital"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-es/strings.xml b/packages/SystemUI/customization/res/values-es/strings.xml
new file mode 100644
index 000000000000..03ef0e5a8cea
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-es/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital predeterminada"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-et/strings.xml b/packages/SystemUI/customization/res/values-et/strings.xml
new file mode 100644
index 000000000000..fec793e99619
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-et/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitaalne vaikimisi"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-eu/strings.xml b/packages/SystemUI/customization/res/values-eu/strings.xml
new file mode 100644
index 000000000000..a70c8085ccf0
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-eu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital lehenetsia"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fa/strings.xml b/packages/SystemUI/customization/res/values-fa/strings.xml
new file mode 100644
index 000000000000..6426d5112528
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"دیجیتال پیش‌فرض"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fi/strings.xml b/packages/SystemUI/customization/res/values-fi/strings.xml
new file mode 100644
index 000000000000..9b19373a3765
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitaalinen (oletus)"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fr-rCA/strings.xml b/packages/SystemUI/customization/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000000..bbd1208b1922
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fr-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Numérique, par défaut"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fr/strings.xml b/packages/SystemUI/customization/res/values-fr/strings.xml
new file mode 100644
index 000000000000..5579a427fe71
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Numérique par défaut"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-gl/strings.xml b/packages/SystemUI/customization/res/values-gl/strings.xml
new file mode 100644
index 000000000000..2da93c6f1e34
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-gl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Predeterminada dixital"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-gu/strings.xml b/packages/SystemUI/customization/res/values-gu/strings.xml
new file mode 100644
index 000000000000..c578a2e2d322
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-gu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ડિજિટલ ડિફૉલ્ટ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hi/strings.xml b/packages/SystemUI/customization/res/values-hi/strings.xml
new file mode 100644
index 000000000000..6080f802af04
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डिफ़ॉल्ट"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hr/strings.xml b/packages/SystemUI/customization/res/values-hr/strings.xml
new file mode 100644
index 000000000000..0a1440fb683b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalni zadani"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hu/strings.xml b/packages/SystemUI/customization/res/values-hu/strings.xml
new file mode 100644
index 000000000000..32618a869a1f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitális, alapértelmezett"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hy/strings.xml b/packages/SystemUI/customization/res/values-hy/strings.xml
new file mode 100644
index 000000000000..d45afbf256ab
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hy/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Թվային, կանխադրված"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-in/strings.xml b/packages/SystemUI/customization/res/values-in/strings.xml
new file mode 100644
index 000000000000..a6110d5d5b09
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-in/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-is/strings.xml b/packages/SystemUI/customization/res/values-is/strings.xml
new file mode 100644
index 000000000000..5a370d614f0f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-is/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Stafræn, sjálfgefið"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-it/strings.xml b/packages/SystemUI/customization/res/values-it/strings.xml
new file mode 100644
index 000000000000..2a5087d30669
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-it/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitale - predefinito"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-iw/strings.xml b/packages/SystemUI/customization/res/values-iw/strings.xml
new file mode 100644
index 000000000000..ddd28f21ad99
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-iw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"דיגיטלי ברירת מחדל"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ja/strings.xml b/packages/SystemUI/customization/res/values-ja/strings.xml
new file mode 100644
index 000000000000..744604a17efa
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ja/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"デジタル デフォルト"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ka/strings.xml b/packages/SystemUI/customization/res/values-ka/strings.xml
new file mode 100644
index 000000000000..88ba1dfc0976
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ka/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ციფრული ნაგულისხმევი"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-kk/strings.xml b/packages/SystemUI/customization/res/values-kk/strings.xml
new file mode 100644
index 000000000000..9ee6522c49ce
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-kk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Цифрлық әдепкі"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-km/strings.xml b/packages/SystemUI/customization/res/values-km/strings.xml
new file mode 100644
index 000000000000..bbc438a69bcd
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-km/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"លំនាំដើមឌីជីថល"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-kn/strings.xml b/packages/SystemUI/customization/res/values-kn/strings.xml
new file mode 100644
index 000000000000..e67319d4021b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-kn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ಡಿಜಿಟಲ್ ಡೀಫಾಲ್ಟ್"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ko/strings.xml b/packages/SystemUI/customization/res/values-ko/strings.xml
new file mode 100644
index 000000000000..fa9103b01e66
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ko/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"디지털 기본"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ky/strings.xml b/packages/SystemUI/customization/res/values-ky/strings.xml
new file mode 100644
index 000000000000..76cc5e211a40
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ky/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Демейки санариптик"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-lo/strings.xml b/packages/SystemUI/customization/res/values-lo/strings.xml
new file mode 100644
index 000000000000..28f50008bd73
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-lo/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ດິຈິຕອນຕາມຄ່າເລີ່ມຕົ້ນ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-lt/strings.xml b/packages/SystemUI/customization/res/values-lt/strings.xml
new file mode 100644
index 000000000000..2fe731547762
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-lt/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Skaitmeninis numatytasis"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-lv/strings.xml b/packages/SystemUI/customization/res/values-lv/strings.xml
new file mode 100644
index 000000000000..e0b904a8a1c9
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-lv/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitālais pulkstenis — noklusējums"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-mk/strings.xml b/packages/SystemUI/customization/res/values-mk/strings.xml
new file mode 100644
index 000000000000..9b95a6e32b31
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-mk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Дигитален стандарден приказ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ml/strings.xml b/packages/SystemUI/customization/res/values-ml/strings.xml
new file mode 100644
index 000000000000..7f6be8a59904
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ml/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ഡിജിറ്റൽ ഡിഫോൾട്ട്"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-mn/strings.xml b/packages/SystemUI/customization/res/values-mn/strings.xml
new file mode 100644
index 000000000000..38369b6f527d
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-mn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Дижитал өгөгдмөл"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-mr/strings.xml b/packages/SystemUI/customization/res/values-mr/strings.xml
new file mode 100644
index 000000000000..821ff100ab13
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-mr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डीफॉल्टसह क्लॉक फेस"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ms/strings.xml b/packages/SystemUI/customization/res/values-ms/strings.xml
new file mode 100644
index 000000000000..2f61b47a2324
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ms/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital lalai"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-my/strings.xml b/packages/SystemUI/customization/res/values-my/strings.xml
new file mode 100644
index 000000000000..3d137ebc3abb
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-my/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ဒစ်ဂျစ်တယ်နာရီ မူရင်း"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-nb/strings.xml b/packages/SystemUI/customization/res/values-nb/strings.xml
new file mode 100644
index 000000000000..6eb4373c448c
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-nb/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital – standard"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ne/strings.xml b/packages/SystemUI/customization/res/values-ne/strings.xml
new file mode 100644
index 000000000000..c5b087744a18
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ne/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डिफल्ट"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-nl/strings.xml b/packages/SystemUI/customization/res/values-nl/strings.xml
new file mode 100644
index 000000000000..4f46ab8b2ba5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-nl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Standaard digitaal"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-or/strings.xml b/packages/SystemUI/customization/res/values-or/strings.xml
new file mode 100644
index 000000000000..a74017f6b689
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-or/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ଡିଜିଟାଲ ଡିଫଲ୍ଟ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pa/strings.xml b/packages/SystemUI/customization/res/values-pa/strings.xml
new file mode 100644
index 000000000000..a77661a8f56b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ਡਿਜੀਟਲ ਡਿਫਾਲਟ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pl/strings.xml b/packages/SystemUI/customization/res/values-pl/strings.xml
new file mode 100644
index 000000000000..6f5b6f280dd1
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Cyfrowa domyślna"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pt-rPT/strings.xml b/packages/SystemUI/customization/res/values-pt-rPT/strings.xml
new file mode 100644
index 000000000000..c6c3cc046965
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pt-rPT/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Predefinição digital"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pt/strings.xml b/packages/SystemUI/customization/res/values-pt/strings.xml
new file mode 100644
index 000000000000..bbe435543211
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pt/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital padrão"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ro/strings.xml b/packages/SystemUI/customization/res/values-ro/strings.xml
new file mode 100644
index 000000000000..ef163e96f79f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ro/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Implicit digital"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ru/strings.xml b/packages/SystemUI/customization/res/values-ru/strings.xml
new file mode 100644
index 000000000000..5ee928e0fa37
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ru/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Цифровые часы, стандартный"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-si/strings.xml b/packages/SystemUI/customization/res/values-si/strings.xml
new file mode 100644
index 000000000000..caf9610e921e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-si/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ඩිජිටල් පෙරනිමිය"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sk/strings.xml b/packages/SystemUI/customization/res/values-sk/strings.xml
new file mode 100644
index 000000000000..1843f971d251
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitálne predvolené"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sl/strings.xml b/packages/SystemUI/customization/res/values-sl/strings.xml
new file mode 100644
index 000000000000..12df66f571d3
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalna (privzeta)"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sq/strings.xml b/packages/SystemUI/customization/res/values-sq/strings.xml
new file mode 100644
index 000000000000..1fc9f252175f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sq/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Dixhitale e parazgjedhur"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sr/strings.xml b/packages/SystemUI/customization/res/values-sr/strings.xml
new file mode 100644
index 000000000000..6b127c9f79e5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Дигитални подразумевани"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sv/strings.xml b/packages/SystemUI/customization/res/values-sv/strings.xml
new file mode 100644
index 000000000000..84ad25c96655
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sv/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital standard"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sw/strings.xml b/packages/SystemUI/customization/res/values-sw/strings.xml
new file mode 100644
index 000000000000..e2ec3de573a8
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Dijitali chaguomsingi"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ta/strings.xml b/packages/SystemUI/customization/res/values-ta/strings.xml
new file mode 100644
index 000000000000..f4eea07b0aa5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ta/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"டிஜிட்டல் இயல்பு"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-te/strings.xml b/packages/SystemUI/customization/res/values-te/strings.xml
new file mode 100644
index 000000000000..c7c77d527e7f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-te/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"డిజిటల్ ఆటోమేటిక్ సెట్టింగ్"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-th/strings.xml b/packages/SystemUI/customization/res/values-th/strings.xml
new file mode 100644
index 000000000000..61d880eb1ad9
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-th/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ดิจิทัลแบบเริ่มต้น"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-tl/strings.xml b/packages/SystemUI/customization/res/values-tl/strings.xml
new file mode 100644
index 000000000000..a3484a7b6d2a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital na default"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-tr/strings.xml b/packages/SystemUI/customization/res/values-tr/strings.xml
new file mode 100644
index 000000000000..a90e9852ef2f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-tr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Dijital varsayılan"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-uk/strings.xml b/packages/SystemUI/customization/res/values-uk/strings.xml
new file mode 100644
index 000000000000..ee9b77b905a2
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-uk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Цифровий, стандартний"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ur/strings.xml b/packages/SystemUI/customization/res/values-ur/strings.xml
new file mode 100644
index 000000000000..06a6a7cd01fd
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ur/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ڈیجیٹل ڈیفالٹ"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-uz/strings.xml b/packages/SystemUI/customization/res/values-uz/strings.xml
new file mode 100644
index 000000000000..6b31b048b4a1
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-uz/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Raqamli soat, standart"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-vi/strings.xml b/packages/SystemUI/customization/res/values-vi/strings.xml
new file mode 100644
index 000000000000..830b6e2b16a1
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-vi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Mặt số mặc định"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zh-rCN/strings.xml b/packages/SystemUI/customization/res/values-zh-rCN/strings.xml
new file mode 100644
index 000000000000..747567e9fb65
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"默认数字"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zh-rHK/strings.xml b/packages/SystemUI/customization/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000000..c19cc68ff150
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zh-rHK/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"數碼時鐘 (預設)"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zh-rTW/strings.xml b/packages/SystemUI/customization/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000000..6fcd313a291d
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zh-rTW/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"數位預設"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zu/strings.xml b/packages/SystemUI/customization/res/values-zu/strings.xml
new file mode 100644
index 000000000000..c87c250ae1b9
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Okuzenzakalelayo kwedijithali"</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values/strings.xml b/packages/SystemUI/customization/res/values/strings.xml
new file mode 100644
index 000000000000..897c842b6d4b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- default clock face name [CHAR LIMIT=NONE]-->
+ <string name="clock_default_name">Default</string>
+
+ <!-- default clock face description [CHAR LIMIT=NONE]-->
+ <string name="clock_default_description">Digital default</string>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index b28920c590c5..b076b2cacf08 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -65,7 +65,13 @@ class DefaultClockController(
protected var onSecondaryDisplay: Boolean = false
override val events: DefaultClockEvents
- override val config = ClockConfig(DEFAULT_CLOCK_ID)
+ override val config: ClockConfig by lazy {
+ ClockConfig(
+ DEFAULT_CLOCK_ID,
+ resources.getString(R.string.clock_default_name),
+ resources.getString(R.string.clock_default_description)
+ )
+ }
init {
val parent = FrameLayout(ctx)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 949641a7f75e..dd52e39488ac 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -25,7 +25,6 @@ import com.android.systemui.plugins.ClockProvider
import com.android.systemui.plugins.ClockSettings
private val TAG = DefaultClockProvider::class.simpleName
-const val DEFAULT_CLOCK_NAME = "Default Clock"
const val DEFAULT_CLOCK_ID = "DEFAULT"
/** Provides the default system clock */
@@ -35,8 +34,7 @@ class DefaultClockProvider(
val resources: Resources,
val hasStepClockAnimation: Boolean = false
) : ClockProvider {
- override fun getClocks(): List<ClockMetadata> =
- listOf(ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME))
+ override fun getClocks(): List<ClockMetadata> = listOf(ClockMetadata(DEFAULT_CLOCK_ID))
override fun createClock(settings: ClockSettings): ClockController {
if (settings.clockId != DEFAULT_CLOCK_ID) {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index e2f4793b8f91..485c27e16150 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -192,15 +192,18 @@ enum class ClockTickRate(val value: Int) {
/** Some data about a clock design */
data class ClockMetadata(
val clockId: ClockId,
- val name: String,
-) {
- constructor(clockId: ClockId) : this(clockId, clockId) {}
-}
+)
/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
data class ClockConfig(
val id: String,
+ /** Localized name of the clock */
+ val name: String,
+
+ /** Localized accessibility description for the clock */
+ val description: String,
+
/** Transition to AOD should move smartspace like large clock instead of small clock */
val useAlternateSmartspaceAODTransition: Boolean = false,
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index ec006c553b94..16eba220cf5d 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -403,7 +403,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="start|center_vertical"
- android:orientation="vertical">
+ android:orientation="horizontal">
<Button
android:id="@+id/apm_button"
android:layout_width="wrap_content"
@@ -414,12 +414,7 @@
style="@style/Widget.Dialog.Button.BorderButton"
android:clickable="true"
android:focusable="true"/>
- </LinearLayout>
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_vertical">
<Button
android:id="@+id/share_wifi_button"
android:layout_width="wrap_content"
@@ -430,8 +425,14 @@
android:ellipsize="end"
android:clickable="true"
android:focusable="true"
- android:layout_alignParentLeft="true"
android:visibility="gone"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_gravity="end|center_vertical">
<Button
android:id="@+id/done_button"
android:layout_width="wrap_content"
@@ -441,9 +442,8 @@
android:maxLines="1"
android:ellipsize="end"
android:clickable="true"
- android:focusable="true"
- android:layout_alignParentRight="true"/>
- </RelativeLayout>
+ android:focusable="true"/>
+ </LinearLayout>
</LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
index b00908fd2bfa..c1bac3151049 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -15,7 +15,7 @@
-->
<!-- Extends Framelayout -->
-<com.android.systemui.statusbar.notification.row.FooterView
+<com.android.systemui.statusbar.notification.footer.ui.view.FooterView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
@@ -76,4 +76,4 @@
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
-</com.android.systemui.statusbar.notification.row.FooterView>
+</com.android.systemui.statusbar.notification.footer.ui.view.FooterView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 937e97a5fc2b..24846d9ae16e 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stel versteknotasapp in Instellings"</string>
<string name="install_app" msgid="5066668100199613936">"Installeer app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Sinkroniseer wedersyds na eksterne skerm?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Sinkroniseer skerm wedersyds"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Maak toe"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoon en kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Onlangse appgebruik"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Sien onlangse toegang"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index de2fda491f78..23def2894368 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"በቅንብሮች ውስጥ ነባሪ የማስታወሻዎች መተግበሪያን ያቀናብሩ"</string>
<string name="install_app" msgid="5066668100199613936">"መተግበሪያን ጫን"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ወደ ውጫዊ ማሳያ ይንጸባረቅ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ማሳያን አንጸባርቅ"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"አሰናብት"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ማይክሮፎን እና ካሜራ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"የቅርብ ጊዜ የመተግበሪያ አጠቃቀም"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"የቅርብ ጊዜ መዳረሻን አሳይ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 79b671ccd4e9..80d63a23fd94 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"يمكنك ضبط تطبيق تدوين الملاحظات التلقائي في \"الإعدادات\"."</string>
<string name="install_app" msgid="5066668100199613936">"تثبيت التطبيق"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"هل تريد بث محتوى جهازك على الشاشة الخارجية؟"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"بث المحتوى على الشاشة"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"إغلاق"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"الميكروفون والكاميرا"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"آخر استخدام في التطبيقات"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"عرض آخر استخدام في التطبيقات"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index ac30f182f521..c84577373919 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ছেটিঙত টোকাৰ ডিফ’ল্ট এপ্ ছেট কৰক"</string>
<string name="install_app" msgid="5066668100199613936">"এপ্‌টো ইনষ্টল কৰক"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"বাহ্যিক ডিছপ্লে’লৈ মিৰ’ৰ কৰিবনে?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ডিছপ্লে’ মিৰ’ৰ কৰক"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"অগ্ৰাহ্য কৰক"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"মাইক্ৰ’ফ’ন আৰু কেমেৰা"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"শেহতীয়া এপৰ ব্যৱহাৰ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"শেহতীয়া এক্সেছ চাওক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 3ca61dc4f575..5aa26bac0687 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlarda defolt qeydlər tətbiqi ayarlayın"</string>
<string name="install_app" msgid="5066668100199613936">"Tətbiqi quraşdırın"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Xarici displeyə əks etdirilsin?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Displeyi əks etdirin"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"İmtina edin"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon və kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Son tətbiq istifadəsi"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Son girişə baxın"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index b51d4b355b19..cd36884e4740 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Podesite podrazumevanu aplikaciju za beleške u Podešavanjima"</string>
<string name="install_app" msgid="5066668100199613936">"Instaliraj aplikaciju"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Želite li da preslikate na spoljnji ekran?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Preslikaj ekran"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Odbaci"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavno koristila aplikacija"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Prikaži nedavni pristup"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 35a84b0afee1..1b03c8ba09f6 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайце ў Наладах стандартную праграму для нататак"</string>
<string name="install_app" msgid="5066668100199613936">"Усталяваць праграму"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Адлюстраваць на знешнім дысплеі?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Адлюстраваць дысплэй"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Закрыць"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Мікрафон і камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Нядаўна выкарыстоўваліся праграмамі"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Паглядзець нядаўні доступ"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6b212e565a59..4ed1ad944045 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартно приложение за бележки от настройките"</string>
<string name="install_app" msgid="5066668100199613936">"Инсталиране на приложението"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Да се дублира ли на външния екран?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Огледално копиране на дисплея"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Отхвърляне"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Скорошно използване на приложението"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Вижте скорошния достъп"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 5b5ac73430e3..426d38d68a0e 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"\'সেটিংস\' থেকে ডিফল্ট নোট নেওয়ার অ্যাপ সেট করুন"</string>
<string name="install_app" msgid="5066668100199613936">"অ্যাপ ইনস্টল করুন"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"এক্সটার্নাল ডিসপ্লে আয়না?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ডিসপ্লে দেখান"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"বাতিল করুন"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"মাইক্রোফোন ও ক্যামেরা"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"সম্প্রতি ব্যবহার করা অ্যাপ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"সাম্প্রতিক অ্যাক্সেস দেখুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 33330b737edc..4eed7b8965ba 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u Postavkama"</string>
<string name="install_app" msgid="5066668100199613936">"Instaliraj aplikaciju"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Preslikati na vanjski ekran?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Preslikaj ekran"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Odbaci"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavno korištenje aplikacije"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Prikaži nedavni pristup"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 45bb34253a86..b55a79ad8dd7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defineix l\'aplicació de notes predeterminada a Configuració"</string>
<string name="install_app" msgid="5066668100199613936">"Instal·la l\'aplicació"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vols replicar-ho a la pantalla externa?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Duplica la pantalla"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Ignora"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micròfon i càmera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Ús recent de l\'aplicació"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Mostra l\'accés recent"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 0d7d23a34ef7..05b04191f6c7 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Výchozí aplikaci pro poznámky nastavíte v Nastavení"</string>
<string name="install_app" msgid="5066668100199613936">"Nainstalovat aplikaci"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Zrcadlit na externí displej?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Zrcadlit displej"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Zavřít"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon a fotoaparát"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedávné použití aplikacemi"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobrazit nedávný přístup"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 4f6b88ec74b3..5971034b991c 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Angiv standardapp til noter i Indstillinger"</string>
<string name="install_app" msgid="5066668100199613936">"Installer app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vil du spejle til ekstern skærm?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Spejl skærm"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Luk"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon og kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Seneste brug af apps"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se seneste adgang"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 07aa14f400dc..c773f71d7786 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standard-Notizen-App in den Einstellungen einrichten"</string>
<string name="install_app" msgid="5066668100199613936">"App installieren"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Auf externen Bildschirm spiegeln?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Bildschirm spiegeln"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Schließen"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon &amp; Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Kürzliche App-Nutzung"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Kürzliche Zugriffe ansehen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 2a8e51cfbc7f..b6c95aa50bfd 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ορίστε την προεπιλεγμένη εφαρμογή σημειώσεων στις Ρυθμίσεις"</string>
<string name="install_app" msgid="5066668100199613936">"Εγκατάσταση εφαρμογής"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Κατοπτρισμός σε εξωτερική οθόνη;"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Κατοπτρισμός οθόνης"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Παράβλεψη"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Μικρόφωνο και Κάμερα"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Πρόσφατη χρήση εφαρμογής"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Εμφάνιση πρόσφατης πρόσβασης"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 8647adb2934f..6c2b2307fccf 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string>
<string name="install_app" msgid="5066668100199613936">"Install app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Mirror display"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Dismiss"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and Camera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 8647adb2934f..6c2b2307fccf 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string>
<string name="install_app" msgid="5066668100199613936">"Install app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Mirror display"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Dismiss"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and Camera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 8647adb2934f..6c2b2307fccf 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string>
<string name="install_app" msgid="5066668100199613936">"Install app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Mirror display"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Dismiss"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and Camera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d3ea858c3137..52514d22f927 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la app de notas predeterminada en Configuración"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"¿Quieres duplicar a la pantalla externa?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Duplicar pantalla"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Descartar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono y cámara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso reciente en apps"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver accesos recientes"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 284fad4d5b89..4a3c06412802 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la aplicación de notas predeterminada en Ajustes"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar aplicación"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"¿Replicar en pantalla externa?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Replicar pantalla"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Cerrar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono y cámara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso reciente en aplicaciones"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acceso reciente"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 2b79ee5f09c1..08b489d11d7e 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Määrake seadetes märkmete vaikerakendus."</string>
<string name="install_app" msgid="5066668100199613936">"Installi rakendus"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Kas peegeldada välisekraanile?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Ekraani peegeldamine"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Loobu"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon ja kaamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Rakenduste hiljutine kasutamine"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Kuva hiljutine juurdepääs"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 68698ea2cc14..19495bccb4f8 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -676,8 +676,8 @@
<string name="group_system_go_back" msgid="8838454003680364227">"Atzera: itzuli aurreko egoerara (atzera egiteko botoia)"</string>
<string name="group_system_access_home_screen" msgid="1857344316928441909">"Atzitu hasierako pantaila"</string>
<string name="group_system_overview_open_apps" msgid="6897128761003265350">"Ikusi irekitako aplikazioen ikuspegi orokorra"</string>
- <string name="group_system_cycle_forward" msgid="9202444850838205990">"Joan azken aplikazioetako batetik bestera (aurrera)"</string>
- <string name="group_system_cycle_back" msgid="5163464503638229131">"Joan azken aplikazioetako batetik bestera (atzera)"</string>
+ <string name="group_system_cycle_forward" msgid="9202444850838205990">"Joan azkenaldian erabilitako aplikazio batetik bestera (aurrera)"</string>
+ <string name="group_system_cycle_back" msgid="5163464503638229131">"Joan azkenaldian erabilitako aplikazio batetik bestera (atzera)"</string>
<string name="group_system_access_all_apps_search" msgid="488070738028991753">"Atzitu aplikazio guztien zerrenda eta bilatu (adibidez, bilatzeko aukeraren edo Exekutatzeko tresna aplikazioaren bidez)"</string>
<string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ezkutatu eta erakutsi (berriro) zereginen barra"</string>
<string name="group_system_access_system_settings" msgid="7961639365383008053">"Atzitu sistemaren ezarpenak"</string>
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ezarri oharren aplikazio lehenetsia ezarpenetan"</string>
<string name="install_app" msgid="5066668100199613936">"Instalatu aplikazioa"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Kanpoko pantailan islatu nahi duzu?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Islatu pantaila"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Baztertu"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonoa eta kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azken erabilera"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ikusi azkenaldiko sarbidea"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 719924037534..68f6c1d9dd88 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"برنامه پیش‌فرض یادداشت را در «تنظیمات» تنظیم کنید"</string>
<string name="install_app" msgid="5066668100199613936">"نصب برنامه"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"در نمایشگر خارجی پخش شود؟"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"بازتاباندن صفحه‌نمایش"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"بستن"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"میکروفون و دوربین"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"استفاده اخیر از برنامه"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"دیدن دسترسی اخیر"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 073ea60b28f4..934abad4b225 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Aseta oletusmuistiinpanosovellus Asetuksista"</string>
<string name="install_app" msgid="5066668100199613936">"Asenna sovellus"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Peilataanko ulkoiselle näytölle?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Peilaa näyttö"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Ohita"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoni ja kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Sovellusten viimeaikainen käyttö"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Katso viimeaikainen käyttö"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 52bcd7652af3..fe90569169d9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'application de prise de notes par défaut dans les Paramètres"</string>
<string name="install_app" msgid="5066668100199613936">"Installer l\'application"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Dupliquer l\'écran sur un moniteur externe?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Dupliquer l\'écran"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Fermer"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone et appareil photo"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applications"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Afficher l\'accès récent"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 4362d3c227fb..27a4bb6a0e1f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir une appli de notes par défaut dans les paramètres"</string>
<string name="install_app" msgid="5066668100199613936">"Installer l\'appli"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirroring sur écran externe ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Dupliquer l\'écran"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Fermer"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micro et caméra"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applis"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consulter les accès récents"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 1b836a8ea688..2056c2fba14b 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Establece a aplicación de notas predeterminada en Configuración"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar aplicación"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Queres proxectar contido nunha pantalla externa?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Replicar pantalla"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Pechar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono e cámara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente por parte de aplicacións"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acceso recente"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 132ee2e73513..84be50a481e8 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"સેટિંગમાં નોંધની ડિફૉલ્ટ ઍપ સેટ કરો"</string>
<string name="install_app" msgid="5066668100199613936">"ઍપ ઇન્સ્ટૉલ કરો"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"શું બાહ્ય ડિસ્પ્લે પર મિરર કરીએ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"મિરર ડિસ્પ્લે"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"છોડી દો"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"માઇક્રોફોન અને કૅમેરા"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"તાજેતરનો ઍપનો વપરાશ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"તાજેતરનો ઍક્સેસ મેનેજ કરો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f942de505920..2b0019f5274e 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग में जाकर, नोट लेने की सुविधा देने वाले ऐप्लिकेशन को डिफ़ॉल्ट के तौर पर सेट करें"</string>
<string name="install_app" msgid="5066668100199613936">"ऐप्लिकेशन इंस्टॉल करें"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"बाहरी डिसप्ले को अन्य डिवाइस पर दिखाना है?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"मिरर डिसप्ले"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"खारिज करें"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफ़ोन और कैमरा"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"हाल ही में इस्तेमाल करने वाला ऐप्लिकेशन"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"हाल में ऐक्सेस करने वाले ऐप"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index f7c68e160b63..23899fcb2110 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u postavkama"</string>
<string name="install_app" msgid="5066668100199613936">"Instalacija"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Želite li zrcaliti na vanjski zaslon?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Zrcaljenje zaslona"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Odbaci"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavna upotreba aplikacije"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Pogledajte nedavni pristup"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c1b38d904c4d..e5b17d9c6517 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Állítson be alapértelmezett jegyzetkészítő alkalmazást a Beállításokban"</string>
<string name="install_app" msgid="5066668100199613936">"Alkalmazás telepítése"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Tükrözi a kijelzőt a külső képernyőre?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Kijelző tükrözése"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Elvetés"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon és kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Legutóbbi alkalmazáshasználat"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Legutóbbi hozzáférés"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 7139a1f844da..4a1c291e3d74 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Կարգավորեք նշումների կանխադրված հավելված Կարգավորումներում"</string>
<string name="install_app" msgid="5066668100199613936">"Տեղադրել հավելվածը"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Հայելապատճենե՞լ արտաքին էկրանին"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Հայելապատճենել էկրանը"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Փակել"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Խոսափող և տեսախցիկ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Հավելվածի վերջին օգտագործումը"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Տեսնել վերջին օգտագործումը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 44aafde6f132..18a76686154f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setel aplikasi catatan default di Setelan"</string>
<string name="install_app" msgid="5066668100199613936">"Instal aplikasi"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Cerminkan ke layar eksternal?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Cerminkan layar"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Tutup"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon &amp; Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Penggunaan aplikasi baru-baru ini"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Lihat akses terbaru"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 1fda572ae10e..70bed4665e17 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stilltu sjálfgefið glósuforrit í stillingunum"</string>
<string name="install_app" msgid="5066668100199613936">"Setja upp forrit"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Spegla yfir á ytri skjá?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Spegla skjá"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Hunsa"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Hljóðnemi og myndavél"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nýlega notað af forriti"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Sjá nýlegan aðgang"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ed8885f6e360..baffdb9778cd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Imposta l\'app per le note predefinita nelle Impostazioni"</string>
<string name="install_app" msgid="5066668100199613936">"Installa app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vuoi eseguire il mirroring al display esterno?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Esegui il mirroring del display"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Chiudi"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfono e fotocamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente da app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Vedi accesso recente"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 51f5452d843f..968a98287275 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"צריך להגדיר את אפליקציית ברירת המחדל לפתקים ב\'הגדרות\'"</string>
<string name="install_app" msgid="5066668100199613936">"התקנת האפליקציה"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"לשקף למסך חיצוני?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"תצוגת מראה"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"סגירה"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"מיקרופון ומצלמה"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"נעשה שימוש לאחרונה באפליקציות"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"צפייה בהרשאות הגישה האחרונות"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index e77aed9b1be7..798d42add510 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"[設定] でデフォルトのメモアプリを設定してください"</string>
<string name="install_app" msgid="5066668100199613936">"アプリをインストール"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"外部ディスプレイにミラーリングしますか?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ディスプレイをミラーリングする"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"閉じる"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"マイクとカメラ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"最近のアプリの使用状況"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"最近のアクセスを表示"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 8d7deec249f8..f21a2a42536b 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"დააყენეთ ნაგულისხმევი შენიშვნების აპი პარამეტრებში"</string>
<string name="install_app" msgid="5066668100199613936">"აპის ინსტალაცია"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"აირეკლოს გარე ეკრანზე?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ეკრანის არეკვლა"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"დახურვა"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"მიკროფონი და კამერა"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"აპის ბოლოდროინდელი გამოყენება"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ბოლო წვდომის ნახვა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index fc4fe8a2a26d..746c02ed780f 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден әдепкі жазба қолданбасын орнатыңыз."</string>
<string name="install_app" msgid="5066668100199613936">"Қолданбаны орнату"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Сыртқы экран арқылы да көрсету керек пе?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Айна дисплей"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Қабылдамау"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон және камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Соңғы рет қолданбаның датчикті пайдалануы"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Соңғы рет пайдаланғандар"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 10c291dec4ab..9f3b99121b19 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"កំណត់កម្មវិធីកំណត់ចំណាំលំនាំដើមនៅក្នុងការកំណត់"</string>
<string name="install_app" msgid="5066668100199613936">"ដំឡើង​កម្មវិធី"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"បញ្ចាំងទៅ​ឧបករណ៍បញ្ចាំង​ខាងក្រៅឬ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"បញ្ចាំងទៅផ្ទាំងអេក្រង់"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ច្រានចោល"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"មីក្រូហ្វូន និងកាមេរ៉ា"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ការប្រើប្រាស់កម្មវិធីថ្មីៗនេះ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"មើលការចូលប្រើនាពេលថ្មីៗនេះ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 77169809b914..79eef7295bc0 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಡೀಫಾಲ್ಟ್ ಟಿಪ್ಪಣಿಗಳ ಆ್ಯಪ್ ಅನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="install_app" msgid="5066668100199613936">"ಆ್ಯಪ್ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ಬಾಹ್ಯ ಡಿಸ್‌ಪ್ಲೇಗೆ ಪ್ರತಿಬಿಂಬಿಸಬೇಕೆ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ಮಿರರ್ ಡಿಸ್‌ಪ್ಲೇ"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ವಜಾಗೊಳಿಸಿ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಕ್ಯಾಮರಾ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್ ಬಳಕೆ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ಇತ್ತೀಚಿನ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ನೋಡಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c2fbf093160c..7985e4c7e3af 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"설정에서 기본 메모 앱 설정"</string>
<string name="install_app" msgid="5066668100199613936">"앱 설치"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"외부 디스플레이로 미러링하시겠습니까?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"디스플레이 미러링"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"닫기"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"마이크 및 카메라"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"최근 앱 사용"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"최근 액세스 보기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 8ab4cb7d9128..ded1f752ef87 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден демейки кыска жазуулар колдонмосун тууралаңыз"</string>
<string name="install_app" msgid="5066668100199613936">"Колдонмону орнотуу"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Тышкы экранга чыгарасызбы?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Тышкы экран"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Жабуу"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон жана камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Жакында колдонмолордо иштетилген"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Акыркы пайдалануусун көрүү"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index a1585f2d69d7..1e61b8a85fb1 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ຕັ້ງຄ່າແອັບຈົດບັນທຶກເລີ່ມຕົ້ນໃນການຕັ້ງຄ່າ"</string>
<string name="install_app" msgid="5066668100199613936">"ຕິດຕັ້ງແອັບ"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ສາຍໃສ່ຈໍສະແດງຜົນພາຍນອກບໍ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ຈໍສະແດງຜົນແບບສະທ້ອນ"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ປິດໄວ້"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ໄມໂຄຣໂຟນ ແລະ ກ້ອງຖ່າຍຮູບ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ການໃຊ້ແອັບຫຼ້າສຸດ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ເບິ່ງສິດເຂົ້າເຖິງຫຼ້າສຸດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index c5f649c82dc0..06c1369d29ad 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nustatykite numatytąją užrašų programą Nustatymuose"</string>
<string name="install_app" msgid="5066668100199613936">"Įdiegti programą"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Bendrinti ekrano vaizdą išoriniame ekrane?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Bendrinti ekrano vaizdą"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Atsisakyti"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonas ir fotoaparatas"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Pastarasis programos naudojimas"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Žr. pastarąją prieigą"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index d49360919a32..fdf30285cee4 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Iestatījumos iestatiet noklusējuma piezīmju lietotni."</string>
<string name="install_app" msgid="5066668100199613936">"Instalēt lietotni"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vai spoguļot ārējā displejā?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Spoguļot displeju"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Nerādīt"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofons un kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nesen izmantoja lietotnes"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Skatīt neseno piekļuvi"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 46193b3a6855..80ef7bb64d07 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Поставете стандардна апликација за белешки во „Поставки“"</string>
<string name="install_app" msgid="5066668100199613936">"Инсталирајте ја апликацијата"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Да се синхронизира на надворешниот екран?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Пресликај екран"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Отфрли"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Неодамнешно користење на апликација"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Видете го скорешниот пристап"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index d63153882e72..5b1c80f37a18 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ക്രമീകരണത്തിൽ കുറിപ്പുകൾക്കുള്ള ഡിഫോൾട്ട് ആപ്പ് സജ്ജീകരിക്കുക"</string>
<string name="install_app" msgid="5066668100199613936">"ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യൂ"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ബാഹ്യ ഡിസ്‌പ്ലേയിലേക്ക് മിറർ ചെയ്യണോ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"മിറർ ഡിസ്‌പ്ലേ"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"മൈക്രോഫോണും ക്യാമറയും"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"അടുത്തിടെയുള്ള ആപ്പ് ഉപയോഗം"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"അടുത്തിടെയുള്ള ആക്‌സസ് കാണുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index b16b22a4e041..3f65931f276e 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Тохиргоонд тэмдэглэлийн өгөгдмөл апп тохируулна уу"</string>
<string name="install_app" msgid="5066668100199613936">"Аппыг суулгах"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Гадны дэлгэцэд тусгал үүсгэх үү?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Дэлгэцийн тусгал үүсгэх"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Хаах"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон болон камер"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Аппын саяхны ашиглалт"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Саяхны хандалтыг харах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 16fac23db53f..238aacab4d32 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग्ज मध्ये डीफॉल्ट टिपा अ‍ॅप सेट करा"</string>
<string name="install_app" msgid="5066668100199613936">"अ‍ॅप इंस्टॉल करा"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"बाह्य डिस्प्लेवर मिरर करायचे आहे का?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"डिस्प्ले मिरर करा"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"डिसमिस करा"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"मायक्रोफोन आणि कॅमेरा"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"अलीकडील अ‍ॅप वापर"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"अलीकडील अ‍ॅक्सेस पहा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 7cafdcde5e79..8c764f1e7f75 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Tetapkan apl nota lalai dalam Tetapan"</string>
<string name="install_app" msgid="5066668100199613936">"Pasang apl"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Paparkan pada paparan luaran?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Segerakkan paparan"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Ketepikan"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon &amp; Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Penggunaan apl terbaharu"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Lihat akses terbaharu"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 620124eb5cec..883b9e95144a 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ဆက်တင်များတွင် မူရင်းမှတ်စုများအက်ပ် သတ်မှတ်ပါ"</string>
<string name="install_app" msgid="5066668100199613936">"အက်ပ် ထည့်သွင်းရန်"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ပြင်ပဖန်သားပြင်သို့ စကရင်ပွားမလား။"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ဖန်သားပြင်ကို စကရင်ပွားရန်"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ပယ်ရန်"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"မိုက်ခရိုဖုန်းနှင့် ကင်မရာ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"လတ်တလော အက်ပ်အသုံးပြုမှု"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"လတ်တလောအသုံးပြုမှုကို ကြည့်ရန်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 722cc12d05f4..53a4c527cca6 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Du kan velge en standardapp for notater i Innstillinger"</string>
<string name="install_app" msgid="5066668100199613936">"Installer appen"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vil du speile til en ekstern skjerm?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Speil skjermen"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Lukk"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon og kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nylig appbruk"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se nylig tilgang"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 74e5c6f328f8..3b31b3adfd64 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिङमा गई नोट बनाउने डिफल्ट एप तोक्नुहोस्"</string>
<string name="install_app" msgid="5066668100199613936">"एप इन्स्टल गर्नुहोस्"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"बाह्य डिस्प्लेमा मिरर गर्ने हो?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"डिस्प्ले मिरर गर्नुहोस्"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"खारेज गर्नुहोस्"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफोन तथा क्यामेरा"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"एपको हालसालैको प्रयोग"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"हालसालै एक्सेस गर्ने एप हेर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 6d97a9ffc805..664af5ec84eb 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standaard notitie-app instellen in Instellingen"</string>
<string name="install_app" msgid="5066668100199613936">"App installeren"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Spiegelen naar extern scherm?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Scherm spiegelen"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Sluiten"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfoon en camera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app-gebruik"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Recente toegang bekijken"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index a6e14f990820..db9e0c5debd8 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ସେଟିଂସରେ ଡିଫଲ୍ଟ ନୋଟ୍ସ ଆପ ସେଟ କରନ୍ତୁ"</string>
<string name="install_app" msgid="5066668100199613936">"ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେକୁ ମିରର କରିବେ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ଡିସପ୍ଲେ ମିରର କରନ୍ତୁ"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ମାଇକ୍ରୋଫୋନ ଏବଂ କେମେରା"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ବର୍ତ୍ତମାନର ଆପ ବ୍ୟବହାର"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ବର୍ତ୍ତମାନର ଆକ୍ସେସ ଦେଖନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index faca7b13eae1..591c5e781382 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਨੋਟ ਐਪ ਨੂੰ ਸੈੱਟ ਕਰੋ"</string>
<string name="install_app" msgid="5066668100199613936">"ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ਕੀ ਬਾਹਰੀ ਡਿਸਪਲੇ \'ਤੇ ਪ੍ਰਤਿਬਿੰਬਿਤ ਕਰਨਾ ਹੈ?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ਡਿਸਪਲੇ ਨੂੰ ਪ੍ਰਤਿਬਿੰਬਿਤ ਕਰੋ"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ਖਾਰਜ ਕਰੋ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਕੈਮਰਾ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ਹਾਲ ਹੀ ਵਿੱਚ ਵਰਤੀ ਗਈ ਐਪ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ਹਾਲੀਆ ਪਹੁੰਚ ਦੇਖੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 3bb539a21f6f..195122113140 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ustaw domyślną aplikację do obsługi notatek w Ustawieniach"</string>
<string name="install_app" msgid="5066668100199613936">"Zainstaluj aplikację"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Powielić na wyświetlaczu zewnętrznym?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Powielaj obraz"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Zamknij"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i aparat"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikacje korzystające w ostatnim czasie"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobacz ostatni dostęp"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 8f93b73c3f85..693a3a1b7030 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defina o app de notas padrão nas Configurações"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar o app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Espelhar para a tela externa?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Espelhar tela"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Dispensar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente do app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consultar acessos recentes"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 02ee09836610..c4f1f6790907 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Predefina a app de notas nas Definições"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Espelhar para o ecrã externo?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Espelhar ecrã"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Ignorar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilização recente da app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acesso recente"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8f93b73c3f85..693a3a1b7030 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defina o app de notas padrão nas Configurações"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar o app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Espelhar para a tela externa?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Espelhar tela"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Dispensar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente do app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consultar acessos recentes"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 14cdeaccdc5c..a942332e2472 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setează aplicația prestabilită de note din Setări"</string>
<string name="install_app" msgid="5066668100199613936">"Instalează aplicația"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Oglindești pe ecranul extern?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Afișare în oglindă"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Închide"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfon și cameră"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilizare recentă în aplicații"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Vezi accesarea recentă"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index c5379c20b7ba..68601d6a71ce 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартное приложение для заметок в настройках."</string>
<string name="install_app" msgid="5066668100199613936">"Установить приложение"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Дублировать на внешний дисплей?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Дублировать дисплей"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Закрыть"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Недавнее использование приложениями"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Посмотреть недавний доступ"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index d53f0eba6e4d..86cb3c324143 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"සැකසීම් තුළ පෙරනිමි සටහන් යෙදුම සකසන්න"</string>
<string name="install_app" msgid="5066668100199613936">"යෙදුම ස්ථාපනය කරන්න"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"බාහිර සංදර්ශකයට දර්පණය කරන්න ද?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"සංදර්ශකය දර්පණය කරන්න"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"අස් කරන්න"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"මයික්‍රොෆෝනය සහ කැමරාව"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"මෑත යෙදුම් භාවිතය"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"මෑත ප්‍රවේශය බලන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7fa0d077918f..56b9f7549038 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nastavte predvolenú aplikáciu na poznámky v Nastaveniach"</string>
<string name="install_app" msgid="5066668100199613936">"Inštalovať aplikáciu"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Chcete zrkadliť na externú obrazovku?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Zrkadliť obrazovku"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Zavrieť"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofón a fotoaparát"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedávne využitie aplikácie"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobraziť nedávny prístup"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 87c18f4cabed..b72f750eae7c 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nastavite privzeto aplikacijo za zapiske v nastavitvah."</string>
<string name="install_app" msgid="5066668100199613936">"Namesti aplikacijo"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Želite zrcaliti v zunanji zaslon?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Zrcali zaslon"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Opusti"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon in fotoaparat"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavna uporaba v aplikacijah"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ogled nedavnih dostopov"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 3e1471a68af2..92f6f9c27e77 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Cakto aplikacionin e parazgjedhur të shënimeve te \"Cilësimet\""</string>
<string name="install_app" msgid="5066668100199613936">"Instalo aplikacionin"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Të pasqyrohet në ekranin e jashtëm?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Pasqyro ekranin"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Hiq"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoni dhe kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Përdorimi i fundit i aplikacionit"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Shiko qasjen e fundit"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 07897d720128..7c0d9be76436 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Подесите подразумевану апликацију за белешке у Подешавањима"</string>
<string name="install_app" msgid="5066668100199613936">"Инсталирај апликацију"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Желите ли да пресликате на спољњи екран?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Пресликај екран"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Одбаци"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Недавно користила апликација"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Прикажи недавни приступ"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index aee168e24329..323ce11f853d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ställ in en standardapp för anteckningar i inställningarna"</string>
<string name="install_app" msgid="5066668100199613936">"Installera appen"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vill du spegla till extern skärm?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Spegla skärm"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Ignorera"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon och kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Senaste appanvändning"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se senaste åtkomst"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index be3baddbe912..304910a46526 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Teua programu chaguomsingi ya madokezo katika Mipangilio"</string>
<string name="install_app" msgid="5066668100199613936">"Sakinisha programu"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Ungependa kuonyesha kwenye skrini ya nje?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Akisi skrini"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Ondoa"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Maikrofoni na Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Matumizi ya programu hivi majuzi"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Angalia ufikiaji wa majuzi"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 785c4d5af8b6..3ac5e2e7c8cc 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"குறிப்பு எடுப்பதற்கான இயல்புநிலை ஆப்ஸை அமைப்புகளில் அமையுங்கள்"</string>
<string name="install_app" msgid="5066668100199613936">"ஆப்ஸை நிறுவுங்கள்"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"வெளிப்புறக் காட்சிக்கு மிரர் செய்யவா?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"டிஸ்பிளேயை மிரர் செய்"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"வேண்டாம்"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"மைக்ரோஃபோனும் கேமராவும்"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"சமீபத்திய ஆப்ஸ் பயன்பாடு"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"சமீபத்திய அணுகலைக் காட்டு"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 96d77b7237ba..0526f95a8e84 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"సెట్టింగ్‌లలో ఆటోమేటిక్‌గా ఉండేలా ఒక నోట్స్ యాప్‌ను సెట్ చేసుకోండి"</string>
<string name="install_app" msgid="5066668100199613936">"యాప్‌ను ఇన్‌స్టాల్ చేయండి"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"బాహ్య డిస్‌ప్లే‌ను మిర్రర్ చేయాలా?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"మిర్రర్ డిస్‌ప్లే"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"విస్మరించండి"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"మైక్రోఫోన్ &amp; కెమెరా"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ఇటీవలి యాప్ వినియోగం"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ఇటీవలి యాక్సెస్‌ను చూడండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index f8fbfbe3c7d3..8949360f9508 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"กำหนดแอปการจดบันทึกเริ่มต้นในการตั้งค่า"</string>
<string name="install_app" msgid="5066668100199613936">"ติดตั้งแอป"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"มิเรอร์ไปยังจอแสดงผลภายนอกไหม"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"มิเรอร์จอแสดงผล"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"ปิด"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ไมโครโฟนและกล้อง"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"การใช้แอปครั้งล่าสุด"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ดูการเข้าถึงล่าสุด"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 435398db067d..e5c11df40e99 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Magtakda ng default na app sa pagtatala sa Mga Setting"</string>
<string name="install_app" msgid="5066668100199613936">"I-install ang app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"I-mirror sa external na display?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"I-mirror ang display"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"I-dismiss"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikropono at Camera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Kamakailang paggamit ng app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Tingnan ang kamakailang access"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d0ddbec98faf..3552d9214fb0 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlar\'ı kullanarak varsayılan notlar ayarlayın"</string>
<string name="install_app" msgid="5066668100199613936">"Uygulamayı yükle"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Harici ekrana yansıtılsın mı?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Ekranı yansıt"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Kapat"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon ve Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Son uygulama kullanımı"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Son erişimi göster"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 1489dc77a9f1..2e6aea9d59d3 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Призначте стандартний додаток для нотаток у налаштуваннях"</string>
<string name="install_app" msgid="5066668100199613936">"Установити додаток"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Дублювати на зовнішньому екрані?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Дублювати екран"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Закрити"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Мікрофон і камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Нещодавнє використання додатками"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Переглянути нещодавній доступ"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 9d69a5e13319..2e2fc418116d 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ترتیبات میں ڈیفالٹ نوٹس ایپ سیٹ کریں"</string>
<string name="install_app" msgid="5066668100199613936">"ایپ انسٹال کریں"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"بیرونی ڈسپلے پر مرر کریں؟"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"ڈسپلے کو دو طرفہ مطابقت پذیر بنائیں"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"برخاست کریں"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"مائیکروفون اور کیمرا"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"حالیہ ایپ کا استعمال"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"حالیہ رسائی دیکھیں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 31b216b8977f..a8654d5604b1 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standart qaydlar ilovasini Sozlamalar orqali tanlang"</string>
<string name="install_app" msgid="5066668100199613936">"Ilovani oʻrnatish"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Tashqi displeyda aks ettirilsinmi?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Displeyni akslantirish"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Yopish"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon va kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Ilovadan oxirgi foydalanish"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Oxirgi ruxsatni koʻrish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 814e0a6087eb..54437456188f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Đặt ứng dụng ghi chú mặc định trong phần Cài đặt"</string>
<string name="install_app" msgid="5066668100199613936">"Cài đặt ứng dụng"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Đồng bộ hoá hai chiều sang màn hình ngoài?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Phản chiếu màn hình"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Đóng"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrô và máy ảnh"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Hoạt động sử dụng gần đây của ứng dụng"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Xem hoạt động truy cập gần đây"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 8b2caf028b5e..44c163b03bcb 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在设置中设置默认记事应用"</string>
<string name="install_app" msgid="5066668100199613936">"安装应用"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"镜像到外接显示屏?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"镜像显示"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"关闭"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"麦克风和摄像头"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"近期应用对手机传感器的使用情况"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期使用情况"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 8a160c366f74..f45b2fe1fc39 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設筆記應用程式"</string>
<string name="install_app" msgid="5066668100199613936">"安裝應用程式"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"要鏡像投射至外部顯示屏嗎?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"鏡像顯示"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"關閉"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"麥克風和相機"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"近期應用程式使用情況"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期存取記錄"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 38b81a0a4dee..5a5bb9d19c3f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設記事應用程式"</string>
<string name="install_app" msgid="5066668100199613936">"安裝應用程式"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"要以鏡像方式投放至外部螢幕嗎?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"鏡像顯示"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"關閉"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"麥克風和相機"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"最近曾使用感應器的應用程式"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期存取記錄"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index fc704172a295..8b6bfae60199 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1183,10 +1183,8 @@
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setha i-app yamanothi azenzakalelayo Kumsethingi"</string>
<string name="install_app" msgid="5066668100199613936">"Faka i-app"</string>
<string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Fanisa nesibonisi sangaphandle?"</string>
- <!-- no translation found for mirror_display (2515262008898122928) -->
- <skip />
- <!-- no translation found for dismiss_dialog (2195508495854675882) -->
- <skip />
+ <string name="mirror_display" msgid="2515262008898122928">"Isibonisi sokufanisa"</string>
+ <string name="dismiss_dialog" msgid="2195508495854675882">"Chitha"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Imakrofoni Nekhamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Ukusetshenziswa kwakamuva kwe-app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Bona ukufinyelela kwakamuva"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 0ee5da22a31b..6d54058f8e0c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -846,7 +846,7 @@
<!-- Amount the button should shake when it's not long-pressed for long enough. -->
<dimen name="keyguard_affordance_shake_amplitude">8dp</dimen>
- <dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
+ <dimen name="keyguard_affordance_horizontal_offset">16dp</dimen>
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
<!-- Value should be at least sum of 'keyguard_affordance_width' +
'keyguard_affordance_horizontal_offset' -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
index 5d036fbe5e52..b44bf395930e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
@@ -71,7 +71,6 @@ public class FloatingRotationButton implements RotationButton {
private AnimatedVectorDrawable mAnimatedDrawable;
private boolean mIsShowing;
- private boolean mCanShow = true;
private int mDisplayRotation;
private boolean mIsTaskbarVisible = false;
@@ -150,7 +149,7 @@ public class FloatingRotationButton implements RotationButton {
@Override
public boolean show() {
- if (!mCanShow || mIsShowing) {
+ if (mIsShowing) {
return false;
}
@@ -222,14 +221,6 @@ public class FloatingRotationButton implements RotationButton {
}
@Override
- public void setCanShowRotationButton(boolean canShow) {
- mCanShow = canShow;
- if (!mCanShow) {
- hide();
- }
- }
-
- @Override
public void onTaskbarStateChanged(boolean taskbarVisible, boolean taskbarStashed) {
mIsTaskbarVisible = taskbarVisible;
mIsTaskbarStashed = taskbarStashed;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java
index 89f71ebf3dce..42dda0a4da4f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButton.java
@@ -36,7 +36,6 @@ public interface RotationButton {
default boolean isVisible() {
return false;
}
- default void setCanShowRotationButton(boolean canShow) {}
default void onTaskbarStateChanged(boolean taskbarVisible, boolean taskbarStashed) {}
default void updateIcon(int lightIconColor, int darkIconColor) { }
default void setOnClickListener(View.OnClickListener onClickListener) { }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 0094820f0dad..a6e04cec5f86 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -23,6 +23,7 @@ import android.view.SurfaceControl;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
+import com.android.internal.os.IResultReceiver;
import com.android.systemui.shared.recents.model.ThumbnailData;
public class RecentsAnimationControllerCompat {
@@ -89,11 +90,16 @@ public class RecentsAnimationControllerCompat {
* @param sendUserLeaveHint determines whether userLeaveHint will be set true to the previous
* app.
*/
- public void finish(boolean toHome, boolean sendUserLeaveHint) {
+ public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) {
try {
- mAnimationController.finish(toHome, sendUserLeaveHint);
+ mAnimationController.finish(toHome, sendUserLeaveHint, finishCb);
} catch (RemoteException e) {
Log.e(TAG, "Failed to finish recents animation", e);
+ try {
+ finishCb.send(0, null);
+ } catch (Exception ex) {
+ // Local call, can ignore
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index bb0cf6d470a2..eb7a7358cbf1 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -34,7 +34,6 @@ import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.customization.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.dagger.qualifiers.DisplaySpecific
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.DOZING_MIGRATION_1
@@ -80,8 +79,8 @@ constructor(
private val batteryController: BatteryController,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val configurationController: ConfigurationController,
- @DisplaySpecific private val resources: Resources,
- @DisplaySpecific private val context: Context,
+ @Main private val resources: Resources,
+ private val context: Context,
@Main private val mainExecutor: DelayableExecutor,
@Background private val bgExecutor: Executor,
@KeyguardSmallClockLog private val smallLogBuffer: LogBuffer?,
@@ -212,13 +211,13 @@ constructor(
if (regionSamplingEnabled) {
clock?.let { clock ->
smallRegionSampler?.let {
- smallClockIsDark = it.currentRegionDarkness().isDark
- clock.smallClock.events.onRegionDarknessChanged(smallClockIsDark)
+ val isRegionDark = it.currentRegionDarkness().isDark
+ clock.smallClock.events.onRegionDarknessChanged(isRegionDark)
}
largeRegionSampler?.let {
- largeClockIsDark = it.currentRegionDarkness().isDark
- clock.largeClock.events.onRegionDarknessChanged(largeClockIsDark)
+ val isRegionDark = it.currentRegionDarkness().isDark
+ clock.largeClock.events.onRegionDarknessChanged(isRegionDark)
}
}
return
@@ -226,12 +225,12 @@ constructor(
val isLightTheme = TypedValue()
context.theme.resolveAttribute(android.R.attr.isLightTheme, isLightTheme, true)
- smallClockIsDark = isLightTheme.data == 0
- largeClockIsDark = isLightTheme.data == 0
+ val isRegionDark = isLightTheme.data == 0
clock?.run {
- smallClock.events.onRegionDarknessChanged(smallClockIsDark)
- largeClock.events.onRegionDarknessChanged(largeClockIsDark)
+ Log.i(TAG, "Region isDark: $isRegionDark")
+ smallClock.events.onRegionDarknessChanged(isRegionDark)
+ largeClock.events.onRegionDarknessChanged(isRegionDark)
}
}
protected open fun createRegionSampler(
@@ -261,9 +260,6 @@ constructor(
get() = isKeyguardVisible && dozeAmount < DOZE_TICKRATE_THRESHOLD
private var cachedWeatherData: WeatherData? = null
- private var smallClockIsDark = true
- private var largeClockIsDark = true
-
private val configListener =
object : ConfigurationController.ConfigurationListener {
override fun onThemeChanged() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 51c0676876b9..50be97ec1af9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -139,7 +139,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
case PROMPT_REASON_USER_REQUEST:
return R.string.kg_prompt_after_user_lockdown_password;
case PROMPT_REASON_PREPARE_FOR_UPDATE:
- return R.string.kg_prompt_unattended_update_password;
+ return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_TRUSTAGENT_EXPIRED:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 714ba81fc664..57151ae32db0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -321,7 +321,7 @@ public class KeyguardPatternViewController
resId = R.string.kg_prompt_after_user_lockdown_pattern;
break;
case PROMPT_REASON_PREPARE_FOR_UPDATE:
- resId = R.string.kg_prompt_unattended_update_pattern;
+ resId = R.string.kg_prompt_reason_timeout_pattern;
break;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
resId = R.string.kg_prompt_reason_timeout_pattern;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 9d6d0332b96b..681aa70402bd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -123,7 +123,7 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
case PROMPT_REASON_USER_REQUEST:
return R.string.kg_prompt_after_user_lockdown_pin;
case PROMPT_REASON_PREPARE_FOR_UPDATE:
- return R.string.kg_prompt_unattended_update_pin;
+ return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_TRUSTAGENT_EXPIRED:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index f9cc03eea288..d8486029a903 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -18,7 +18,6 @@ package com.android.keyguard;
import static java.util.Collections.emptySet;
-import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
@@ -79,14 +78,6 @@ public class KeyguardStatusView extends GridLayout {
mKeyguardSlice = findViewById(R.id.keyguard_slice_view);
mMediaHostContainer = findViewById(R.id.status_view_media_container);
- if (mMediaHostContainer != null) {
- LayoutTransition mediaLayoutTransition = new LayoutTransition();
- ((ViewGroup) mMediaHostContainer).setLayoutTransition(mediaLayoutTransition);
- mediaLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
- mediaLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- mediaLayoutTransition.disableTransitionType(LayoutTransition.APPEARING);
- mediaLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING);
- }
updateDark();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 67b705222977..79642bdae1ce 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -23,7 +23,6 @@ import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_CL
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.animation.Animator;
-import android.animation.LayoutTransition;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.content.res.Configuration;
@@ -50,14 +49,15 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.keyguard.KeyguardClockSwitch.ClockSize;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
+import com.android.systemui.animation.ViewHierarchyAnimator;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.power.shared.model.ScreenPowerState;
import com.android.systemui.plugins.ClockController;
import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.power.shared.model.ScreenPowerState;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
@@ -175,27 +175,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
return;
}
- final LayoutTransition mediaLayoutTransition =
- ((ViewGroup) mediaHostContainer).getLayoutTransition();
- if (mediaLayoutTransition == null) return;
-
- mediaLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
+ ViewHierarchyAnimator.Companion.animateNextUpdate(mediaHostContainer,
+ Interpolators.STANDARD, /* duration= */ 500L,
+ /* animateChildren= */ false);
});
-
- mediaHostContainer.addOnLayoutChangeListener(
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
- final LayoutTransition mediaLayoutTransition =
- ((ViewGroup) mediaHostContainer).getLayoutTransition();
- if (mediaLayoutTransition == null) return;
- if (!mediaLayoutTransition.isTransitionTypeEnabled(
- LayoutTransition.CHANGING)) {
- return;
- }
- // Note: when this is called, the LayoutTransition is already been set up.
- // Disables the LayoutTransition until it's explicitly enabled again.
- mediaLayoutTransition.disableTransitionType(LayoutTransition.CHANGING);
- }
- );
}
mDumpManager.registerDumpable(getInstanceName(), this);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 3f5ec7d020da..3bf148276eab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -189,6 +189,8 @@ import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.Assert;
import com.android.systemui.util.settings.SecureSettings;
+import dalvik.annotation.optimization.NeverCompile;
+
import com.google.android.collect.Lists;
import java.io.PrintWriter;
@@ -4430,6 +4432,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
@SuppressLint("MissingPermission")
+ @NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("KeyguardUpdateMonitor state:");
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index a7b35ef3aba4..0d3f726b011b 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -62,6 +62,7 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.biometrics.UdfpsController;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -74,12 +75,15 @@ import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.Objects;
import java.util.function.Consumer;
@@ -128,6 +132,8 @@ public class LockIconViewController implements Dumpable {
@NonNull private final KeyguardTransitionInteractor mTransitionInteractor;
@NonNull private final KeyguardInteractor mKeyguardInteractor;
@NonNull private final View.AccessibilityDelegate mAccessibilityDelegate;
+ @NonNull private final Lazy<BouncerInteractor> mBouncerInteractor;
+ @NonNull private final SceneContainerFlags mSceneContainerFlags;
// Tracks the velocity of a touch to help filter out the touches that move too fast.
private VelocityTracker mVelocityTracker;
@@ -204,7 +210,9 @@ public class LockIconViewController implements Dumpable {
@NonNull KeyguardInteractor keyguardInteractor,
@NonNull FeatureFlags featureFlags,
PrimaryBouncerInteractor primaryBouncerInteractor,
- Context context
+ Context context,
+ Lazy<BouncerInteractor> bouncerInteractor,
+ SceneContainerFlags sceneContainerFlags
) {
mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -233,6 +241,8 @@ public class LockIconViewController implements Dumpable {
dumpManager.registerDumpable(TAG, this);
mResources = resources;
mContext = context;
+ mBouncerInteractor = bouncerInteractor;
+ mSceneContainerFlags = sceneContainerFlags;
mAccessibilityDelegate = new View.AccessibilityDelegate() {
private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint =
@@ -715,7 +725,8 @@ public class LockIconViewController implements Dumpable {
return mDownDetected;
}
- private void onLongPress() {
+ @VisibleForTesting
+ protected void onLongPress() {
cancelTouches();
if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) {
Log.v(TAG, "lock icon long-press rejected by the falsing manager.");
@@ -732,7 +743,11 @@ public class LockIconViewController implements Dumpable {
// play device entry haptic (consistent with UDFPS controller longpress)
vibrateOnLongPress();
- mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
+ if (mSceneContainerFlags.isEnabled()) {
+ mBouncerInteractor.get().showOrUnlockDevice(null);
+ } else {
+ mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 018038423d4e..7739021bad33 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -87,7 +87,6 @@ import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -130,14 +129,14 @@ import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.util.leak.LeakReporter;
import com.android.systemui.util.sensors.AsyncSensorManager;
+import dagger.Lazy;
+
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Named;
-import dagger.Lazy;
-
/**
* Class to handle ugly dependencies throughout sysui until we determine the
* long-term dependency injection solution.
@@ -298,7 +297,6 @@ public class Dependency {
@Inject Lazy<AccessibilityFloatingMenuController> mAccessibilityFloatingMenuController;
@Inject Lazy<StatusBarStateController> mStatusBarStateController;
@Inject Lazy<NotificationLockscreenUserManager> mNotificationLockscreenUserManager;
- @Inject Lazy<NotificationGutsManager> mNotificationGutsManager;
@Inject Lazy<NotificationMediaManager> mNotificationMediaManager;
@Inject Lazy<NotificationRemoteInputManager> mNotificationRemoteInputManager;
@Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
@@ -498,7 +496,6 @@ public class Dependency {
mProviders.put(NotificationLockscreenUserManager.class,
mNotificationLockscreenUserManager::get);
mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get);
- mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get);
mProviders.put(NotificationRemoteInputManager.class,
mNotificationRemoteInputManager::get);
mProviders.put(SmartReplyConstants.class, mSmartReplyConstants::get);
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 4541384aaa37..b573fadea15e 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -28,6 +28,7 @@ import com.android.systemui.res.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.settings.UserTracker;
@@ -46,6 +47,7 @@ import dagger.assisted.AssistedInject;
/**
* Manages notification when a guest session is resumed.
*/
+@SysUISingleton
public class GuestResumeSessionReceiver {
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 4af2c740ddc9..54dbf7275dce 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -93,6 +93,8 @@ import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.ThreadFactory;
import com.android.systemui.util.settings.SecureSettings;
+import dalvik.annotation.optimization.NeverCompile;
+
import kotlin.Pair;
import java.io.PrintWriter;
@@ -1088,6 +1090,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
}
}
+ @NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("ScreenDecorations state:");
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
index f6e02969e4c2..53b6879db3d7 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt
@@ -15,7 +15,10 @@ interface CommunalRepository {
class CommunalRepositoryImpl
@Inject
constructor(
- featureFlags: FeatureFlagsClassic,
+ private val featureFlags: FeatureFlagsClassic,
) : CommunalRepository {
- override val isCommunalEnabled = featureFlags.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED)
+ override val isCommunalEnabled: Boolean
+ get() =
+ featureFlags.isEnabled(Flags.COMMUNAL_SERVICE_ENABLED) &&
+ featureFlags.isEnabled(Flags.COMMUNAL_HUB)
}
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 9fb8da3e76af..04bb6ae75e60 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
@@ -28,11 +28,13 @@ import kotlinx.coroutines.flow.Flow
class CommunalInteractor
@Inject
constructor(
- communalRepository: CommunalRepository,
+ private val communalRepository: CommunalRepository,
widgetRepository: CommunalWidgetRepository,
) {
+
/** Whether communal features are enabled. */
- val isCommunalEnabled: Boolean = communalRepository.isCommunalEnabled
+ val isCommunalEnabled: Boolean
+ get() = communalRepository.isCommunalEnabled
/** A flow of info about the widget to be displayed, or null if widget is unavailable. */
val appWidgetInfo: Flow<CommunalAppWidgetInfo?> = widgetRepository.stopwatchAppWidgetInfo
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 4b6ad6d9be03..d5f0e649ef40 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -56,6 +56,7 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.FlagsModule;
import com.android.systemui.keyboard.KeyboardModule;
+import com.android.systemui.keyevent.data.repository.KeyEventRepositoryModule;
import com.android.systemui.keyguard.ui.view.layout.blueprints.KeyguardBlueprintModule;
import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.log.dagger.MonitorLog;
@@ -181,6 +182,7 @@ import javax.inject.Named;
FalsingModule.class,
FlagsModule.class,
FooterActionsModule.class,
+ KeyEventRepositoryModule.class,
KeyboardModule.class,
KeyguardBlueprintModule.class,
LetterboxModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
index 5b85ad01301b..1e29e1fa3197 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
@@ -2,7 +2,7 @@ package com.android.systemui.deviceentry.data.repository
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow
+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
@@ -51,7 +51,7 @@ interface DeviceEntryRepository {
* When this is `false`, an automatically-triggered face unlock shouldn't automatically dismiss
* the lockscreen.
*/
- fun isBypassEnabled(): Boolean
+ val isBypassEnabled: StateFlow<Boolean>
}
/** Encapsulates application state for device entry. */
@@ -68,7 +68,7 @@ constructor(
) : DeviceEntryRepository {
override val isUnlocked =
- ConflatedCallbackFlow.conflatedCallbackFlow {
+ conflatedCallbackFlow {
val callback =
object : KeyguardStateController.Callback {
override fun onUnlockedChanged() {
@@ -112,7 +112,24 @@ constructor(
}
}
- override fun isBypassEnabled() = keyguardBypassController.bypassEnabled
+ override val isBypassEnabled: StateFlow<Boolean> =
+ conflatedCallbackFlow {
+ val listener =
+ object : KeyguardBypassController.OnBypassStateChangedListener {
+ override fun onBypassStateChanged(isEnabled: Boolean) {
+ trySend(isEnabled)
+ }
+ }
+ keyguardBypassController.registerOnBypassStateChangedListener(listener)
+ awaitClose {
+ keyguardBypassController.unregisterOnBypassStateChangedListener(listener)
+ }
+ }
+ .stateIn(
+ applicationScope,
+ SharingStarted.Eagerly,
+ initialValue = keyguardBypassController.bypassEnabled,
+ )
companion object {
private const val TAG = "DeviceEntryRepositoryImpl"
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 5612c9a488ff..e96e318fd59d 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -106,5 +106,5 @@ constructor(
* authentication challenge via face unlock or fingerprint sensor can automatically bypass the
* lock screen.
*/
- fun isBypassEnabled() = repository.isBypassEnabled()
+ val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepository.kt b/packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepository.kt
new file mode 100644
index 000000000000..5bc5d0b290ca
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepository.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyevent.data.repository
+
+import android.view.KeyEvent
+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.statusbar.CommandQueue
+import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/** Defines interface for classes that encapsulate application state for key event presses. */
+interface KeyEventRepository {
+ /** Observable for whether the power button key is pressed/down or not. */
+ val isPowerButtonDown: Flow<Boolean>
+}
+
+@SysUISingleton
+class KeyEventRepositoryImpl
+@Inject
+constructor(
+ val commandQueue: CommandQueue,
+) : KeyEventRepository {
+ override val isPowerButtonDown: Flow<Boolean> = conflatedCallbackFlow {
+ val callback =
+ object : CommandQueue.Callbacks {
+ override fun handleSystemKey(event: KeyEvent) {
+ if (event.keyCode == KeyEvent.KEYCODE_POWER) {
+ trySendWithFailureLogging(event.isDown, TAG, "updated isPowerButtonDown")
+ }
+ }
+ }
+ commandQueue.addCallback(callback)
+ awaitClose { commandQueue.removeCallback(callback) }
+ }
+
+ companion object {
+ private const val TAG = "KeyEventRepositoryImpl"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryModule.kt
new file mode 100644
index 000000000000..afba5dbd84c1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyevent/data/repository/KeyEventRepositoryModule.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyevent.data.repository
+
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface KeyEventRepositoryModule {
+ @Binds fun keyEventRepository(impl: KeyEventRepositoryImpl): KeyEventRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractor.kt
index 3f2f67dbba37..9949fa589cd5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractor.kt
@@ -13,55 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.systemui.keyevent.domain.interactor
-import android.view.KeyEvent
-import com.android.systemui.back.domain.interactor.BackActionInteractor
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.domain.interactor.KeyguardKeyEventInteractor
+import com.android.systemui.keyevent.data.repository.KeyEventRepository
import javax.inject.Inject
/**
- * Sends key events to the appropriate interactors and then acts upon key events that haven't
- * already been handled but should be handled by SystemUI.
+ * Business logic for all key event state. This includes all key events, regardless of whether
+ * they've been handled or not by a consumer.
+ *
+ * For key events that SysUI wants to properly handle, see [SysUIKeyEventHandler].
*/
@SysUISingleton
class KeyEventInteractor
@Inject
constructor(
- private val backActionInteractor: BackActionInteractor,
- private val keyguardKeyEventInteractor: KeyguardKeyEventInteractor,
+ repository: KeyEventRepository,
) {
- fun dispatchKeyEvent(event: KeyEvent): Boolean {
- if (keyguardKeyEventInteractor.dispatchKeyEvent(event)) {
- return true
- }
-
- when (event.keyCode) {
- KeyEvent.KEYCODE_BACK -> {
- if (event.handleAction()) {
- backActionInteractor.onBackRequested()
- }
- return true
- }
- }
- return false
- }
-
- fun interceptMediaKey(event: KeyEvent): Boolean {
- return keyguardKeyEventInteractor.interceptMediaKey(event)
- }
-
- fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
- return keyguardKeyEventInteractor.dispatchKeyEventPreIme(event)
- }
-
- companion object {
- // Most actions shouldn't be handled on the down event and instead handled on subsequent
- // key events like ACTION_UP.
- fun KeyEvent.handleAction(): Boolean {
- return action != KeyEvent.ACTION_DOWN
- }
- }
+ val isPowerButtonDown = repository.isPowerButtonDown
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt b/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt
new file mode 100644
index 000000000000..1febc79b8241
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandler.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyevent.domain.interactor
+
+import android.view.KeyEvent
+import com.android.systemui.back.domain.interactor.BackActionInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardKeyEventInteractor
+import javax.inject.Inject
+
+/**
+ * Sends key events to the appropriate interactors and then acts upon key events that haven't
+ * already been handled but should be handled by SystemUI.
+ *
+ * To observe any key event states, see [KeyEventInteractor].
+ */
+@SysUISingleton
+class SysUIKeyEventHandler
+@Inject
+constructor(
+ private val backActionInteractor: BackActionInteractor,
+ private val keyguardKeyEventInteractor: KeyguardKeyEventInteractor,
+) {
+ fun dispatchKeyEvent(event: KeyEvent): Boolean {
+ if (keyguardKeyEventInteractor.dispatchKeyEvent(event)) {
+ return true
+ }
+
+ when (event.keyCode) {
+ KeyEvent.KEYCODE_BACK -> {
+ if (event.handleAction()) {
+ backActionInteractor.onBackRequested()
+ }
+ return true
+ }
+ }
+ return false
+ }
+
+ fun interceptMediaKey(event: KeyEvent): Boolean {
+ return keyguardKeyEventInteractor.interceptMediaKey(event)
+ }
+
+ fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
+ return keyguardKeyEventInteractor.dispatchKeyEventPreIme(event)
+ }
+
+ companion object {
+ // Most actions shouldn't be handled on the down event and instead handled on subsequent
+ // key events like ACTION_UP.
+ fun KeyEvent.handleAction(): Boolean {
+ return action != KeyEvent.ACTION_DOWN
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt
index d69876292024..6d084563cbb3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt
@@ -21,7 +21,7 @@ import android.media.AudioManager
import android.view.KeyEvent
import com.android.systemui.back.domain.interactor.BackActionInteractor
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor.Companion.handleAction
+import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler.Companion.handleAction
import com.android.systemui.media.controls.util.MediaSessionLegacyHelperWrapper
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.domain.interactor.PowerInteractor
@@ -29,15 +29,16 @@ import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
/** Handles key events arriving when the keyguard is showing or device is dozing. */
+@ExperimentalCoroutinesApi
@SysUISingleton
class KeyguardKeyEventInteractor
@Inject
constructor(
private val context: Context,
private val statusBarStateController: StatusBarStateController,
- private val keyguardInteractor: KeyguardInteractor,
private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
private val shadeController: ShadeController,
private val mediaSessionLegacyHelperWrapper: MediaSessionLegacyHelperWrapper,
@@ -56,7 +57,11 @@ constructor(
if (event.handleAction()) {
when (event.keyCode) {
KeyEvent.KEYCODE_MENU -> return dispatchMenuKeyEvent()
- KeyEvent.KEYCODE_SPACE -> return dispatchSpaceEvent()
+ KeyEvent.KEYCODE_SPACE,
+ KeyEvent.KEYCODE_ENTER ->
+ if (isDeviceAwake()) {
+ return collapseShadeLockedOrShowPrimaryBouncer()
+ }
}
}
return false
@@ -92,16 +97,24 @@ constructor(
(statusBarStateController.state != StatusBarState.SHADE) &&
statusBarKeyguardViewManager.shouldDismissOnMenuPressed()
if (shouldUnlockOnMenuPressed) {
- shadeController.animateCollapseShadeForced()
- return true
+ return collapseShadeLockedOrShowPrimaryBouncer()
}
return false
}
- private fun dispatchSpaceEvent(): Boolean {
- if (isDeviceAwake() && statusBarStateController.state != StatusBarState.SHADE) {
- shadeController.animateCollapseShadeForced()
- return true
+ private fun collapseShadeLockedOrShowPrimaryBouncer(): Boolean {
+ when (statusBarStateController.state) {
+ StatusBarState.SHADE -> return false
+ StatusBarState.SHADE_LOCKED -> {
+ shadeController.animateCollapseShadeForced()
+ return true
+ }
+ StatusBarState.KEYGUARD -> {
+ if (!statusBarKeyguardViewManager.primaryBouncerIsShowing()) {
+ statusBarKeyguardViewManager.showPrimaryBouncer(true)
+ return true
+ }
+ }
}
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index abc30efec716..c5a8375f5576 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -47,6 +47,7 @@ import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.doOnEnd
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -402,6 +403,9 @@ object KeyguardBottomAreaViewBinder {
KeyguardBottomAreaVibrations.ShakeAnimationDuration.inWholeMilliseconds
shakeAnimator.interpolator =
CycleInterpolator(KeyguardBottomAreaVibrations.ShakeAnimationCycles)
+ shakeAnimator.doOnEnd {
+ view.translationX = 0f
+ }
shakeAnimator.start()
vibratorHelper?.vibrate(KeyguardBottomAreaVibrations.Shake)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index f0d118cbe20f..99025acef70d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -41,6 +41,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewMod
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.doOnEnd
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
@@ -240,6 +241,9 @@ object KeyguardQuickAffordanceViewBinder {
KeyguardBottomAreaVibrations.ShakeAnimationDuration.inWholeMilliseconds
shakeAnimator.interpolator =
CycleInterpolator(KeyguardBottomAreaVibrations.ShakeAnimationCycles)
+ shakeAnimator.doOnEnd {
+ view.translationX = 0f
+ }
shakeAnimator.start()
vibratorHelper?.vibrate(KeyguardBottomAreaVibrations.Shake)
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
index 72aea040ba05..2217509167ef 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
@@ -33,6 +33,8 @@ import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnail
import com.android.systemui.mediaprojection.appselector.data.ShellRecentTaskListProvider
import com.android.systemui.mediaprojection.appselector.view.MediaProjectionRecentsViewController
import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider
+import com.android.systemui.mediaprojection.appselector.view.WindowMetricsProvider
+import com.android.systemui.mediaprojection.appselector.view.WindowMetricsProviderImpl
import com.android.systemui.mediaprojection.devicepolicy.MediaProjectionDevicePolicyModule
import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile
import com.android.systemui.mediaprojection.permission.MediaProjectionPermissionActivity
@@ -106,6 +108,8 @@ interface MediaProjectionAppSelectorModule {
impl: TaskPreviewSizeProvider
): DefaultLifecycleObserver
+ @Binds fun windowMetricsProvider(impl: WindowMetricsProviderImpl): WindowMetricsProvider
+
companion object {
@Provides
@MediaProjectionAppSelector
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt
index 864d35af41b4..c829471f53f3 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt
@@ -19,8 +19,6 @@ package com.android.systemui.mediaprojection.appselector.view
import android.content.Context
import android.content.res.Configuration
import android.graphics.Rect
-import android.view.WindowInsets.Type
-import android.view.WindowManager
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorScope
@@ -36,7 +34,7 @@ class TaskPreviewSizeProvider
@Inject
constructor(
private val context: Context,
- private val windowManager: WindowManager,
+ private val windowMetricsProvider: WindowMetricsProvider,
private val configurationController: ConfigurationController,
) : CallbackController<TaskPreviewSizeListener>, ConfigurationListener, DefaultLifecycleObserver {
@@ -62,17 +60,14 @@ constructor(
}
private fun calculateSize(): Rect {
- val windowMetrics = windowManager.maximumWindowMetrics
- val maximumWindowHeight = windowMetrics.bounds.height()
- val width = windowMetrics.bounds.width()
+ val maxWindowBounds = windowMetricsProvider.maximumWindowBounds
+ val maximumWindowHeight = maxWindowBounds.height()
+ val width = maxWindowBounds.width()
var height = maximumWindowHeight
val isLargeScreen = isLargeScreen(context)
if (isLargeScreen) {
- val taskbarSize =
- windowManager.currentWindowMetrics.windowInsets
- .getInsets(Type.tappableElement())
- .bottom
+ val taskbarSize = windowMetricsProvider.currentWindowInsets.bottom
height -= taskbarSize
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProvider.kt
new file mode 100644
index 000000000000..193292032868
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProvider.kt
@@ -0,0 +1,30 @@
+package com.android.systemui.mediaprojection.appselector.view
+
+import android.graphics.Insets
+import android.graphics.Rect
+import android.view.WindowInsets
+import android.view.WindowManager
+import javax.inject.Inject
+
+/** Provides values related to window metrics. */
+interface WindowMetricsProvider {
+
+ val maximumWindowBounds: Rect
+
+ val currentWindowInsets: Insets
+}
+
+class WindowMetricsProviderImpl
+@Inject
+constructor(
+ private val windowManager: WindowManager,
+) : WindowMetricsProvider {
+ override val maximumWindowBounds: Rect
+ get() = windowManager.maximumWindowMetrics.bounds
+
+ override val currentWindowInsets: Insets
+ get() =
+ windowManager.currentWindowMetrics.windowInsets.getInsets(
+ WindowInsets.Type.tappableElement()
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 2b56d0cf9f83..d08d0400f354 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -239,6 +239,8 @@ public class MediaProjectionPermissionActivity extends Activity
protected void onDestroy() {
super.onDestroy();
if (mDialog != null) {
+ mDialog.setOnDismissListener(null);
+ mDialog.setOnCancelListener(null);
mDialog.dismiss();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.java b/packages/SystemUI/src/com/android/systemui/model/SysUiState.java
index 07846b56d784..3cdcb2c4f550 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.java
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.java
@@ -24,6 +24,8 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.shared.system.QuickStepContract;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -108,6 +110,7 @@ public class SysUiState implements Dumpable {
}
}
+ @NeverCompile
@Override
public void dump(PrintWriter pw, String[] args) {
pw.println("SysUiState state:");
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index 564e984fbce2..2928cceb35aa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -65,6 +65,8 @@ import com.android.systemui.util.settings.SecureSettings;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.pip.Pip;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.util.Optional;
@@ -476,6 +478,7 @@ public class NavigationBarControllerImpl implements
return mNavigationBars.get(mDisplayTracker.getDefaultDisplayId());
}
+ @NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("mIsLargeScreen=" + mIsLargeScreen);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 4d6d95a05b1b..bc4f7f2513ce 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -584,7 +584,6 @@ public class NavigationBarView extends FrameLayout {
if (!visible) {
mTransitionListener.onBackAltCleared();
}
- mRotationButtonController.getRotationButton().setCanShowRotationButton(!visible);
}
void setDisabledFlags(int disabledFlags, SysUiState sysUiState) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
index 202254bb323f..4aad6a069cbb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
@@ -72,6 +72,8 @@ import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.Utils;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.function.Consumer;
@@ -934,6 +936,7 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl
return mListeningAndVisibilityLifecycleOwner;
}
+ @NeverCompile
@Override
public void dump(PrintWriter pw, String[] args) {
IndentingPrintWriter indentingPw = new IndentingPrintWriter(pw, /* singleIndent= */ " ");
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 584456d79890..91b4d1778e1c 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -42,6 +42,7 @@ import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICA
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -51,7 +52,6 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch
-import javax.inject.Inject
/**
* Hooks up business logic that manipulates the state of the [SceneInteractor] for the system UI
@@ -142,7 +142,7 @@ constructor(
// When the device becomes unlocked in Lockscreen, go to Gone if
// bypass is enabled.
renderedScenes.contains(SceneKey.Lockscreen) ->
- if (deviceEntryInteractor.isBypassEnabled()) {
+ if (deviceEntryInteractor.isBypassEnabled.value) {
SceneKey.Gone to
"device unlocked in Lockscreen scene with bypass"
} else {
@@ -179,36 +179,34 @@ constructor(
}
applicationScope.launch {
- powerInteractor.isAsleep
- .collect { isAsleep ->
- if (isAsleep) {
- switchToScene(
- targetSceneKey = SceneKey.Lockscreen,
- loggingReason = "device is starting to sleep",
- )
- } else {
- val authMethod = authenticationInteractor.getAuthenticationMethod()
- val isUnlocked = deviceEntryInteractor.isUnlocked.value
- when {
- authMethod == AuthenticationMethodModel.None -> {
- switchToScene(
- targetSceneKey = SceneKey.Gone,
- loggingReason =
- "device is starting to wake up while auth method is" +
- " none",
- )
- }
- authMethod.isSecure && isUnlocked -> {
- switchToScene(
- targetSceneKey = SceneKey.Gone,
- loggingReason =
- "device is starting to wake up while unlocked with a" +
- " secure auth method",
- )
- }
+ powerInteractor.isAsleep.collect { isAsleep ->
+ if (isAsleep) {
+ switchToScene(
+ targetSceneKey = SceneKey.Lockscreen,
+ loggingReason = "device is starting to sleep",
+ )
+ } else {
+ val authMethod = authenticationInteractor.getAuthenticationMethod()
+ val isUnlocked = deviceEntryInteractor.isUnlocked.value
+ when {
+ authMethod == AuthenticationMethodModel.None -> {
+ switchToScene(
+ targetSceneKey = SceneKey.Gone,
+ loggingReason =
+ "device is starting to wake up while auth method is" + " none",
+ )
+ }
+ authMethod.isSecure && isUnlocked -> {
+ switchToScene(
+ targetSceneKey = SceneKey.Gone,
+ loggingReason =
+ "device is starting to wake up while unlocked with a" +
+ " secure auth method",
+ )
}
}
}
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
index 4bc93a8f1ca5..2e45353634fe 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
@@ -61,12 +61,17 @@ sealed interface UserAction {
data class Swipe(
/** The direction of the swipe. */
val direction: Direction,
+ /**
+ * The edge from which the swipe originated or `null`, if the swipe didn't start close to an
+ * edge.
+ */
+ val fromEdge: Edge? = null,
/** The number of pointers that were used (for example, one or two fingers). */
val pointerCount: Int = 1,
) : UserAction
/** The user has hit the back button or performed the back navigation gesture. */
- object Back : UserAction
+ data object Back : UserAction
}
/** Enumerates all known "cardinal" directions for user actions. */
@@ -76,3 +81,11 @@ enum class Direction {
RIGHT,
DOWN,
}
+
+/** Enumerates all known edges from which a swipe can start. */
+enum class Edge {
+ LEFT,
+ TOP,
+ RIGHT,
+ BOTTOM,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 2ef83dd42868..ba0cf08150f6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -230,6 +230,8 @@ import com.android.systemui.util.Utils;
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
+import dalvik.annotation.optimization.NeverCompile;
+
import kotlin.Unit;
import java.io.PrintWriter;
@@ -3379,6 +3381,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mBlockingExpansionForCurrentTouch = isTracking();
}
+ @NeverCompile
@Override
public void dump(PrintWriter pw, String[] args) {
pw.println(TAG + ":");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 5414b3f30aa5..d05dfe2c11c1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -48,7 +48,7 @@ import com.android.systemui.dock.DockManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
-import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor;
+import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.TransitionState;
@@ -106,7 +106,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
private final NotificationInsetsController mNotificationInsetsController;
private final boolean mIsTrackpadCommonEnabled;
private final FeatureFlags mFeatureFlags;
- private final KeyEventInteractor mKeyEventInteractor;
+ private final SysUIKeyEventHandler mSysUIKeyEventHandler;
private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private GestureDetector mPulsingWakeupGestureHandler;
@@ -185,7 +185,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
SystemClock clock,
BouncerMessageInteractor bouncerMessageInteractor,
BouncerLogger bouncerLogger,
- KeyEventInteractor keyEventInteractor,
+ SysUIKeyEventHandler sysUIKeyEventHandler,
PrimaryBouncerInteractor primaryBouncerInteractor,
AlternateBouncerInteractor alternateBouncerInteractor) {
mLockscreenShadeTransitionController = transitionController;
@@ -214,7 +214,7 @@ public class NotificationShadeWindowViewController implements Dumpable {
mNotificationInsetsController = notificationInsetsController;
mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON);
mFeatureFlags = featureFlags;
- mKeyEventInteractor = keyEventInteractor;
+ mSysUIKeyEventHandler = sysUIKeyEventHandler;
mPrimaryBouncerInteractor = primaryBouncerInteractor;
mAlternateBouncerInteractor = alternateBouncerInteractor;
@@ -529,17 +529,17 @@ public class NotificationShadeWindowViewController implements Dumpable {
@Override
public boolean interceptMediaKey(KeyEvent event) {
- return mKeyEventInteractor.interceptMediaKey(event);
+ return mSysUIKeyEventHandler.interceptMediaKey(event);
}
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
- return mKeyEventInteractor.dispatchKeyEventPreIme(event);
+ return mSysUIKeyEventHandler.dispatchKeyEventPreIme(event);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- return mKeyEventInteractor.dispatchKeyEvent(event);
+ return mSysUIKeyEventHandler.dispatchKeyEvent(event);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index 9b74ac4afed4..3bbb2cf83a83 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -105,6 +105,8 @@ import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.LargeScreenUtils;
import com.android.systemui.util.kotlin.JavaAdapter;
+import dalvik.annotation.optimization.NeverCompile;
+
import dagger.Lazy;
import java.io.PrintWriter;
@@ -2015,6 +2017,7 @@ public class QuickSettingsController implements Dumpable {
(int) ((y - getInitialTouchY()) / displayDensity), (int) (vel / displayDensity));
}
+ @NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println(TAG + ":");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index d24f9d8f476c..77b095802b00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar;
import android.view.View;
+import androidx.annotation.Nullable;
+
import com.android.app.animation.Interpolators;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
@@ -113,7 +115,16 @@ public class CrossFadeHelper {
fadeIn(view, ANIMATION_DURATION_LENGTH, 0);
}
+ public static void fadeIn(final View view, Runnable endRunnable) {
+ fadeIn(view, ANIMATION_DURATION_LENGTH, /* delay= */ 0, endRunnable);
+ }
+
public static void fadeIn(final View view, long duration, int delay) {
+ fadeIn(view, duration, delay, /* endRunnable= */ null);
+ }
+
+ public static void fadeIn(final View view, long duration, int delay,
+ @Nullable Runnable endRunnable) {
view.animate().cancel();
if (view.getVisibility() == View.INVISIBLE) {
view.setAlpha(0.0f);
@@ -124,7 +135,7 @@ public class CrossFadeHelper {
.setDuration(duration)
.setStartDelay(delay)
.setInterpolator(Interpolators.ALPHA_IN)
- .withEndAction(null);
+ .withEndAction(endRunnable);
if (view.hasOverlappingRendering() && view.getLayerType() != View.LAYER_TYPE_HARDWARE) {
view.animate().withLayer();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index f616b91c4712..3a4ad0e79994 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -51,6 +51,7 @@ import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Interpolator;
+import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import com.android.app.animation.Interpolators;
@@ -959,12 +960,17 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
public void setDozing(boolean dozing, boolean fade, long delay) {
+ setDozing(dozing, fade, delay, /* onChildCompleted= */ null);
+ }
+
+ public void setDozing(boolean dozing, boolean fade, long delay,
+ @Nullable Runnable endRunnable) {
mDozer.setDozing(f -> {
mDozeAmount = f;
updateDecorColor();
updateIconColor();
updateAllowAnimation();
- }, dozing, fade, delay, this);
+ }, dozing, fade, delay, this, endRunnable);
}
private void updateAllowAnimation() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 9db61c6b3ba2..fc84973c46bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -83,6 +83,8 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceP
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.CarrierConfigTracker;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -1154,6 +1156,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
/** */
+ @NeverCompile
public void dump(PrintWriter pw, String[] args) {
pw.println("NetworkController state:");
pw.println(" mUserSetup=" + mUserSetup);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index 167efc784ff5..dc0eb7b4aab3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -24,6 +24,8 @@ import android.graphics.ColorMatrixColorFilter;
import android.view.View;
import android.widget.ImageView;
+import androidx.annotation.Nullable;
+
import com.android.app.animation.Interpolators;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
@@ -81,6 +83,11 @@ public class NotificationDozeHelper {
public void setDozing(Consumer<Float> listener, boolean dozing,
boolean animate, long delay, View view) {
+ setDozing(listener, dozing, animate, delay, view, /* endRunnable= */ null);
+ }
+
+ public void setDozing(Consumer<Float> listener, boolean dozing,
+ boolean animate, long delay, View view, @Nullable Runnable endRunnable) {
if (animate) {
startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dozing,
delay,
@@ -89,6 +96,9 @@ public class NotificationDozeHelper {
@Override
public void onAnimationEnd(Animator animation) {
view.setTag(DOZE_ANIMATOR_TAG, null);
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
}
@Override
@@ -102,6 +112,9 @@ public class NotificationDozeHelper {
animator.cancel();
}
listener.accept(dozing ? 1f : 0f);
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 733d774f8b80..8561869af352 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.notification.collection.render.GroupMember
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.data.NotificationDataLayerModule;
import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository;
import com.android.systemui.statusbar.notification.icon.ConversationIconManager;
import com.android.systemui.statusbar.notification.icon.IconManager;
@@ -95,6 +96,7 @@ import javax.inject.Provider;
CoordinatorsModule.class,
KeyguardNotificationVisibilityProviderModule.class,
ShadeEventsModule.class,
+ NotificationDataLayerModule.class,
NotifPipelineChoreographerModule.class,
NotificationSectionHeadersModule.class,
NotificationListViewModelModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt
new file mode 100644
index 000000000000..5435fb5449cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.data
+
+import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardStateRepositoryModule
+import dagger.Module
+
+@Module(includes = [NotificationsKeyguardStateRepositoryModule::class])
+interface NotificationDataLayerModule
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepository.kt
new file mode 100644
index 000000000000..cf03d1c5addc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepository.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.data.repository
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/** View-states pertaining to notifications on the keyguard. */
+interface NotificationsKeyguardViewStateRepository {
+ /** Are notifications fully hidden from view? */
+ val areNotificationsFullyHidden: Flow<Boolean>
+
+ /** Is a pulse expansion occurring? */
+ val isPulseExpanding: Flow<Boolean>
+}
+
+@Module
+interface NotificationsKeyguardStateRepositoryModule {
+ @Binds
+ fun bindImpl(
+ impl: NotificationsKeyguardViewStateRepositoryImpl
+ ): NotificationsKeyguardViewStateRepository
+}
+
+@SysUISingleton
+class NotificationsKeyguardViewStateRepositoryImpl
+@Inject
+constructor(
+ wakeUpCoordinator: NotificationWakeUpCoordinator,
+) : NotificationsKeyguardViewStateRepository {
+ override val areNotificationsFullyHidden: Flow<Boolean> = conflatedCallbackFlow {
+ val listener =
+ object : NotificationWakeUpCoordinator.WakeUpListener {
+ override fun onFullyHiddenChanged(isFullyHidden: Boolean) {
+ trySend(isFullyHidden)
+ }
+ }
+ trySend(wakeUpCoordinator.notificationsFullyHidden)
+ wakeUpCoordinator.addListener(listener)
+ awaitClose { wakeUpCoordinator.removeListener(listener) }
+ }
+
+ override val isPulseExpanding: Flow<Boolean> = conflatedCallbackFlow {
+ val listener =
+ object : NotificationWakeUpCoordinator.WakeUpListener {
+ override fun onPulseExpansionChanged(expandingChanged: Boolean) {
+ trySend(expandingChanged)
+ }
+ }
+ trySend(wakeUpCoordinator.isPulseExpanding())
+ wakeUpCoordinator.addListener(listener)
+ awaitClose { wakeUpCoordinator.removeListener(listener) }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractor.kt
new file mode 100644
index 000000000000..87b8e55dbd1a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractor.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.domain.interactor
+
+import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+/** Domain logic pertaining to notifications on the keyguard. */
+class NotificationsKeyguardInteractor
+@Inject
+constructor(
+ repository: NotificationsKeyguardViewStateRepository,
+) {
+ /** Is a pulse expansion occurring? */
+ val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding
+
+ /** Are notifications fully hidden from view? */
+ val areNotificationsFullyHidden: Flow<Boolean> = repository.areNotificationsFullyHidden
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
index 26db5f2bc095..e74b3fcdf050 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
@@ -11,10 +11,10 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.notification.row;
+package com.android.systemui.statusbar.notification.footer.ui.view;
import static android.graphics.PorterDuff.Mode.SRC_ATOP;
@@ -35,6 +35,8 @@ import androidx.annotation.NonNull;
import com.android.settingslib.Utils;
import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.row.FooterViewButton;
+import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.util.DumpUtilsKt;
@@ -93,6 +95,7 @@ public class FooterView extends StackScrollerDecorView {
updateColors();
}
+ /** Show a message instead of the footer buttons. */
public void setFooterLabelVisible(boolean isVisible) {
if (isVisible) {
mManageButton.setVisibility(View.GONE);
@@ -105,14 +108,22 @@ public class FooterView extends StackScrollerDecorView {
}
}
+ /** Set onClickListener for the manage/history button. */
public void setManageButtonClickListener(OnClickListener listener) {
mManageButton.setOnClickListener(listener);
}
+ /** Set onClickListener for the clear all (end) button. */
public void setClearAllButtonClickListener(OnClickListener listener) {
mClearAllButton.setOnClickListener(listener);
}
+ /**
+ * Whether the touch is outside the Clear all button.
+ *
+ * TODO(b/293167744): This is an artifact from the time when we could press underneath the
+ * shade to dismiss it. Check if it's safe to remove.
+ */
public boolean isOnEmptySpace(float touchX, float touchY) {
return touchX < mContent.getX()
|| touchX > mContent.getX() + mContent.getWidth()
@@ -120,6 +131,7 @@ public class FooterView extends StackScrollerDecorView {
|| touchY > mContent.getY() + mContent.getHeight();
}
+ /** Show "History" instead of "Manage" on the start button. */
public void showHistory(boolean showHistory) {
if (mShowHistory == showHistory) {
return;
@@ -141,6 +153,7 @@ public class FooterView extends StackScrollerDecorView {
.setCompoundDrawablesRelative(mSeenNotifsFilteredIcon, null, null, null);
}
+ /** Whether the start button shows "History" (true) or "Manage" (false). */
public boolean isHistoryShown() {
return mShowHistory;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
index a77e67b6908d..805a4dba111f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
@@ -26,26 +26,21 @@ import android.widget.FrameLayout
import androidx.annotation.ColorInt
import androidx.annotation.VisibleForTesting
import androidx.collection.ArrayMap
-import com.android.app.animation.Interpolators
import com.android.internal.statusbar.StatusBarIcon
import com.android.internal.util.ContrastColorUtil
import com.android.settingslib.Utils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
-import com.android.systemui.flags.Flags.NEW_AOD_TRANSITION
import com.android.systemui.flags.ViewRefactorFlag
import com.android.systemui.plugins.DarkIconDispatcher
-import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
-import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.NotificationListener
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.NotificationShelfController
import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.NotificationUtils
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.collection.ListEntry
@@ -60,6 +55,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.NotificationIconAreaController
import com.android.systemui.statusbar.phone.NotificationIconContainer
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
@@ -79,9 +75,9 @@ class NotificationIconAreaControllerViewBinderWrapperImpl
@Inject
constructor(
private val context: Context,
- private val statusBarStateController: StatusBarStateController,
private val wakeUpCoordinator: NotificationWakeUpCoordinator,
private val bypassController: KeyguardBypassController,
+ private val configurationController: ConfigurationController,
private val mediaManager: NotificationMediaManager,
notificationListener: NotificationListener,
private val dozeParameters: DozeParameters,
@@ -89,7 +85,7 @@ constructor(
private val bubblesOptional: Optional<Bubbles>,
demoModeController: DemoModeController,
darkIconDispatcher: DarkIconDispatcher,
- private val featureFlags: FeatureFlags,
+ private val featureFlags: FeatureFlagsClassic,
private val statusBarWindowController: StatusBarWindowController,
private val screenOffAnimationController: ScreenOffAnimationController,
private val shelfIconsViewModel: NotificationIconContainerShelfViewModel,
@@ -98,14 +94,12 @@ constructor(
) :
NotificationIconAreaController,
DarkIconDispatcher.DarkReceiver,
- StatusBarStateController.StateListener,
NotificationWakeUpCoordinator.WakeUpListener,
DemoMode {
private val contrastColorUtil: ContrastColorUtil = ContrastColorUtil.getInstance(context)
private val updateStatusBarIcons = Runnable { updateStatusBarIcons() }
private val shelfRefactor = ViewRefactorFlag(featureFlags, Flags.NOTIFICATION_SHELF_REFACTOR)
- private val statusViewMigrated = featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)
private val tintAreas = ArrayList<Rect>()
private var iconSize = 0
@@ -119,7 +113,6 @@ constructor(
private var aodBindJob: DisposableHandle? = null
private var aodIconAppearTranslation = 0
private var aodIconTint = 0
- private var aodIconsVisible = false
private var showLowPriority = true
@VisibleForTesting
@@ -132,7 +125,6 @@ constructor(
}
init {
- statusBarStateController.addCallback(this)
wakeUpCoordinator.addListener(this)
demoModeController.addCallback(this)
notificationListener.addNotificationSettingsListener(settingsListener)
@@ -160,8 +152,11 @@ constructor(
NotificationIconContainerViewBinder.bind(
aodIcons,
aodIconsViewModel,
+ configurationController,
+ dozeParameters,
+ featureFlags,
+ screenOffAnimationController,
)
- updateAodIconsVisibility(animate = false, forceUpdate = changed)
if (changed) {
updateAodNotificationIcons()
}
@@ -176,6 +171,10 @@ constructor(
NotificationIconContainerViewBinder.bind(
icons,
shelfIconsViewModel,
+ configurationController,
+ dozeParameters,
+ featureFlags,
+ screenOffAnimationController,
)
shelfIcons = icons
}
@@ -249,20 +248,8 @@ constructor(
notificationIcons!!.setIsolatedIconLocation(iconDrawingRect, requireStateUpdate)
}
- override fun onDozingChanged(isDozing: Boolean) {
- if (aodIcons == null) {
- return
- }
- val animate = (dozeParameters.alwaysOn && !dozeParameters.displayNeedsBlanking)
- aodIcons!!.setDozing(isDozing, animate, 0)
- }
-
override fun setAnimationsEnabled(enabled: Boolean) = unsupported
- override fun onStateChanged(newState: Int) {
- updateAodIconsVisibility(animate = false, forceUpdate = false)
- }
-
override fun onThemeChanged() {
reloadAodColor()
updateAodIconColors()
@@ -272,53 +259,11 @@ constructor(
return if (aodIcons == null) 0 else aodIcons!!.height
}
- @VisibleForTesting
- fun appearAodIcons() {
- if (aodIcons == null) {
- return
- }
- if (screenOffAnimationController.shouldAnimateAodIcons()) {
- if (!statusViewMigrated) {
- aodIcons!!.translationY = -aodIconAppearTranslation.toFloat()
- }
- aodIcons!!.alpha = 0f
- animateInAodIconTranslation()
- aodIcons!!
- .animate()
- .alpha(1f)
- .setInterpolator(Interpolators.LINEAR)
- .setDuration(AOD_ICONS_APPEAR_DURATION)
- .start()
- } else {
- aodIcons!!.alpha = 1.0f
- if (!statusViewMigrated) {
- aodIcons!!.translationY = 0f
- }
- }
- }
-
override fun onFullyHiddenChanged(isFullyHidden: Boolean) {
- var animate = true
- if (!bypassController.bypassEnabled) {
- animate = dozeParameters.alwaysOn && !dozeParameters.displayNeedsBlanking
- if (!featureFlags.isEnabled(NEW_AOD_TRANSITION)) {
- // We only want the appear animations to happen when the notifications get fully
- // hidden,
- // since otherwise the unhide animation overlaps
- animate = animate and isFullyHidden
- }
- }
- updateAodIconsVisibility(animate, false /* force */)
updateAodNotificationIcons()
updateAodIconColors()
}
- override fun onPulseExpansionChanged(expandingChanged: Boolean) {
- if (expandingChanged) {
- updateAodIconsVisibility(animate = true, forceUpdate = false)
- }
- }
-
override fun demoCommands(): List<String> {
val commands = ArrayList<String>()
commands.add(DemoMode.COMMAND_NOTIFICATIONS)
@@ -352,6 +297,10 @@ constructor(
NotificationIconContainerViewBinder.bind(
notificationIcons!!,
statusBarIconsViewModel,
+ configurationController,
+ dozeParameters,
+ featureFlags,
+ screenOffAnimationController,
)
}
@@ -602,17 +551,6 @@ constructor(
v.setDecorColor(tint)
}
- private fun animateInAodIconTranslation() {
- if (!statusViewMigrated) {
- aodIcons!!
- .animate()
- .setInterpolator(Interpolators.DECELERATE_QUINT)
- .translationY(0f)
- .setDuration(AOD_ICONS_APPEAR_DURATION)
- .start()
- }
- }
-
private fun reloadAodColor() {
aodIconTint =
Utils.getColorAttrDefaultColor(
@@ -635,69 +573,7 @@ constructor(
}
}
- private fun updateAodIconsVisibility(animate: Boolean, forceUpdate: Boolean) {
- if (aodIcons == null) {
- return
- }
- var visible = (bypassController.bypassEnabled || wakeUpCoordinator.notificationsFullyHidden)
-
- // Hide the AOD icons if we're not in the KEYGUARD state unless the screen off animation is
- // playing, in which case we want them to be visible since we're animating in the AOD UI and
- // will be switching to KEYGUARD shortly.
- if (
- statusBarStateController.state != StatusBarState.KEYGUARD &&
- !screenOffAnimationController.shouldShowAodIconsWhenShade()
- ) {
- visible = false
- }
- if (visible && wakeUpCoordinator.isPulseExpanding() && !bypassController.bypassEnabled) {
- visible = false
- }
- if (aodIconsVisible != visible || forceUpdate) {
- aodIconsVisible = visible
- aodIcons!!.animate().cancel()
- if (animate) {
- if (featureFlags.isEnabled(NEW_AOD_TRANSITION)) {
- // Let's make sure the icon are translated to 0, since we cancelled it above
- animateInAodIconTranslation()
- if (aodIconsVisible) {
- CrossFadeHelper.fadeIn(aodIcons)
- } else {
- CrossFadeHelper.fadeOut(aodIcons)
- }
- } else {
- val wasFullyInvisible = aodIcons!!.visibility != View.VISIBLE
- if (aodIconsVisible) {
- if (wasFullyInvisible) {
- // No fading here, let's just appear the icons instead!
- aodIcons!!.visibility = View.VISIBLE
- aodIcons!!.alpha = 1.0f
- appearAodIcons()
- } else {
- // Let's make sure the icon are translated to 0, since we cancelled it
- // above
- animateInAodIconTranslation()
- // We were fading out, let's fade in instead
- CrossFadeHelper.fadeIn(aodIcons)
- }
- } else {
- // Let's make sure the icon are translated to 0, since we cancelled it above
- animateInAodIconTranslation()
- CrossFadeHelper.fadeOut(aodIcons)
- }
- }
- } else {
- aodIcons!!.alpha = 1.0f
- if (!statusViewMigrated) {
- aodIcons!!.translationY = 0f
- }
- aodIcons!!.visibility = if (visible) View.VISIBLE else View.INVISIBLE
- }
- }
- }
-
companion object {
- private const val AOD_ICONS_APPEAR_DURATION: Long = 200
@ColorInt private val DEFAULT_AOD_ICON_COLOR = -0x1
val unsupported: Nothing
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
index f8ff3e393033..0d2f00aa3627 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
@@ -15,12 +15,27 @@
*/
package com.android.systemui.statusbar.notification.icon.ui.viewbinder
+import android.content.res.Resources
+import android.view.View
+import androidx.annotation.DimenRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.animation.Interpolators
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.flags.Flags
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel
+import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.NotificationIconContainer
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.onDensityOrFontScaleChanged
+import com.android.systemui.util.kotlin.stateFlow
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
/** Binds a [NotificationIconContainer] to its [view model][NotificationIconContainerViewModel]. */
@@ -28,11 +43,144 @@ object NotificationIconContainerViewBinder {
fun bind(
view: NotificationIconContainer,
viewModel: NotificationIconContainerViewModel,
+ configurationController: ConfigurationController,
+ dozeParameters: DozeParameters,
+ featureFlags: FeatureFlagsClassic,
+ screenOffAnimationController: ScreenOffAnimationController,
): DisposableHandle {
return view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
launch { viewModel.animationsEnabled.collect(view::setAnimationsEnabled) }
+ launch {
+ viewModel.isDozing.collect { (isDozing, animate) ->
+ val animateIfNotBlanking = animate && !dozeParameters.displayNeedsBlanking
+ view.setDozing(isDozing, animateIfNotBlanking, /* delay= */ 0) {
+ viewModel.completeDozeAnimation()
+ }
+ }
+ }
+ // TODO(278765923): this should live where AOD is bound, not inside of the NIC
+ // view-binder
+ launch {
+ val iconAppearTranslation =
+ view.resources.getConfigAwareDimensionPixelSize(
+ this,
+ configurationController,
+ R.dimen.shelf_appear_translation,
+ )
+ bindVisibility(
+ viewModel,
+ view,
+ featureFlags,
+ screenOffAnimationController,
+ iconAppearTranslation,
+ ) {
+ viewModel.completeVisibilityAnimation()
+ }
+ }
}
}
}
+ private suspend fun bindVisibility(
+ viewModel: NotificationIconContainerViewModel,
+ view: NotificationIconContainer,
+ featureFlags: FeatureFlagsClassic,
+ screenOffAnimationController: ScreenOffAnimationController,
+ iconAppearTranslation: StateFlow<Int>,
+ onAnimationEnd: () -> Unit,
+ ) {
+ val statusViewMigrated = featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)
+ viewModel.isVisible.collect { (isVisible, animate) ->
+ view.animate().cancel()
+ when {
+ !animate -> {
+ view.alpha = 1f
+ if (!statusViewMigrated) {
+ view.translationY = 0f
+ }
+ view.visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
+ }
+ featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> {
+ animateInIconTranslation(view, statusViewMigrated)
+ if (isVisible) {
+ CrossFadeHelper.fadeIn(view, onAnimationEnd)
+ } else {
+ CrossFadeHelper.fadeOut(view, onAnimationEnd)
+ }
+ }
+ !isVisible -> {
+ // Let's make sure the icon are translated to 0, since we cancelled it above
+ animateInIconTranslation(view, statusViewMigrated)
+ CrossFadeHelper.fadeOut(view, onAnimationEnd)
+ }
+ view.visibility != View.VISIBLE -> {
+ // No fading here, let's just appear the icons instead!
+ view.visibility = View.VISIBLE
+ view.alpha = 1f
+ appearIcons(
+ view,
+ animate = screenOffAnimationController.shouldAnimateAodIcons(),
+ iconAppearTranslation.value,
+ statusViewMigrated,
+ )
+ onAnimationEnd()
+ }
+ else -> {
+ // Let's make sure the icons are translated to 0, since we cancelled it above
+ animateInIconTranslation(view, statusViewMigrated)
+ // We were fading out, let's fade in instead
+ CrossFadeHelper.fadeIn(view, onAnimationEnd)
+ }
+ }
+ }
+ }
+
+ private fun appearIcons(
+ view: View,
+ animate: Boolean,
+ iconAppearTranslation: Int,
+ statusViewMigrated: Boolean,
+ ) {
+ if (animate) {
+ if (!statusViewMigrated) {
+ view.translationY = -iconAppearTranslation.toFloat()
+ }
+ view.alpha = 0f
+ animateInIconTranslation(view, statusViewMigrated)
+ view
+ .animate()
+ .alpha(1f)
+ .setInterpolator(Interpolators.LINEAR)
+ .setDuration(AOD_ICONS_APPEAR_DURATION)
+ .start()
+ } else {
+ view.alpha = 1.0f
+ if (!statusViewMigrated) {
+ view.translationY = 0f
+ }
+ }
+ }
+
+ private fun animateInIconTranslation(view: View, statusViewMigrated: Boolean) {
+ if (!statusViewMigrated) {
+ view
+ .animate()
+ .setInterpolator(Interpolators.DECELERATE_QUINT)
+ .translationY(0f)
+ .setDuration(AOD_ICONS_APPEAR_DURATION)
+ .start()
+ }
+ }
+
+ private const val AOD_ICONS_APPEAR_DURATION: Long = 200
}
+
+fun Resources.getConfigAwareDimensionPixelSize(
+ scope: CoroutineScope,
+ configurationController: ConfigurationController,
+ @DimenRes id: Int,
+): StateFlow<Int> =
+ scope.stateFlow(
+ changedSignals = configurationController.onDensityOrFontScaleChanged,
+ getValue = { getDimensionPixelSize(id) }
+ )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
index 90507fc82a79..3289a3ce5574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt
@@ -15,19 +15,48 @@
*/
package com.android.systemui.statusbar.notification.icon.ui.viewmodel
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
+import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.util.kotlin.pairwise
+import com.android.systemui.util.kotlin.sample
+import com.android.systemui.util.ui.AnimatableEvent
+import com.android.systemui.util.ui.AnimatedValue
+import com.android.systemui.util.ui.toAnimatedValueFlow
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
/** View-model for the row of notification icons displayed on the always-on display. */
+@SysUISingleton
class NotificationIconContainerAlwaysOnDisplayViewModel
@Inject
constructor(
+ private val deviceEntryInteractor: DeviceEntryInteractor,
+ private val dozeParameters: DozeParameters,
+ private val featureFlags: FeatureFlagsClassic,
keyguardInteractor: KeyguardInteractor,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ private val notificationsKeyguardInteractor: NotificationsKeyguardInteractor,
+ screenOffAnimationController: ScreenOffAnimationController,
shadeInteractor: ShadeInteractor,
) : NotificationIconContainerViewModel {
+
+ private val onDozeAnimationComplete = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
+ private val onVisAnimationComplete = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
+
override val animationsEnabled: Flow<Boolean> =
combine(
shadeInteractor.isShadeTouchable,
@@ -35,4 +64,97 @@ constructor(
) { panelTouchesEnabled, isKeyguardVisible ->
panelTouchesEnabled && isKeyguardVisible
}
+
+ override val isDozing: Flow<AnimatedValue<Boolean>> =
+ keyguardTransitionInteractor.startedKeyguardTransitionStep
+ // Determine if we're dozing based on the most recent transition
+ .map { step: TransitionStep ->
+ val isDozing = step.to == KeyguardState.AOD || step.to == KeyguardState.DOZING
+ isDozing to step
+ }
+ // Only emit changes based on whether we've started or stopped dozing
+ .distinctUntilChanged { (wasDozing, _), (isDozing, _) -> wasDozing != isDozing }
+ // Determine whether we need to animate
+ .map { (isDozing, step) ->
+ val animate = step.to == KeyguardState.AOD || step.from == KeyguardState.AOD
+ AnimatableEvent(isDozing, animate)
+ }
+ .distinctUntilChanged()
+ .toAnimatedValueFlow(completionEvents = onDozeAnimationComplete)
+
+ override val isVisible: Flow<AnimatedValue<Boolean>> =
+ combine(
+ keyguardTransitionInteractor.finishedKeyguardState.map { it != KeyguardState.GONE },
+ deviceEntryInteractor.isBypassEnabled,
+ areNotifsFullyHiddenAnimated(),
+ isPulseExpandingAnimated(),
+ ) {
+ onKeyguard: Boolean,
+ bypassEnabled: Boolean,
+ (notifsFullyHidden: Boolean, isAnimatingHide: Boolean),
+ (pulseExpanding: Boolean, isAnimatingPulse: Boolean),
+ ->
+ val isAnimating = isAnimatingHide || isAnimatingPulse
+ when {
+ // Hide the AOD icons if we're not in the KEYGUARD state unless the screen off
+ // animation is playing, in which case we want them to be visible if we're
+ // animating in the AOD UI and will be switching to KEYGUARD shortly.
+ !onKeyguard && !screenOffAnimationController.shouldShowAodIconsWhenShade() ->
+ AnimatedValue(false, isAnimating = false)
+ // If we're bypassing, then we're visible
+ bypassEnabled -> AnimatedValue(true, isAnimating)
+ // If we are pulsing (and not bypassing), then we are hidden
+ pulseExpanding -> AnimatedValue(false, isAnimating)
+ // If notifs are fully gone, then we're visible
+ notifsFullyHidden -> AnimatedValue(true, isAnimating)
+ // Otherwise, we're hidden
+ else -> AnimatedValue(false, isAnimating)
+ }
+ }
+ .distinctUntilChanged()
+
+ override fun completeDozeAnimation() {
+ onDozeAnimationComplete.tryEmit(Unit)
+ }
+
+ override fun completeVisibilityAnimation() {
+ onVisAnimationComplete.tryEmit(Unit)
+ }
+
+ /** Is there an expanded pulse, are we animating in response? */
+ private fun isPulseExpandingAnimated(): Flow<AnimatedValue<Boolean>> {
+ return notificationsKeyguardInteractor.isPulseExpanding
+ .pairwise(initialValue = null)
+ // If pulsing changes, start animating, unless it's the first emission
+ .map { (prev, expanding) ->
+ AnimatableEvent(expanding!!, startAnimating = prev != null)
+ }
+ .toAnimatedValueFlow(completionEvents = onVisAnimationComplete)
+ }
+
+ /** Are notifications completely hidden from view, are we animating in response? */
+ private fun areNotifsFullyHiddenAnimated(): Flow<AnimatedValue<Boolean>> {
+ return notificationsKeyguardInteractor.areNotificationsFullyHidden
+ .pairwise(initialValue = null)
+ .sample(deviceEntryInteractor.isBypassEnabled) { (prev, fullyHidden), bypassEnabled ->
+ val animate =
+ when {
+ // Don't animate for the first value
+ prev == null -> false
+ // Always animate if bypass is enabled.
+ bypassEnabled -> true
+ // If we're not bypassing and we're not going to AOD, then we're not
+ // animating.
+ !dozeParameters.alwaysOn -> false
+ // Don't animate when going to AOD if the display needs blanking.
+ dozeParameters.displayNeedsBlanking -> false
+ // We only want the appear animations to happen when the notifications
+ // get fully hidden, since otherwise the un-hide animation overlaps.
+ featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> true
+ else -> fullyHidden!!
+ }
+ AnimatableEvent(fullyHidden!!, animate)
+ }
+ .toAnimatedValueFlow(completionEvents = onVisAnimationComplete)
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
index 49f262de8f4a..c44a2b60142c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt
@@ -15,12 +15,18 @@
*/
package com.android.systemui.statusbar.notification.icon.ui.viewmodel
+import com.android.systemui.util.ui.AnimatedValue
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
/** View-model for the overflow row of notification icons displayed in the notification shade. */
class NotificationIconContainerShelfViewModel @Inject constructor() :
NotificationIconContainerViewModel {
override val animationsEnabled: Flow<Boolean> = flowOf(true)
+ override val isDozing: Flow<AnimatedValue<Boolean>> = emptyFlow()
+ override val isVisible: Flow<AnimatedValue<Boolean>> = emptyFlow()
+ override fun completeDozeAnimation() {}
+ override fun completeVisibilityAnimation() {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
index ee57b780b8c3..035687a4a91b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -17,9 +17,11 @@ package com.android.systemui.statusbar.notification.icon.ui.viewmodel
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.util.ui.AnimatedValue
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.emptyFlow
/** View-model for the row of notification icons displayed in the status bar, */
class NotificationIconContainerStatusBarViewModel
@@ -35,4 +37,9 @@ constructor(
) { panelTouchesEnabled, isKeyguardShowing ->
panelTouchesEnabled && !isKeyguardShowing
}
+
+ override val isDozing: Flow<AnimatedValue<Boolean>> = emptyFlow()
+ override val isVisible: Flow<AnimatedValue<Boolean>> = emptyFlow()
+ override fun completeDozeAnimation() {}
+ override fun completeVisibilityAnimation() {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
index 6f8ce4b1db4b..65eb22075ec7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.statusbar.notification.icon.ui.viewmodel
+import com.android.systemui.util.ui.AnimatedValue
import kotlinx.coroutines.flow.Flow
/**
@@ -24,4 +25,22 @@ import kotlinx.coroutines.flow.Flow
interface NotificationIconContainerViewModel {
/** Are changes to the icon container animated? */
val animationsEnabled: Flow<Boolean>
+
+ /** Should icons be rendered in "dozing" mode? */
+ val isDozing: Flow<AnimatedValue<Boolean>>
+
+ /** Is the icon container visible? */
+ val isVisible: Flow<AnimatedValue<Boolean>>
+
+ /**
+ * Signal completion of the [isDozing] animation; if [isDozing]'s [AnimatedValue.isAnimating]
+ * property was `true`, calling this method will update it to `false.
+ */
+ fun completeDozeAnimation()
+
+ /**
+ * Signal completion of the [isVisible] animation; if [isVisible]'s [AnimatedValue.isAnimating]
+ * property was `true`, calling this method will update it to `false.
+ */
+ fun completeVisibilityAnimation()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
index 197ae1a77198..dc9028d94312 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryDumper.kt
@@ -25,6 +25,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.dump.DumpsysTableLogger
import com.android.systemui.dump.Row
import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import dalvik.annotation.optimization.NeverCompile
import java.io.PrintWriter
import javax.inject.Inject
@@ -39,6 +40,7 @@ constructor(val dumpManager: DumpManager, val notificationPipeline: NotifPipelin
Log.i("NotificationMemory", "Registered dumpable.")
}
+ @NeverCompile
override fun dump(pw: PrintWriter, args: Array<out String>) {
val memoryUse =
NotificationMemoryMeter.notificationMemoryUse(notificationPipeline.allNotifs)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
index 42c80ed22717..40897dae4c44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
@@ -42,9 +42,8 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.Dependency;
-import com.android.systemui.res.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.Compile;
@@ -76,7 +75,9 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC
final StatusBarNotification sbn,
final NotificationEntry entry,
final ExpandableNotificationRow row,
- final AssistantFeedbackController controller) {
+ final AssistantFeedbackController controller,
+ final IStatusBarService statusBarService,
+ final NotificationGutsManager notificationGutsManager) {
mPkg = sbn.getPackageName();
mPm = pm;
mEntry = entry;
@@ -84,8 +85,8 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC
mRanking = entry.getRanking();
mFeedbackController = controller;
mAppName = mPkg;
- mStatusBarService = Dependency.get(IStatusBarService.class);
- mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);
+ mStatusBarService = statusBarService;
+ mNotificationGutsManager = notificationGutsManager;
bindHeader();
bindPrompt();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index dc318a392ed5..9e9116bd70e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -44,6 +44,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.settingslib.notification.ConversationIconFactory;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
@@ -99,6 +100,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta
// Dependencies:
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final StatusBarStateController mStatusBarStateController;
+ private final IStatusBarService mStatusBarService;
private final DeviceProvisionedController mDeviceProvisionedController;
private final AssistantFeedbackController mAssistantFeedbackController;
@@ -152,6 +154,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta
WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
NotificationLockscreenUserManager notificationLockscreenUserManager,
StatusBarStateController statusBarStateController,
+ IStatusBarService statusBarService,
DeviceProvisionedController deviceProvisionedController,
MetricsLogger metricsLogger,
HeadsUpManager headsUpManager,
@@ -177,6 +180,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta
mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
mLockscreenUserManager = notificationLockscreenUserManager;
mStatusBarStateController = statusBarStateController;
+ mStatusBarService = statusBarService;
mDeviceProvisionedController = deviceProvisionedController;
mMetricsLogger = metricsLogger;
mHeadsUpManager = headsUpManager;
@@ -358,7 +362,8 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta
PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(mContext,
userHandle.getIdentifier());
- feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), row, mAssistantFeedbackController);
+ feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), row, mAssistantFeedbackController,
+ mStatusBarService, this);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
index 0c686be0406d..e200b901e815 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
@@ -167,7 +167,7 @@ public abstract class StackScrollerDecorView extends ExpandableView {
}
@VisibleForTesting
- boolean isSecondaryVisible() {
+ public boolean isSecondaryVisible() {
return mIsSecondaryVisible;
}
@@ -179,7 +179,8 @@ public abstract class StackScrollerDecorView extends ExpandableView {
return mIsVisible;
}
- void setDuration(int duration) {
+ @VisibleForTesting
+ public void setDuration(int duration) {
mDuration = duration;
}
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 78d75582817b..10b1bcda27db 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
@@ -86,12 +86,12 @@ import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.ExpandHelper;
-import com.android.systemui.res.R;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.flags.ViewRefactorFlag;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
+import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.statusbar.CommandQueue;
@@ -106,12 +106,12 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 8ca18521de63..80f98a68b4f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -27,16 +27,16 @@ import android.view.ViewGroup;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.SystemBarUtils;
import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.res.R;
import com.android.systemui.animation.ShadeInterpolation;
+import com.android.systemui.res.R;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.SourceType;
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.row.FooterView;
import java.util.ArrayList;
import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 6e6318e780dc..f380ce53b950 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -239,6 +239,8 @@ import com.android.wm.shell.startingsurface.StartingSurface;
import dagger.Lazy;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
@@ -1763,6 +1765,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
}
+ @NeverCompile
@Override
public void dump(PrintWriter pwOriginal, String[] args) {
IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 7cbaf63bc6db..b15c0fdd5a4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -33,6 +33,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.collection.ArrayMap;
@@ -624,12 +625,32 @@ public class NotificationIconContainer extends ViewGroup {
}
public void setDozing(boolean dozing, boolean fade, long delay) {
+ setDozing(dozing, fade, delay, /* endRunnable= */ null);
+ }
+
+ public void setDozing(boolean dozing, boolean fade, long delay,
+ @Nullable Runnable endRunnable) {
mDozing = dozing;
mDisallowNextAnimation |= !fade;
- for (int i = 0; i < getChildCount(); i++) {
+ final int childCount = getChildCount();
+ // Track all the child invocations of setDozing, invoking the top-level endRunnable once
+ // they have all completed.
+ final Runnable onChildCompleted = endRunnable == null ? null : new Runnable() {
+ private int mPendingCallbacks = childCount;
+
+ @Override
+ public void run() {
+ if (--mPendingCallbacks == 0) {
+ endRunnable.run();
+ }
+ }
+ };
+ for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
if (view instanceof StatusBarIconView) {
- ((StatusBarIconView) view).setDozing(dozing, fade, delay);
+ ((StatusBarIconView) view).setDozing(dozing, fade, delay, onChildCompleted);
+ } else if (onChildCompleted != null) {
+ onChildCompleted.run();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt
new file mode 100644
index 000000000000..21acfb41f10c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationControllerExt.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.statusbar.policy
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * A [Flow] that emits whenever screen density or font scale has changed.
+ *
+ * @see ConfigurationController.ConfigurationListener.onDensityOrFontScaleChanged
+ */
+val ConfigurationController.onDensityOrFontScaleChanged: Flow<Unit>
+ get() =
+ ConflatedCallbackFlow.conflatedCallbackFlow {
+ val listener =
+ object : ConfigurationController.ConfigurationListener {
+ override fun onDensityOrFontScaleChanged() {
+ trySend(Unit)
+ }
+ }
+ addCallback(listener)
+ awaitClose { removeCallback(listener) }
+ }
diff --git a/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt b/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt
new file mode 100644
index 000000000000..ac04d31041b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt
@@ -0,0 +1,50 @@
+package com.android.systemui.util
+
+import java.lang.ref.SoftReference
+import java.lang.ref.WeakReference
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KProperty
+
+/**
+ * Creates a Kotlin idiomatic weak reference.
+ *
+ * Usage:
+ * ```
+ * var weakReferenceObj: Object? by weakReference(null)
+ * weakReferenceObj = Object()
+ * ```
+ */
+fun <T> weakReference(obj: T? = null): ReadWriteProperty<Any?, T?> {
+ return object : ReadWriteProperty<Any?, T?> {
+ var weakRef = WeakReference<T?>(obj)
+ override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
+ return weakRef.get()
+ }
+
+ override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
+ weakRef = WeakReference(value)
+ }
+ }
+}
+
+/**
+ * Creates a Kotlin idiomatic soft reference.
+ *
+ * Usage:
+ * ```
+ * var softReferenceObj: Object? by softReference(null)
+ * softReferenceObj = Object()
+ * ```
+ */
+fun <T> softReference(obj: T? = null): ReadWriteProperty<Any?, T?> {
+ return object : ReadWriteProperty<Any?, T?> {
+ var softRef = SoftReference<T?>(obj)
+ override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
+ return softRef.get()
+ }
+
+ override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
+ softRef = SoftReference(value)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
index 47d505ea36d5..83ff78980880 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
@@ -18,19 +18,24 @@ package com.android.systemui.util.kotlin
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.time.SystemClockImpl
-import kotlinx.coroutines.CoroutineStart
import java.util.concurrent.atomic.AtomicReference
+import kotlin.math.max
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import kotlin.math.max
/**
* Returns a new [Flow] that combines the two most recent emissions from [this] using [transform].
@@ -44,8 +49,7 @@ fun <T, R> Flow<T>.pairwiseBy(transform: suspend (old: T, new: T) -> R): Flow<R>
var previousValue: Any? = noVal
collect { newVal ->
if (previousValue != noVal) {
- @Suppress("UNCHECKED_CAST")
- emit(transform(previousValue as T, newVal))
+ @Suppress("UNCHECKED_CAST") emit(transform(previousValue as T, newVal))
}
previousValue = newVal
}
@@ -60,13 +64,11 @@ fun <T, R> Flow<T>.pairwiseBy(transform: suspend (old: T, new: T) -> R): Flow<R>
fun <T, R> Flow<T>.pairwiseBy(
initialValue: T,
transform: suspend (previousValue: T, newValue: T) -> R,
-): Flow<R> =
- onStart { emit(initialValue) }.pairwiseBy(transform)
+): Flow<R> = onStart { emit(initialValue) }.pairwiseBy(transform)
/**
* Returns a new [Flow] that combines the two most recent emissions from [this] using [transform].
*
- *
* The output of [getInitialValue] will be used as the "old" value for the first emission. As
* opposed to the initial value in the above [pairwiseBy], [getInitialValue] can do some work before
* returning the initial value.
@@ -76,8 +78,7 @@ fun <T, R> Flow<T>.pairwiseBy(
fun <T, R> Flow<T>.pairwiseBy(
getInitialValue: suspend () -> T,
transform: suspend (previousValue: T, newValue: T) -> R,
-): Flow<R> =
- onStart { emit(getInitialValue()) }.pairwiseBy(transform)
+): Flow<R> = onStart { emit(getInitialValue()) }.pairwiseBy(transform)
/**
* Returns a new [Flow] that produces the two most recent emissions from [this]. Note that the new
@@ -88,8 +89,8 @@ fun <T, R> Flow<T>.pairwiseBy(
fun <T> Flow<T>.pairwise(): Flow<WithPrev<T>> = pairwiseBy(::WithPrev)
/**
- * Returns a new [Flow] that produces the two most recent emissions from [this]. [initialValue]
- * will be used as the "old" value for the first emission.
+ * Returns a new [Flow] that produces the two most recent emissions from [this]. [initialValue] will
+ * be used as the "old" value for the first emission.
*
* Useful for code that needs to compare the current value to the previous value.
*/
@@ -102,9 +103,9 @@ data class WithPrev<T>(val previousValue: T, val newValue: T)
* Returns a new [Flow] that combines the [Set] changes between each emission from [this] using
* [transform].
*
- * If [emitFirstEvent] is `true`, then the first [Set] emitted from the upstream [Flow] will cause
- * a change event to be emitted that contains no removals, and all elements from that first [Set]
- * as additions.
+ * If [emitFirstEvent] is `true`, then the first [Set] emitted from the upstream [Flow] will cause a
+ * change event to be emitted that contains no removals, and all elements from that first [Set] as
+ * additions.
*
* If [emitFirstEvent] is `false`, then the first emission is ignored and no changes are emitted
* until a second [Set] has been emitted from the upstream [Flow].
@@ -112,22 +113,23 @@ data class WithPrev<T>(val previousValue: T, val newValue: T)
fun <T, R> Flow<Set<T>>.setChangesBy(
transform: suspend (removed: Set<T>, added: Set<T>) -> R,
emitFirstEvent: Boolean = true,
-): Flow<R> = (if (emitFirstEvent) onStart { emit(emptySet()) } else this)
- .distinctUntilChanged()
- .pairwiseBy { old: Set<T>, new: Set<T> ->
- // If an element was present in the old set, but not the new one, then it was removed
- val removed = old - new
- // If an element is present in the new set, but on the old one, then it was added
- val added = new - old
- transform(removed, added)
- }
+): Flow<R> =
+ (if (emitFirstEvent) onStart { emit(emptySet()) } else this)
+ .distinctUntilChanged()
+ .pairwiseBy { old: Set<T>, new: Set<T> ->
+ // If an element was present in the old set, but not the new one, then it was removed
+ val removed = old - new
+ // If an element is present in the new set, but on the old one, then it was added
+ val added = new - old
+ transform(removed, added)
+ }
/**
* Returns a new [Flow] that produces the [Set] changes between each emission from [this].
*
- * If [emitFirstEvent] is `true`, then the first [Set] emitted from the upstream [Flow] will cause
- * a change event to be emitted that contains no removals, and all elements from that first [Set]
- * as additions.
+ * If [emitFirstEvent] is `true`, then the first [Set] emitted from the upstream [Flow] will cause a
+ * change event to be emitted that contains no removals, and all elements from that first [Set] as
+ * additions.
*
* If [emitFirstEvent] is `false`, then the first emission is ignored and no changes are emitted
* until a second [Set] has been emitted from the upstream [Flow].
@@ -153,14 +155,11 @@ fun <A, B, C> Flow<A>.sample(other: Flow<B>, transform: suspend (A, B) -> C): Fl
coroutineScope {
val noVal = Any()
val sampledRef = AtomicReference(noVal)
- val job = launch(Dispatchers.Unconfined) {
- other.collect { sampledRef.set(it) }
- }
+ val job = launch(Dispatchers.Unconfined) { other.collect { sampledRef.set(it) } }
collect {
val sampled = sampledRef.get()
if (sampled != noVal) {
- @Suppress("UNCHECKED_CAST")
- emit(transform(it, sampled as B))
+ @Suppress("UNCHECKED_CAST") emit(transform(it, sampled as B))
}
}
job.cancel()
@@ -181,7 +180,6 @@ fun <A> Flow<*>.sample(other: Flow<A>): Flow<A> = sample(other) { _, a -> a }
* latest value is emitted.
*
* Example:
- *
* ```kotlin
* flow {
* emit(1) // t=0ms
@@ -210,7 +208,6 @@ fun <T> Flow<T>.throttle(periodMs: Long): Flow<T> = this.throttle(periodMs, Syst
* during this period, only The latest value is emitted.
*
* Example:
- *
* ```kotlin
* flow {
* emit(1) // t=0ms
@@ -248,10 +245,11 @@ fun <T> Flow<T>.throttle(periodMs: Long, clock: SystemClock): Flow<T> = channelF
// We create delayJob to allow cancellation during the delay period
delayJob = launch {
delay(timeUntilNextEmit)
- sendJob = outerScope.launch(start = CoroutineStart.UNDISPATCHED) {
- send(it)
- previousEmitTimeMs = clock.elapsedRealtime()
- }
+ sendJob =
+ outerScope.launch(start = CoroutineStart.UNDISPATCHED) {
+ send(it)
+ previousEmitTimeMs = clock.elapsedRealtime()
+ }
}
} else {
send(it)
@@ -259,4 +257,15 @@ fun <T> Flow<T>.throttle(periodMs: Long, clock: SystemClock): Flow<T> = channelF
}
}
}
-} \ No newline at end of file
+}
+
+/**
+ * Returns a [StateFlow] launched in the surrounding [CoroutineScope]. This [StateFlow] gets its
+ * value by invoking [getValue] whenever an event is emitted from [changedSignals]. It will also
+ * immediately invoke [getValue] to establish its initial value.
+ */
+inline fun <T> CoroutineScope.stateFlow(
+ changedSignals: Flow<Unit>,
+ crossinline getValue: () -> T,
+): StateFlow<T> =
+ changedSignals.map { getValue() }.stateIn(this, SharingStarted.Eagerly, getValue())
diff --git a/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt b/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt
new file mode 100644
index 000000000000..51d2afabd7f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/ui/AnimatedValue.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.util.ui
+
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.transformLatest
+
+/**
+ * A state comprised of a [value] of type [T] paired with a boolean indicating whether or not the
+ * [value] [isAnimating] in the UI.
+ */
+data class AnimatedValue<T>(
+ val value: T,
+ val isAnimating: Boolean,
+)
+
+/**
+ * An event comprised of a [value] of type [T] paired with a [boolean][startAnimating] indicating
+ * whether or not this event should start an animation.
+ */
+data class AnimatableEvent<T>(
+ val value: T,
+ val startAnimating: Boolean,
+)
+
+/**
+ * Returns a [Flow] that tracks an [AnimatedValue] state. The input [Flow] is used to update the
+ * [AnimatedValue.value], as well as [AnimatedValue.isAnimating] if the event's
+ * [AnimatableEvent.startAnimating] value is `true`. When [completionEvents] emits a value, the
+ * [AnimatedValue.isAnimating] will flip to `false`.
+ */
+fun <T> Flow<AnimatableEvent<T>>.toAnimatedValueFlow(
+ completionEvents: Flow<Any?>,
+): Flow<AnimatedValue<T>> = transformLatest { (value, startAnimating) ->
+ emit(AnimatedValue(value, isAnimating = startAnimating))
+ if (startAnimating) {
+ // Wait for a completion now that we've started animating
+ completionEvents
+ .map { Unit } // replace the event so that it's never `null`
+ .firstOrNull() // `null` indicates an empty flow
+ // emit the new state if the flow was not empty.
+ ?.run { emit(AnimatedValue(value, isAnimating = false)) }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index ea4d31bca035..d65a69c62072 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -77,6 +77,8 @@ import com.android.systemui.util.RingerModeLiveData;
import com.android.systemui.util.RingerModeTracker;
import com.android.systemui.util.concurrency.ThreadFactory;
+import dalvik.annotation.optimization.NeverCompile;
+
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
@@ -286,6 +288,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
return new MediaSessions(context, looper, callbacks);
}
+ @NeverCompile
public void dump(PrintWriter pw, String[] args) {
pw.println(VolumeDialogControllerImpl.class.getSimpleName() + " state:");
pw.print(" mVolumePolicy: "); pw.println(mVolumePolicy);
diff --git a/packages/SystemUI/tests/src/com/android/TestMocksModule.kt b/packages/SystemUI/tests/src/com/android/TestMocksModule.kt
index c1be44ab8a85..167e3417c162 100644
--- a/packages/SystemUI/tests/src/com/android/TestMocksModule.kt
+++ b/packages/SystemUI/tests/src/com/android/TestMocksModule.kt
@@ -81,7 +81,7 @@ data class TestMocksModule(
@get:Provides val notificationStackSizeCalculator: NotificationStackSizeCalculator = mock(),
@get:Provides val notificationWakeUpCoordinator: NotificationWakeUpCoordinator = mock(),
@get:Provides val screenLifecycle: ScreenLifecycle = mock(),
- @get:Provides val screenOffAnimController: ScreenOffAnimationController = mock(),
+ @get:Provides val screenOffAnimationController: ScreenOffAnimationController = mock(),
@get:Provides val scrimController: ScrimController = mock(),
@get:Provides val statusBarStateController: SysuiStatusBarStateController = mock(),
@get:Provides val statusBarWindowController: StatusBarWindowController = mock(),
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
index 989164ebf174..3b8e02f7455a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java
@@ -20,7 +20,6 @@ import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.animation.LayoutTransition;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
@@ -69,7 +68,6 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase {
@Mock protected KeyguardClockSwitch mKeyguardClockSwitch;
@Mock protected FrameLayout mMediaHostContainer;
- @Mock protected LayoutTransition mMediaLayoutTransition;
@Before
public void setup() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index e4e2b0a8d89f..948942fbce3a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -16,22 +16,27 @@
package com.android.keyguard;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.animation.LayoutTransition;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
-import com.android.systemui.res.R;
+import com.android.app.animation.Interpolators;
+import com.android.systemui.animation.ViewHierarchyAnimator;
import com.android.systemui.plugins.ClockConfig;
import com.android.systemui.plugins.ClockController;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -39,6 +44,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import java.lang.reflect.Field;
+
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidTestingRunner.class)
@@ -81,7 +88,7 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
public void updatePosition_primaryClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", false, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", false, true));
mController.updatePosition(10, 15, 20f, true);
@@ -96,7 +103,7 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
public void updatePosition_alternateClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", true, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", true, true));
mController.updatePosition(10, 15, 20f, true);
@@ -142,19 +149,7 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
}
@Test
- public void onInit_addsOnLayoutChangeListenerToMediaHostContainer() {
- when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
- mMediaHostContainer);
-
- mController.onInit();
-
- ArgumentCaptor<View.OnLayoutChangeListener> captor =
- ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
- verify(mMediaHostContainer).addOnLayoutChangeListener(captor.capture());
- }
-
- @Test
- public void clockSwitchHeightChanged_mediaChangingLayoutTransitionEnabled() {
+ public void clockSwitchHeightChanged_animatesMediaHostContainer() {
when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
mMediaHostContainer);
@@ -167,6 +162,10 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
// Above here is the same as `onInit_addsOnLayoutChangeListenerToClockSwitch`.
// Below here is the actual test.
+ ViewHierarchyAnimator.Companion animator = ViewHierarchyAnimator.Companion;
+ ViewHierarchyAnimator.Companion spiedAnimator = spy(animator);
+ setCompanion(spiedAnimator);
+
View.OnLayoutChangeListener listener = captor.getValue();
mController.setSplitShadeEnabled(true);
@@ -174,17 +173,20 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
when(mKeyguardUpdateMonitor.isKeyguardVisible()).thenReturn(true);
when(mMediaHostContainer.getVisibility()).thenReturn(View.VISIBLE);
when(mMediaHostContainer.getHeight()).thenReturn(200);
- when(mMediaHostContainer.getLayoutTransition()).thenReturn(mMediaLayoutTransition);
when(mKeyguardClockSwitch.getHeight()).thenReturn(0);
listener.onLayoutChange(mKeyguardClockSwitch, /* left= */ 0, /* top= */ 0, /* right= */
0, /* bottom= */ 0, /* oldLeft= */ 0, /* oldTop= */ 0, /* oldRight= */
0, /* oldBottom = */ 200);
- verify(mMediaLayoutTransition).enableTransitionType(LayoutTransition.CHANGING);
+ verify(spiedAnimator).animateNextUpdate(mMediaHostContainer,
+ Interpolators.STANDARD, /* duration= */ 500L, /* animateChildren= */ false);
+
+ // Resets ViewHierarchyAnimator.Companion to its original value
+ setCompanion(animator);
}
@Test
- public void clockSwitchHeightNotChanged_mediaChangingLayoutTransitionNotEnabled() {
+ public void clockSwitchHeightNotChanged_doesNotAnimateMediaOutputContainer() {
when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
mMediaHostContainer);
@@ -197,6 +199,10 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
// Above here is the same as `onInit_addsOnLayoutChangeListenerToClockSwitch`.
// Below here is the actual test.
+ ViewHierarchyAnimator.Companion animator = ViewHierarchyAnimator.Companion;
+ ViewHierarchyAnimator.Companion spiedAnimator = spy(animator);
+ setCompanion(spiedAnimator);
+
View.OnLayoutChangeListener listener = captor.getValue();
mController.setSplitShadeEnabled(true);
@@ -204,36 +210,24 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll
when(mKeyguardUpdateMonitor.isKeyguardVisible()).thenReturn(true);
when(mMediaHostContainer.getVisibility()).thenReturn(View.VISIBLE);
when(mMediaHostContainer.getHeight()).thenReturn(200);
- when(mMediaHostContainer.getLayoutTransition()).thenReturn(mMediaLayoutTransition);
when(mKeyguardClockSwitch.getHeight()).thenReturn(200);
listener.onLayoutChange(mKeyguardClockSwitch, /* left= */ 0, /* top= */ 0, /* right= */
0, /* bottom= */ 0, /* oldLeft= */ 0, /* oldTop= */ 0, /* oldRight= */
0, /* oldBottom = */ 200);
- verify(mMediaLayoutTransition, never()).enableTransitionType(LayoutTransition.CHANGING);
- }
-
- @Test
- public void onMediaHostContainerLayout_disablesChangingLayoutTransition() {
- when(mKeyguardStatusView.findViewById(R.id.status_view_media_container)).thenReturn(
- mMediaHostContainer);
-
- mController.onInit();
+ verify(spiedAnimator, never()).animateNextUpdate(any(), any(), anyLong(), anyBoolean());
- ArgumentCaptor<View.OnLayoutChangeListener> captor =
- ArgumentCaptor.forClass(View.OnLayoutChangeListener.class);
- verify(mMediaHostContainer).addOnLayoutChangeListener(captor.capture());
-
- // Above here is the same as `onInit_addsOnLayoutChangeListenerToMediaHostContainer`.
- // Below here is the actual test.
-
- View.OnLayoutChangeListener listener = captor.getValue();
-
- when(mMediaHostContainer.getLayoutTransition()).thenReturn(mMediaLayoutTransition);
+ // Resets ViewHierarchyAnimator.Companion to its original value
+ setCompanion(animator);
+ }
- when(mMediaLayoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGING)).thenReturn(
- true);
- listener.onLayoutChange(mMediaHostContainer, 1, 2, 3, 4, 1, 2, 3, 4);
- verify(mMediaLayoutTransition).disableTransitionType(LayoutTransition.CHANGING);
+ private void setCompanion(ViewHierarchyAnimator.Companion companion) {
+ try {
+ Field field = ViewHierarchyAnimator.class.getDeclaredField("Companion");
+ field.setAccessible(true);
+ field.set(null, companion);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
index 58d372c68c55..86439e557f8b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -1,6 +1,5 @@
package com.android.keyguard
-import android.animation.LayoutTransition
import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
@@ -36,20 +35,6 @@ class KeyguardStatusViewTest : SysuiTestCase() {
}
@Test
- fun mediaViewHasLayoutTransitionInDisabledState() {
- val layoutTransition = (mediaView as ViewGroup).layoutTransition
- assertThat(layoutTransition).isNotNull()
- assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGE_APPEARING))
- .isFalse()
- assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGE_DISAPPEARING))
- .isFalse()
- assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.APPEARING)).isFalse()
- assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.DISAPPEARING))
- .isFalse()
- assertThat(layoutTransition.isTransitionTypeEnabled(LayoutTransition.CHANGING)).isFalse()
- }
-
- @Test
fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
val translationY = 1234f
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index ce1930a6e80f..d61ca697642a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -42,6 +42,7 @@ import android.view.accessibility.AccessibilityManager;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController;
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.doze.util.BurnInHelperKt;
import com.android.systemui.dump.DumpManager;
@@ -51,6 +52,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
+import com.android.systemui.scene.SceneTestUtils;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -75,6 +77,8 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
protected MockitoSession mStaticMockSession;
+ protected final SceneTestUtils mSceneTestUtils = new SceneTestUtils(this);
+ protected @Mock BouncerInteractor mBouncerInteractor;
protected @Mock LockIconView mLockIconView;
protected @Mock AnimatedStateListDrawable mIconDrawable;
protected @Mock Context mContext;
@@ -93,6 +97,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
protected @Mock AuthRippleController mAuthRippleController;
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
protected FakeFeatureFlags mFeatureFlags;
+
protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor;
protected LockIconViewController mUnderTest;
@@ -148,6 +153,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
mFeatureFlags.set(MIGRATE_LOCK_ICON, false);
mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
mFeatureFlags.set(LOCKSCREEN_ENABLE_LANDSCAPE, false);
+
mUnderTest = new LockIconViewController(
mStatusBarStateController,
mKeyguardUpdateMonitor,
@@ -168,7 +174,9 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(),
mFeatureFlags,
mPrimaryBouncerInteractor,
- mContext
+ mContext,
+ () -> mBouncerInteractor,
+ mSceneTestUtils.getSceneContainerFlags()
);
}
@@ -227,8 +235,8 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
setupLockIconViewMocks();
}
- protected void init(boolean useMigrationFlag) {
- mFeatureFlags.set(DOZING_MIGRATION_1, useMigrationFlag);
+ protected void init(boolean useDozeMigrationFlag) {
+ mFeatureFlags.set(DOZING_MIGRATION_1, useDozeMigrationFlag);
mUnderTest.setLockIconView(mLockIconView);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
index 7b920939263e..4bacc3dfca0d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
@@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -404,6 +405,49 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
// THEN uses perform haptic feedback
verify(mVibrator).performHapticFeedback(any(), eq(UdfpsController.LONG_PRESS));
+ }
+
+ @Test
+ public void longPress_showBouncer_sceneContainerNotEnabled() {
+ init(/* useMigrationFlag= */ false);
+ mSceneTestUtils.getSceneContainerFlags().setEnabled(false);
+ mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
+ when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
+
+ // WHEN longPress
+ mUnderTest.onLongPress();
+
+ // THEN show primary bouncer via keyguard view controller, not scene container
+ verify(mKeyguardViewController).showPrimaryBouncer(anyBoolean());
+ verify(mBouncerInteractor, never()).showOrUnlockDevice(any());
+ }
+
+ @Test
+ public void longPress_showBouncer() {
+ init(/* useMigrationFlag= */ false);
+ mSceneTestUtils.getSceneContainerFlags().setEnabled(true);
+ mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
+ when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
+
+ // WHEN longPress
+ mUnderTest.onLongPress();
+
+ // THEN show primary bouncer
+ verify(mKeyguardViewController, never()).showPrimaryBouncer(anyBoolean());
+ verify(mBouncerInteractor).showOrUnlockDevice(any());
+ }
+
+ @Test
+ public void longPress_falsingTriggered_doesNotShowBouncer() {
+ init(/* useMigrationFlag= */ false);
+ mSceneTestUtils.getSceneContainerFlags().setEnabled(true);
+ mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
+ when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(true);
+
+ // WHEN longPress
+ mUnderTest.onLongPress();
+ // THEN don't show primary bouncer
+ verify(mBouncerInteractor, never()).showOrUnlockDevice(any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index 59c7e7669b63..8faf715521f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -166,6 +166,9 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
waitForIdleSync()
verify(controller).onLaunchAnimationCancelled()
verify(controller, never()).onLaunchAnimationStart(anyBoolean())
+ verify(listener).onLaunchAnimationCancelled()
+ verify(listener, never()).onLaunchAnimationStart()
+ assertNull(runner.delegate)
}
@Test
@@ -176,6 +179,9 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
waitForIdleSync()
verify(controller).onLaunchAnimationCancelled()
verify(controller, never()).onLaunchAnimationStart(anyBoolean())
+ verify(listener).onLaunchAnimationCancelled()
+ verify(listener, never()).onLaunchAnimationStart()
+ assertNull(runner.delegate)
}
@Test
@@ -194,6 +200,15 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
}
}
+ @Test
+ fun disposeRunner_delegateDereferenced() {
+ val runner = activityLaunchAnimator.createRunner(controller)
+ assertNotNull(runner.delegate)
+ runner.dispose()
+ waitForIdleSync()
+ assertNull(runner.delegate)
+ }
+
private fun fakeWindow(): RemoteAnimationTarget {
val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */)
val taskInfo = ActivityManager.RunningTaskInfo()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt
index a7e7dd074a33..2b51ac5e3187 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.animation
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.core.animation.doOnEnd
+import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.doOnEnd
@@ -30,6 +31,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidTestingRunner::class)
@SmallTest
@RunWithLooper
+@FlakyTest(bugId = 302149604)
class AnimatorTestRuleOrderTest : SysuiTestCase() {
@get:Rule val animatorTestRule = AnimatorTestRule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
index 679dfefae7cd..2c80035873f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
@@ -12,6 +12,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
@@ -22,6 +23,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@@ -54,6 +56,7 @@ class DeviceEntryRepositoryTest : SysuiTestCase() {
keyguardBypassController = keyguardBypassController,
keyguardStateController = keyguardStateController,
)
+ testScope.runCurrent()
}
@Test
@@ -66,8 +69,7 @@ class DeviceEntryRepositoryTest : SysuiTestCase() {
assertThat(isUnlocked).isFalse()
val captor = argumentCaptor<KeyguardStateController.Callback>()
- Mockito.verify(keyguardStateController, Mockito.atLeastOnce())
- .addCallback(captor.capture())
+ verify(keyguardStateController, Mockito.atLeastOnce()).addCallback(captor.capture())
whenever(keyguardStateController.isUnlocked).thenReturn(true)
captor.value.onUnlockedChanged()
@@ -98,7 +100,12 @@ class DeviceEntryRepositoryTest : SysuiTestCase() {
testScope.runTest {
whenever(keyguardBypassController.isBypassEnabled).thenAnswer { false }
whenever(keyguardBypassController.bypassEnabled).thenAnswer { false }
- assertThat(underTest.isBypassEnabled()).isFalse()
+ withArgCaptor {
+ verify(keyguardBypassController).registerOnBypassStateChangedListener(capture())
+ }
+ .onBypassStateChanged(false)
+ runCurrent()
+ assertThat(underTest.isBypassEnabled.value).isFalse()
}
@Test
@@ -106,7 +113,12 @@ class DeviceEntryRepositoryTest : SysuiTestCase() {
testScope.runTest {
whenever(keyguardBypassController.isBypassEnabled).thenAnswer { true }
whenever(keyguardBypassController.bypassEnabled).thenAnswer { true }
- assertThat(underTest.isBypassEnabled()).isTrue()
+ withArgCaptor {
+ verify(keyguardBypassController).registerOnBypassStateChangedListener(capture())
+ }
+ .onBypassStateChanged(true)
+ runCurrent()
+ assertThat(underTest.isBypassEnabled.value).isTrue()
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index c4cd8a4de8ab..c13fde75a068 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -218,14 +218,14 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
fun isBypassEnabled_enabledInRepository_true() =
testScope.runTest {
utils.deviceEntryRepository.setBypassEnabled(true)
- assertThat(underTest.isBypassEnabled()).isTrue()
+ assertThat(underTest.isBypassEnabled.value).isTrue()
}
@Test
fun isBypassEnabled_disabledInRepository_false() =
testScope.runTest {
utils.deviceEntryRepository.setBypassEnabled(false)
- assertThat(underTest.isBypassEnabled()).isFalse()
+ assertThat(underTest.isBypassEnabled.value).isFalse()
}
private fun switchToScene(sceneKey: SceneKey) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorTest.kt
index 632d149c9520..f37306276848 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/KeyEventInteractorTest.kt
@@ -16,23 +16,17 @@
package com.android.systemui.keyevent.domain.interactor
-import android.view.KeyEvent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.back.domain.interactor.BackActionInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
-import com.android.systemui.keyguard.domain.interactor.KeyguardKeyEventInteractor
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.whenever
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyevent.data.repository.FakeKeyEventRepository
import com.google.common.truth.Truth.assertThat
+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.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
@SmallTest
@@ -40,108 +34,27 @@ import org.mockito.junit.MockitoJUnit
class KeyEventInteractorTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
- private lateinit var keyguardInteractorWithDependencies:
- KeyguardInteractorFactory.WithDependencies
- @Mock private lateinit var keyguardKeyEventInteractor: KeyguardKeyEventInteractor
- @Mock private lateinit var backActionInteractor: BackActionInteractor
+ private lateinit var repository: FakeKeyEventRepository
private lateinit var underTest: KeyEventInteractor
@Before
fun setup() {
- keyguardInteractorWithDependencies = KeyguardInteractorFactory.create()
+ repository = FakeKeyEventRepository()
underTest =
KeyEventInteractor(
- backActionInteractor,
- keyguardKeyEventInteractor,
+ repository,
)
}
@Test
- fun dispatchBackKey_notHandledByKeyguardKeyEventInteractor_handledByBackActionInteractor() {
- val backKeyEventActionDown = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)
- val backKeyEventActionUp = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)
-
- // GIVEN back key ACTION_DOWN and ACTION_UP aren't handled by the keyguardKeyEventInteractor
- whenever(keyguardKeyEventInteractor.dispatchKeyEvent(backKeyEventActionDown))
- .thenReturn(false)
- whenever(keyguardKeyEventInteractor.dispatchKeyEvent(backKeyEventActionUp))
- .thenReturn(false)
-
- // WHEN back key event ACTION_DOWN, the event is handled even though back isn't requested
- assertThat(underTest.dispatchKeyEvent(backKeyEventActionDown)).isTrue()
- // THEN back event isn't handled on ACTION_DOWN
- verify(backActionInteractor, never()).onBackRequested()
-
- // WHEN back key event ACTION_UP
- assertThat(underTest.dispatchKeyEvent(backKeyEventActionUp)).isTrue()
- // THEN back event is handled on ACTION_UP
- verify(backActionInteractor).onBackRequested()
- }
-
- @Test
- fun dispatchKeyEvent_isNotHandledByKeyguardKeyEventInteractor() {
- val keyEvent =
- KeyEvent(
- KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_SPACE,
- )
- whenever(keyguardKeyEventInteractor.dispatchKeyEvent(eq(keyEvent))).thenReturn(false)
- assertThat(underTest.dispatchKeyEvent(keyEvent)).isFalse()
- }
-
- @Test
- fun dispatchKeyEvent_handledByKeyguardKeyEventInteractor() {
- val keyEvent =
- KeyEvent(
- KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_SPACE,
- )
- whenever(keyguardKeyEventInteractor.dispatchKeyEvent(eq(keyEvent))).thenReturn(true)
- assertThat(underTest.dispatchKeyEvent(keyEvent)).isTrue()
- }
-
- @Test
- fun interceptMediaKey_isNotHandledByKeyguardKeyEventInteractor() {
- val keyEvent =
- KeyEvent(
- KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_SPACE,
- )
- whenever(keyguardKeyEventInteractor.interceptMediaKey(eq(keyEvent))).thenReturn(false)
- assertThat(underTest.interceptMediaKey(keyEvent)).isFalse()
- }
-
- @Test
- fun interceptMediaKey_handledByKeyguardKeyEventInteractor() {
- val keyEvent =
- KeyEvent(
- KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_SPACE,
- )
- whenever(keyguardKeyEventInteractor.interceptMediaKey(eq(keyEvent))).thenReturn(true)
- assertThat(underTest.interceptMediaKey(keyEvent)).isTrue()
- }
-
- @Test
- fun dispatchKeyEventPreIme_isNotHandledByKeyguardKeyEventInteractor() {
- val keyEvent =
- KeyEvent(
- KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_SPACE,
- )
- whenever(keyguardKeyEventInteractor.dispatchKeyEventPreIme(eq(keyEvent))).thenReturn(false)
- assertThat(underTest.dispatchKeyEventPreIme(keyEvent)).isFalse()
- }
-
- @Test
- fun dispatchKeyEventPreIme_handledByKeyguardKeyEventInteractor() {
- val keyEvent =
- KeyEvent(
- KeyEvent.ACTION_UP,
- KeyEvent.KEYCODE_SPACE,
- )
- whenever(keyguardKeyEventInteractor.dispatchKeyEventPreIme(eq(keyEvent))).thenReturn(true)
- assertThat(underTest.dispatchKeyEventPreIme(keyEvent)).isTrue()
- }
+ fun dispatchBackKey_notHandledByKeyguardKeyEventInteractor_handledByBackActionInteractor() =
+ runTest {
+ val isPowerDown by collectLastValue(underTest.isPowerButtonDown)
+ repository.setPowerButtonDown(false)
+ assertThat(isPowerDown).isFalse()
+
+ repository.setPowerButtonDown(true)
+ assertThat(isPowerDown).isTrue()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerTest.kt
new file mode 100644
index 000000000000..af00a48d571b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyevent/domain/interactor/SysUIKeyEventHandlerTest.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyevent.domain.interactor
+
+import android.view.KeyEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.back.domain.interactor.BackActionInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.keyguard.domain.interactor.KeyguardKeyEventInteractor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+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.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SysUIKeyEventHandlerTest : SysuiTestCase() {
+ @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+ private lateinit var keyguardInteractorWithDependencies:
+ KeyguardInteractorFactory.WithDependencies
+ @Mock private lateinit var keyguardKeyEventInteractor: KeyguardKeyEventInteractor
+ @Mock private lateinit var backActionInteractor: BackActionInteractor
+
+ private lateinit var underTest: SysUIKeyEventHandler
+
+ @Before
+ fun setup() {
+ keyguardInteractorWithDependencies = KeyguardInteractorFactory.create()
+ underTest =
+ SysUIKeyEventHandler(
+ backActionInteractor,
+ keyguardKeyEventInteractor,
+ )
+ }
+
+ @Test
+ fun dispatchBackKey_notHandledByKeyguardKeyEventInteractor_handledByBackActionInteractor() {
+ val backKeyEventActionDown = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)
+ val backKeyEventActionUp = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)
+
+ // GIVEN back key ACTION_DOWN and ACTION_UP aren't handled by the keyguardKeyEventInteractor
+ whenever(keyguardKeyEventInteractor.dispatchKeyEvent(backKeyEventActionDown))
+ .thenReturn(false)
+ whenever(keyguardKeyEventInteractor.dispatchKeyEvent(backKeyEventActionUp))
+ .thenReturn(false)
+
+ // WHEN back key event ACTION_DOWN, the event is handled even though back isn't requested
+ assertThat(underTest.dispatchKeyEvent(backKeyEventActionDown)).isTrue()
+ // THEN back event isn't handled on ACTION_DOWN
+ verify(backActionInteractor, never()).onBackRequested()
+
+ // WHEN back key event ACTION_UP
+ assertThat(underTest.dispatchKeyEvent(backKeyEventActionUp)).isTrue()
+ // THEN back event is handled on ACTION_UP
+ verify(backActionInteractor).onBackRequested()
+ }
+
+ @Test
+ fun dispatchKeyEvent_isNotHandledByKeyguardKeyEventInteractor() {
+ val keyEvent =
+ KeyEvent(
+ KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ whenever(keyguardKeyEventInteractor.dispatchKeyEvent(eq(keyEvent))).thenReturn(false)
+ assertThat(underTest.dispatchKeyEvent(keyEvent)).isFalse()
+ }
+
+ @Test
+ fun dispatchKeyEvent_handledByKeyguardKeyEventInteractor() {
+ val keyEvent =
+ KeyEvent(
+ KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ whenever(keyguardKeyEventInteractor.dispatchKeyEvent(eq(keyEvent))).thenReturn(true)
+ assertThat(underTest.dispatchKeyEvent(keyEvent)).isTrue()
+ }
+
+ @Test
+ fun interceptMediaKey_isNotHandledByKeyguardKeyEventInteractor() {
+ val keyEvent =
+ KeyEvent(
+ KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ whenever(keyguardKeyEventInteractor.interceptMediaKey(eq(keyEvent))).thenReturn(false)
+ assertThat(underTest.interceptMediaKey(keyEvent)).isFalse()
+ }
+
+ @Test
+ fun interceptMediaKey_handledByKeyguardKeyEventInteractor() {
+ val keyEvent =
+ KeyEvent(
+ KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ whenever(keyguardKeyEventInteractor.interceptMediaKey(eq(keyEvent))).thenReturn(true)
+ assertThat(underTest.interceptMediaKey(keyEvent)).isTrue()
+ }
+
+ @Test
+ fun dispatchKeyEventPreIme_isNotHandledByKeyguardKeyEventInteractor() {
+ val keyEvent =
+ KeyEvent(
+ KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ whenever(keyguardKeyEventInteractor.dispatchKeyEventPreIme(eq(keyEvent))).thenReturn(false)
+ assertThat(underTest.dispatchKeyEventPreIme(keyEvent)).isFalse()
+ }
+
+ @Test
+ fun dispatchKeyEventPreIme_handledByKeyguardKeyEventInteractor() {
+ val keyEvent =
+ KeyEvent(
+ KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_SPACE,
+ )
+ whenever(keyguardKeyEventInteractor.dispatchKeyEventPreIme(eq(keyEvent))).thenReturn(true)
+ assertThat(underTest.dispatchKeyEventPreIme(keyEvent)).isTrue()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
index bbe68234f055..e10815d9de61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
@@ -35,6 +35,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -46,6 +47,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
+@ExperimentalCoroutinesApi
@SmallTest
@RunWith(AndroidJUnit4::class)
class KeyguardKeyEventInteractorTest : SysuiTestCase() {
@@ -57,8 +59,6 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP)
private val backKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)
- private lateinit var keyguardInteractorWithDependencies:
- KeyguardInteractorFactory.WithDependencies
private lateinit var powerInteractor: PowerInteractor
@Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
@@ -73,14 +73,12 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
fun setup() {
whenever(mediaSessionLegacyHelperWrapper.getHelper(any()))
.thenReturn(mediaSessionLegacyHelper)
- keyguardInteractorWithDependencies = KeyguardInteractorFactory.create()
powerInteractor = PowerInteractorFactory.create().powerInteractor
underTest =
KeyguardKeyEventInteractor(
context,
statusBarStateController,
- keyguardInteractorWithDependencies.keyguardInteractor,
statusBarKeyguardViewManager,
shadeController,
mediaSessionLegacyHelperWrapper,
@@ -132,58 +130,73 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
}
@Test
- fun dispatchKeyEvent_menuActionUp_interactiveKeyguard_collapsesShade() {
+ fun dispatchKeyEvent_menuActionUp_awakeKeyguard_showsPrimaryBouncer() {
powerInteractor.setAwakeForTest()
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
- verify(shadeController).animateCollapseShadeForced()
+ verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_MENU)
}
@Test
- fun dispatchKeyEvent_menuActionUp_interactiveShadeLocked_collapsesShade() {
+ fun dispatchKeyEvent_menuActionUp_awakeShadeLocked_collapsesShade() {
powerInteractor.setAwakeForTest()
whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)
- // action down: does NOT collapse the shade
- val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
- verify(shadeController, never()).animateCollapseShadeForced()
-
- // action up: collapses the shade
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
- verify(shadeController).animateCollapseShadeForced()
+ verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_MENU)
}
@Test
- fun dispatchKeyEvent_menuActionUp_nonInteractiveKeyguard_neverCollapsesShade() {
+ fun dispatchKeyEvent_menuActionUp_asleepKeyguard_neverCollapsesShade() {
powerInteractor.setAsleepForTest()
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
- verify(shadeController, never()).animateCollapseShadeForced()
+ verifyActionsDoNothing(KeyEvent.KEYCODE_MENU)
}
@Test
- fun dispatchKeyEvent_spaceActionUp_interactiveKeyguard_collapsesShade() {
+ fun dispatchKeyEvent_spaceActionUp_awakeKeyguard_collapsesShade() {
powerInteractor.setAwakeForTest()
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ whenever(statusBarKeyguardViewManager.primaryBouncerIsShowing()).thenReturn(false)
- // action down: does NOT collapse the shade
- val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)
- assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
- verify(shadeController, never()).animateCollapseShadeForced()
+ verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_SPACE)
+ }
- // action up: collapses the shade
- val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE)
- assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
- verify(shadeController).animateCollapseShadeForced()
+ @Test
+ fun dispatchKeyEvent_spaceActionUp_shadeLocked_collapsesShade() {
+ powerInteractor.setAwakeForTest()
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+
+ verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_SPACE)
+ }
+
+ @Test
+ fun dispatchKeyEvent_enterActionUp_awakeKeyguard_showsPrimaryBouncer() {
+ powerInteractor.setAwakeForTest()
+ whenever(statusBarKeyguardViewManager.primaryBouncerIsShowing()).thenReturn(false)
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+
+ verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_ENTER)
+ }
+
+ @Test
+ fun dispatchKeyEvent_enterActionUp_awakeKeyguard_primaryBouncerAlreadyShowing() {
+ powerInteractor.setAwakeForTest()
+ whenever(statusBarKeyguardViewManager.primaryBouncerIsShowing()).thenReturn(true)
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+
+ verifyActionsDoNothing(KeyEvent.KEYCODE_ENTER)
+ }
+
+ @Test
+ fun dispatchKeyEvent_enterActionUp_shadeLocked_collapsesShade() {
+ powerInteractor.setAwakeForTest()
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+
+ verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_ENTER)
}
@Test
@@ -253,4 +266,42 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
.isFalse()
verify(statusBarKeyguardViewManager, never()).interceptMediaKey(any())
}
+
+ private fun verifyActionUpCollapsesTheShade(keycode: Int) {
+ // action down: does NOT collapse the shade
+ val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
+ verify(shadeController, never()).animateCollapseShadeForced()
+
+ // action up: collapses the shade
+ val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
+ verify(shadeController).animateCollapseShadeForced()
+ }
+
+ private fun verifyActionUpShowsPrimaryBouncer(keycode: Int) {
+ // action down: does NOT collapse the shade
+ val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
+ verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
+
+ // action up: collapses the shade
+ val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
+ verify(statusBarKeyguardViewManager).showPrimaryBouncer(eq(true))
+ }
+
+ private fun verifyActionsDoNothing(keycode: Int) {
+ // action down: does nothing
+ val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
+ verify(shadeController, never()).animateCollapseShadeForced()
+ verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
+
+ // action up: doesNothing
+ val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
+ assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
+ verify(shadeController, never()).animateCollapseShadeForced()
+ verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
index 906420d03bed..9630ee32d456 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
@@ -46,6 +46,7 @@ class TaskPreviewSizeProviderTest : SysuiTestCase() {
private val mockContext = mock<Context>()
private val resources = mock<Resources>()
private val windowManager = mock<WindowManager>()
+ private val windowMetricsProvider = mock<WindowMetricsProvider>()
private val sizeUpdates = arrayListOf<Rect>()
private val testConfigurationController = FakeConfigurationController()
@@ -112,13 +113,12 @@ class TaskPreviewSizeProviderTest : SysuiTestCase() {
}
private fun givenTaskbarSize(size: Int) {
- val windowInsets =
- WindowInsets.Builder()
- .setInsets(Type.tappableElement(), Insets.of(Rect(0, 0, 0, size)))
- .build()
+ val insets = Insets.of(Rect(0, 0, 0, size))
+ val windowInsets = WindowInsets.Builder().setInsets(Type.tappableElement(), insets).build()
val windowMetrics = WindowMetrics(windowManager.maximumWindowMetrics.bounds, windowInsets)
whenever(windowManager.maximumWindowMetrics).thenReturn(windowMetrics)
whenever(windowManager.currentWindowMetrics).thenReturn(windowMetrics)
+ whenever(windowMetricsProvider.currentWindowInsets).thenReturn(insets)
}
private fun givenDisplay(width: Int, height: Int, isTablet: Boolean = false) {
@@ -126,6 +126,7 @@ class TaskPreviewSizeProviderTest : SysuiTestCase() {
val windowMetrics = WindowMetrics(bounds, { null }, 1.0f)
whenever(windowManager.maximumWindowMetrics).thenReturn(windowMetrics)
whenever(windowManager.currentWindowMetrics).thenReturn(windowMetrics)
+ whenever(windowMetricsProvider.maximumWindowBounds).thenReturn(bounds)
val minDimension = min(width, height)
@@ -147,7 +148,11 @@ class TaskPreviewSizeProviderTest : SysuiTestCase() {
}
}
- return TaskPreviewSizeProvider(mockContext, windowManager, testConfigurationController)
+ return TaskPreviewSizeProvider(
+ mockContext,
+ windowMetricsProvider,
+ testConfigurationController
+ )
.also { it.addCallback(listener) }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt
new file mode 100644
index 000000000000..fe18454ec06c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt
@@ -0,0 +1,44 @@
+package com.android.systemui.mediaprojection.appselector.view
+
+import android.graphics.Insets
+import android.graphics.Rect
+import android.view.WindowManager
+import android.view.WindowMetrics
+import androidx.core.view.WindowInsetsCompat
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+@SmallTest
+class WindowMetricsProviderImplTest : SysuiTestCase() {
+
+ private val windowManager = mock<WindowManager>()
+ private val windowMetricsProvider = WindowMetricsProviderImpl(windowManager)
+
+ @Test
+ fun getMaximumWindowBounds_returnsValueFromWMMaxWindowMetrics() {
+ val bounds = Rect(/* left= */ 100, /* top= */ 200, /* right= */ 300, /* bottom= */ 400)
+ val metrics =
+ WindowMetrics(bounds, /* windowInsetsSupplier= */ { null }, /* density= */ 1.0f)
+ whenever(windowManager.maximumWindowMetrics).thenReturn(metrics)
+
+ assertThat(windowMetricsProvider.maximumWindowBounds).isEqualTo(bounds)
+ }
+
+ @Test
+ fun getCurrentWindowInsets_returnsFromWMCurrentWindowMetrics() {
+ val bounds = Rect()
+ val insets =
+ Insets.of(Rect(/* left= */ 123, /* top= */ 456, /* right= */ 789, /* bottom= */ 1012))
+ val windowInsets =
+ android.view.WindowInsets.Builder()
+ .setInsets(WindowInsetsCompat.Type.tappableElement(), insets)
+ .build()
+ whenever(windowManager.currentWindowMetrics).thenReturn(WindowMetrics(bounds, windowInsets))
+
+ assertThat(windowMetricsProvider.currentWindowInsets).isEqualTo(insets)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index b4f9e8dcfb39..677d9db0b97c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -49,7 +49,7 @@ import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.flags.SystemPropertiesHelper
-import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
+import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
@@ -144,7 +144,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
@Mock lateinit var dragDownHelper: DragDownHelper
@Mock
lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel
- @Mock lateinit var keyEventInteractor: KeyEventInteractor
+ @Mock lateinit var sysUIKeyEventHandler: SysUIKeyEventHandler
@Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
@Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
private val notificationExpansionRepository = NotificationExpansionRepository()
@@ -251,7 +251,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
securityModel = mock(KeyguardSecurityModel::class.java),
),
BouncerLogger(logcatLogBuffer("BouncerLog")),
- keyEventInteractor,
+ sysUIKeyEventHandler,
primaryBouncerInteractor,
alternateBouncerInteractor,
)
@@ -475,21 +475,21 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
fun forwardsDispatchKeyEvent() {
val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
interactionEventHandler.dispatchKeyEvent(keyEvent)
- verify(keyEventInteractor).dispatchKeyEvent(keyEvent)
+ verify(sysUIKeyEventHandler).dispatchKeyEvent(keyEvent)
}
@Test
fun forwardsDispatchKeyEventPreIme() {
val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_B)
interactionEventHandler.dispatchKeyEventPreIme(keyEvent)
- verify(keyEventInteractor).dispatchKeyEventPreIme(keyEvent)
+ verify(sysUIKeyEventHandler).dispatchKeyEventPreIme(keyEvent)
}
@Test
fun forwardsInterceptMediaKey() {
val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP)
interactionEventHandler.interceptMediaKey(keyEvent)
- verify(keyEventInteractor).interceptMediaKey(keyEvent)
+ verify(sysUIKeyEventHandler).interceptMediaKey(keyEvent)
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 189c9e25d9b0..a4a2ca0a6a21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -48,7 +48,7 @@ import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.flags.SystemPropertiesHelper
-import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
+import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
@@ -253,7 +253,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
securityModel = Mockito.mock(KeyguardSecurityModel::class.java),
),
BouncerLogger(logcatLogBuffer("BouncerLog")),
- Mockito.mock(KeyEventInteractor::class.java),
+ Mockito.mock(SysUIKeyEventHandler::class.java),
primaryBouncerInteractor,
alternateBouncerInteractor,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index e71473681211..ae659f4d2676 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -131,11 +131,10 @@ class ClockRegistryTest : SysuiTestCase() {
fun addClock(
id: ClockId,
- name: String,
create: (ClockId) -> ClockController = ::failFactory,
getThumbnail: (ClockId) -> Drawable? = ::failThumbnail
): FakeClockPlugin {
- metadata.add(ClockMetadata(id, name))
+ metadata.add(ClockMetadata(id))
createCallbacks[id] = create
thumbnailCallbacks[id] = getThumbnail
return this
@@ -149,7 +148,7 @@ class ClockRegistryTest : SysuiTestCase() {
scope = TestScope(dispatcher)
fakeDefaultProvider = FakeClockPlugin()
- .addClock(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME, { mockDefaultClock }, { mockThumbnail })
+ .addClock(DEFAULT_CLOCK_ID, { mockDefaultClock }, { mockThumbnail })
whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
val captor = argumentCaptor<PluginListener<ClockProviderPlugin>>()
@@ -183,13 +182,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun pluginRegistration_CorrectState() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = FakeLifecycle("1", plugin1)
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3")
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3")
+ .addClock("clock_4")
val lifecycle2 = FakeLifecycle("2", plugin2)
pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
@@ -198,11 +197,11 @@ class ClockRegistryTest : SysuiTestCase() {
assertEquals(
list.toSet(),
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1"),
- ClockMetadata("clock_2", "clock 2"),
- ClockMetadata("clock_3", "clock 3"),
- ClockMetadata("clock_4", "clock 4")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1"),
+ ClockMetadata("clock_2"),
+ ClockMetadata("clock_3"),
+ ClockMetadata("clock_4")
)
)
}
@@ -216,13 +215,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun clockIdConflict_ErrorWithoutCrash_unloadDuplicate() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1", { mockClock }, { mockThumbnail })
- .addClock("clock_2", "clock 2", { mockClock }, { mockThumbnail })
+ .addClock("clock_1", { mockClock }, { mockThumbnail })
+ .addClock("clock_2", { mockClock }, { mockThumbnail })
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
@@ -231,9 +230,9 @@ class ClockRegistryTest : SysuiTestCase() {
assertEquals(
list.toSet(),
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1"),
- ClockMetadata("clock_2", "clock 2")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1"),
+ ClockMetadata("clock_2")
)
)
@@ -248,13 +247,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun createCurrentClock_pluginConnected() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3", { mockClock })
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3", { mockClock })
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
@@ -268,13 +267,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun activeClockId_changeAfterPluginConnected() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3", { mockClock })
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3", { mockClock })
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
@@ -289,13 +288,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun createDefaultClock_pluginDisconnected() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3")
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3")
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
@@ -310,13 +309,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun pluginRemoved_clockAndListChanged() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3", { mockClock })
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3", { mockClock })
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
var changeCallCount = 0
@@ -415,13 +414,13 @@ class ClockRegistryTest : SysuiTestCase() {
@Test
fun pluginAddRemove_concurrentModification() {
- val plugin1 = FakeClockPlugin().addClock("clock_1", "clock 1")
+ val plugin1 = FakeClockPlugin().addClock("clock_1")
val lifecycle1 = FakeLifecycle("1", plugin1)
- val plugin2 = FakeClockPlugin().addClock("clock_2", "clock 2")
+ val plugin2 = FakeClockPlugin().addClock("clock_2")
val lifecycle2 = FakeLifecycle("2", plugin2)
- val plugin3 = FakeClockPlugin().addClock("clock_3", "clock 3")
+ val plugin3 = FakeClockPlugin().addClock("clock_3")
val lifecycle3 = FakeLifecycle("3", plugin3)
- val plugin4 = FakeClockPlugin().addClock("clock_4", "clock 4")
+ val plugin4 = FakeClockPlugin().addClock("clock_4")
val lifecycle4 = FakeLifecycle("4", plugin4)
// Set the current clock to the final clock to load
@@ -450,10 +449,10 @@ class ClockRegistryTest : SysuiTestCase() {
// Verify all plugins were correctly loaded into the registry
assertEquals(registry.getClocks().toSet(), setOf(
- ClockMetadata("DEFAULT", "Default Clock"),
- ClockMetadata("clock_2", "clock 2"),
- ClockMetadata("clock_3", "clock 3"),
- ClockMetadata("clock_4", "clock 4")
+ ClockMetadata("DEFAULT"),
+ ClockMetadata("clock_2"),
+ ClockMetadata("clock_3"),
+ ClockMetadata("clock_4")
))
}
@@ -527,8 +526,8 @@ class ClockRegistryTest : SysuiTestCase() {
featureFlags.set(TRANSIT_CLOCK, flag)
registry.isTransitClockEnabled = featureFlags.isEnabled(TRANSIT_CLOCK)
val plugin = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("DIGITAL_CLOCK_METRO", "metro clock")
+ .addClock("clock_1")
+ .addClock("DIGITAL_CLOCK_METRO")
val lifecycle = FakeLifecycle("metro", plugin)
pluginListener.onPluginLoaded(plugin, mockContext, lifecycle)
@@ -536,17 +535,17 @@ class ClockRegistryTest : SysuiTestCase() {
if (flag) {
assertEquals(
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1"),
- ClockMetadata("DIGITAL_CLOCK_METRO", "metro clock")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1"),
+ ClockMetadata("DIGITAL_CLOCK_METRO")
),
list.toSet()
)
} else {
assertEquals(
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1")
),
list.toSet()
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepositoryTest.kt
new file mode 100644
index 000000000000..2f8f3bb14ee5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/data/repository/NotificationsKeyguardViewStateRepositoryTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.statusbar.notification.data.repository
+
+import androidx.test.filters.SmallTest
+import com.android.SysUITestModule
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.mockito.Mockito.verify
+
+@SmallTest
+class NotificationsKeyguardViewStateRepositoryTest : SysuiTestCase() {
+
+ private val testComponent: TestComponent =
+ DaggerNotificationsKeyguardViewStateRepositoryTest_TestComponent.factory()
+ .create(test = this)
+
+ @Test
+ fun areNotifsFullyHidden_reflectsWakeUpCoordinator() =
+ with(testComponent) {
+ testScope.runTest {
+ whenever(mockWakeUpCoordinator.notificationsFullyHidden).thenReturn(false)
+ val notifsFullyHidden by collectLastValue(underTest.areNotificationsFullyHidden)
+ runCurrent()
+
+ assertThat(notifsFullyHidden).isFalse()
+
+ withArgCaptor { verify(mockWakeUpCoordinator).addListener(capture()) }
+ .onFullyHiddenChanged(true)
+ runCurrent()
+
+ assertThat(notifsFullyHidden).isTrue()
+ }
+ }
+
+ @Test
+ fun isPulseExpanding_reflectsWakeUpCoordinator() =
+ with(testComponent) {
+ testScope.runTest {
+ whenever(mockWakeUpCoordinator.isPulseExpanding()).thenReturn(false)
+ val isPulseExpanding by collectLastValue(underTest.isPulseExpanding)
+ runCurrent()
+
+ assertThat(isPulseExpanding).isFalse()
+
+ withArgCaptor { verify(mockWakeUpCoordinator).addListener(capture()) }
+ .onPulseExpansionChanged(true)
+ runCurrent()
+
+ assertThat(isPulseExpanding).isTrue()
+ }
+ }
+
+ @SysUISingleton
+ @Component(
+ modules =
+ [
+ SysUITestModule::class,
+ ]
+ )
+ interface TestComponent {
+
+ val underTest: NotificationsKeyguardViewStateRepositoryImpl
+
+ val mockWakeUpCoordinator: NotificationWakeUpCoordinator
+ val testScope: TestScope
+
+ @Component.Factory
+ interface Factory {
+ fun create(
+ @BindsInstance test: SysuiTestCase,
+ ): TestComponent
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
new file mode 100644
index 000000000000..705a5a3f9792
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.SysUITestModule
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardViewStateRepository
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+
+@SmallTest
+class NotificationsKeyguardInteractorTest : SysuiTestCase() {
+
+ private val testComponent: TestComponent =
+ DaggerNotificationsKeyguardInteractorTest_TestComponent.factory().create(test = this)
+
+ @Test
+ fun areNotifsFullyHidden_reflectsRepository() =
+ with(testComponent) {
+ testScope.runTest {
+ repository.setNotificationsFullyHidden(false)
+ val notifsFullyHidden by collectLastValue(underTest.areNotificationsFullyHidden)
+ runCurrent()
+
+ assertThat(notifsFullyHidden).isFalse()
+
+ repository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(notifsFullyHidden).isTrue()
+ }
+ }
+
+ @Test
+ fun isPulseExpanding_reflectsRepository() =
+ with(testComponent) {
+ testScope.runTest {
+ repository.setPulseExpanding(false)
+ val isPulseExpanding by collectLastValue(underTest.isPulseExpanding)
+ runCurrent()
+
+ assertThat(isPulseExpanding).isFalse()
+
+ repository.setPulseExpanding(true)
+ runCurrent()
+
+ assertThat(isPulseExpanding).isTrue()
+ }
+ }
+
+ @SysUISingleton
+ @Component(
+ modules =
+ [
+ SysUITestModule::class,
+ ]
+ )
+ interface TestComponent {
+
+ val underTest: NotificationsKeyguardInteractor
+
+ val repository: FakeNotificationsKeyguardViewStateRepository
+ val testScope: TestScope
+
+ @Component.Factory
+ interface Factory {
+ fun create(@BindsInstance test: SysuiTestCase): TestComponent
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
index b120c4747cb9..f72142ffc6d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
@@ -11,10 +11,10 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.notification.row;
+package com.android.systemui.statusbar.notification.footer.ui.view;
import static com.google.common.truth.Truth.assertThat;
@@ -31,8 +31,8 @@ import android.widget.TextView;
import androidx.test.filters.SmallTest;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.res.R;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
index 7caa5ccc5837..e57986ddfa18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImplTest.kt
@@ -26,9 +26,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FakeFeatureFlagsClassicModule
import com.android.systemui.flags.Flags
import com.android.systemui.statusbar.phone.DozeParameters
-import com.android.systemui.statusbar.phone.NotificationIconContainer
import com.android.systemui.user.domain.UserDomainLayerModule
-import com.android.systemui.util.mockito.whenever
import dagger.BindsInstance
import dagger.Component
import org.junit.Assert.assertFalse
@@ -37,7 +35,6 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@@ -46,7 +43,6 @@ import org.mockito.MockitoAnnotations
class NotificationIconAreaControllerViewBinderWrapperImplTest : SysuiTestCase() {
@Mock private lateinit var dozeParams: DozeParameters
- @Mock private lateinit var aodIcons: NotificationIconContainer
private lateinit var testComponent: TestComponent
private val underTest
@@ -85,15 +81,6 @@ class NotificationIconAreaControllerViewBinderWrapperImplTest : SysuiTestCase()
assertTrue(underTest.shouldShowLowPriorityIcons())
}
- @Test
- fun testAppearResetsTranslation() {
- underTest.setupAodIcons(aodIcons)
- whenever(dozeParams.shouldControlScreenOff()).thenReturn(false)
- underTest.appearAodIcons()
- verify(aodIcons).translationY = 0f
- verify(aodIcons).alpha = 1.0f
- }
-
@SysUISingleton
@Component(
modules =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 99c3b194a662..31efebbc5b60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
@@ -25,6 +25,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
import com.android.systemui.flags.FakeFeatureFlagsClassicModule
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -37,10 +38,13 @@ import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardViewStateRepository
import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController
import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
import com.android.systemui.user.domain.UserDomainLayerModule
import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.ui.AnimatedValue
import com.google.common.truth.Truth.assertThat
import dagger.BindsInstance
import dagger.Component
@@ -59,19 +63,24 @@ import org.mockito.MockitoAnnotations
class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
@Mock private lateinit var dozeParams: DozeParameters
+ @Mock private lateinit var screenOffAnimController: ScreenOffAnimationController
private lateinit var testComponent: TestComponent
- private val underTest
+ private val underTest: NotificationIconContainerAlwaysOnDisplayViewModel
get() = testComponent.underTest
- private val deviceProvisioningRepository
+ private val deviceEntryRepository: FakeDeviceEntryRepository
+ get() = testComponent.deviceEntryRepository
+ private val deviceProvisioningRepository: FakeDeviceProvisioningRepository
get() = testComponent.deviceProvisioningRepository
- private val keyguardRepository
+ private val keyguardRepository: FakeKeyguardRepository
get() = testComponent.keyguardRepository
- private val keyguardTransitionRepository
+ private val keyguardTransitionRepository: FakeKeyguardTransitionRepository
get() = testComponent.keyguardTransitionRepository
- private val powerRepository
+ private val notifsKeyguardRepository: FakeNotificationsKeyguardViewStateRepository
+ get() = testComponent.notifsKeyguardRepository
+ private val powerRepository: FakePowerRepository
get() = testComponent.powerRepository
- private val scope
+ private val scope: TestScope
get() = testComponent.scope
@Before
@@ -84,12 +93,14 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
test = this,
featureFlags =
FakeFeatureFlagsClassicModule {
- set(Flags.FACE_AUTH_REFACTOR, value = false)
+ setDefault(Flags.FACE_AUTH_REFACTOR)
set(Flags.FULL_SCREEN_USER_SWITCHER, value = false)
+ setDefault(Flags.NEW_AOD_TRANSITION)
},
mocks =
TestMocksModule(
dozeParameters = dozeParams,
+ screenOffAnimationController = screenOffAnimController,
),
)
@@ -251,6 +262,204 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
assertThat(animationsEnabled).isFalse()
}
+ @Test
+ fun isDozing_startAodTransition() =
+ scope.runTest {
+ val isDozing by collectLastValue(underTest.isDozing)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ runCurrent()
+ assertThat(isDozing).isEqualTo(AnimatedValue(true, isAnimating = true))
+ }
+
+ @Test
+ fun isDozing_startDozeTransition() =
+ scope.runTest {
+ val isDozing by collectLastValue(underTest.isDozing)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.DOZING,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ runCurrent()
+ assertThat(isDozing).isEqualTo(AnimatedValue(true, isAnimating = false))
+ }
+
+ @Test
+ fun isDozing_startDozeToAodTransition() =
+ scope.runTest {
+ val isDozing by collectLastValue(underTest.isDozing)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.AOD,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ runCurrent()
+ assertThat(isDozing).isEqualTo(AnimatedValue(true, isAnimating = true))
+ }
+
+ @Test
+ fun isNotDozing_startAodToGoneTransition() =
+ scope.runTest {
+ val isDozing by collectLastValue(underTest.isDozing)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.AOD,
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ runCurrent()
+ assertThat(isDozing).isEqualTo(AnimatedValue(false, isAnimating = true))
+ }
+
+ @Test
+ fun isDozing_stopAnimation() =
+ scope.runTest {
+ val isDozing by collectLastValue(underTest.isDozing)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.AOD,
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ runCurrent()
+
+ underTest.completeDozeAnimation()
+ runCurrent()
+
+ assertThat(isDozing?.isAnimating).isEqualTo(false)
+ }
+
+ @Test
+ fun isNotVisible_pulseExpanding() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ notifsKeyguardRepository.setPulseExpanding(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isFalse()
+ }
+
+ @Test
+ fun isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.FINISHED,
+ )
+ )
+ whenever(screenOffAnimController.shouldShowAodIconsWhenShade()).thenReturn(false)
+ runCurrent()
+
+ assertThat(isVisible).isEqualTo(AnimatedValue(false, isAnimating = false))
+ }
+
+ @Test
+ fun isVisible_bypassEnabled() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ deviceEntryRepository.setBypassEnabled(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isTrue()
+ }
+
+ @Test
+ fun isNotVisible_pulseExpanding_notBypassing() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ notifsKeyguardRepository.setPulseExpanding(true)
+ deviceEntryRepository.setBypassEnabled(false)
+ runCurrent()
+
+ assertThat(isVisible?.value).isEqualTo(false)
+ }
+
+ @Test
+ fun isVisible_notifsFullyHidden_bypassEnabled() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ runCurrent()
+ notifsKeyguardRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(true)
+ notifsKeyguardRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = true))
+ }
+
+ @Test
+ fun isVisible_notifsFullyHidden_bypassDisabled_aodDisabled() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ notifsKeyguardRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParams.alwaysOn).thenReturn(false)
+ notifsKeyguardRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = false))
+ }
+
+ @Test
+ fun isVisible_notifsFullyHidden_bypassDisabled_displayNeedsBlanking() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ notifsKeyguardRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParams.alwaysOn).thenReturn(true)
+ whenever(dozeParams.displayNeedsBlanking).thenReturn(true)
+ notifsKeyguardRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = false))
+ }
+
+ @Test
+ fun isVisible_notifsFullyHidden_bypassDisabled() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ runCurrent()
+ notifsKeyguardRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParams.alwaysOn).thenReturn(true)
+ whenever(dozeParams.displayNeedsBlanking).thenReturn(false)
+ notifsKeyguardRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible).isEqualTo(AnimatedValue(true, isAnimating = true))
+ }
+
+ @Test
+ fun isVisible_stopAnimation() =
+ scope.runTest {
+ val isVisible by collectLastValue(underTest.isVisible)
+ notifsKeyguardRepository.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParams.alwaysOn).thenReturn(true)
+ whenever(dozeParams.displayNeedsBlanking).thenReturn(false)
+ notifsKeyguardRepository.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ underTest.completeVisibilityAnimation()
+ runCurrent()
+
+ assertThat(isVisible?.isAnimating).isEqualTo(false)
+ }
+
@SysUISingleton
@Component(
modules =
@@ -264,9 +473,11 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
val underTest: NotificationIconContainerAlwaysOnDisplayViewModel
+ val deviceEntryRepository: FakeDeviceEntryRepository
val deviceProvisioningRepository: FakeDeviceProvisioningRepository
val keyguardRepository: FakeKeyguardRepository
val keyguardTransitionRepository: FakeKeyguardTransitionRepository
+ val notifsKeyguardRepository: FakeNotificationsKeyguardViewStateRepository
val powerRepository: FakePowerRepository
val scope: TestScope
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
index d1518f7e0d08..e1e7f92265f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
@@ -82,6 +82,7 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() {
DaggerNotificationIconContainerStatusBarViewModelTest_TestComponent.factory()
.create(
test = this,
+ // Configurable bindings
featureFlags =
FakeFeatureFlagsClassicModule {
set(Flags.FACE_AUTH_REFACTOR, value = false)
@@ -248,6 +249,7 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() {
modules =
[
SysUITestModule::class,
+ // Real impls
BiometricsDomainLayerModule::class,
UserDomainLayerModule::class,
]
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 c9b77c5372df..9c20e541e35f 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
@@ -54,9 +54,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -132,7 +132,8 @@ public class FeedbackInfoTest extends SysuiTestCase {
public void testBindNotification_SetsTextApplicationName() {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
- mMockNotificationRow, mAssistantFeedbackController);
+ mMockNotificationRow, mAssistantFeedbackController, mStatusBarService,
+ mNotificationGutsManager);
final TextView textView = mFeedbackInfo.findViewById(R.id.pkg_name);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -143,7 +144,8 @@ public class FeedbackInfoTest extends SysuiTestCase {
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
- mMockNotificationRow, mAssistantFeedbackController);
+ mMockNotificationRow, mAssistantFeedbackController, mStatusBarService,
+ mNotificationGutsManager);
final ImageView iconView = mFeedbackInfo.findViewById(R.id.pkg_icon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -153,7 +155,7 @@ public class FeedbackInfoTest extends SysuiTestCase {
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_SILENCED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically demoted to Silent by the system. "
+ "Let the developer know your feedback. Was this correct?",
@@ -165,7 +167,7 @@ public class FeedbackInfoTest extends SysuiTestCase {
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_PROMOTED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically ranked higher in your shade. "
+ "Let the developer know your feedback. Was this correct?",
@@ -177,7 +179,7 @@ public class FeedbackInfoTest extends SysuiTestCase {
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_ALERTED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically promoted to Default by the system. "
+ "Let the developer know your feedback. Was this correct?",
@@ -189,7 +191,7 @@ public class FeedbackInfoTest extends SysuiTestCase {
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_DEMOTED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically ranked lower in your shade. "
+ "Let the developer know your feedback. Was this correct?",
@@ -199,7 +201,7 @@ public class FeedbackInfoTest extends SysuiTestCase {
@Test
public void testPositiveFeedback() {
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
final View yes = mFeedbackInfo.findViewById(R.id.yes);
yes.performClick();
@@ -216,7 +218,7 @@ public class FeedbackInfoTest extends SysuiTestCase {
.thenReturn(true);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
final View no = mFeedbackInfo.findViewById(R.id.no);
no.performClick();
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 1ab36b805ca6..8a730cfd7ddd 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
@@ -195,6 +195,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mWindowRootViewVisibilityInteractor,
mNotificationLockscreenUserManager,
mStatusBarStateController,
+ mBarService,
mDeviceProvisionedController,
mMetricsLogger,
mHeadsUpManager,
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 236bcb416573..a2be8b0e0be2 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
@@ -65,12 +65,12 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.ExpandHelper;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.EmptyShadeView;
@@ -81,9 +81,9 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 93faa77bef5c..49906dca0344 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -5,18 +5,18 @@ import android.content.pm.PackageManager
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
import com.android.systemui.dump.DumpManager
+import com.android.systemui.res.R
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
import com.android.systemui.statusbar.EmptyShadeView
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView.FooterViewState
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.row.FooterView
-import com.android.systemui.statusbar.notification.row.FooterView.FooterViewState
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Expect
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
new file mode 100644
index 000000000000..aaf8d0761dce
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.util.ui
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AnimatedValueTest : SysuiTestCase() {
+
+ @Test
+ fun animatableEvent_updatesValue() = runTest {
+ val events = MutableSharedFlow<AnimatableEvent<Int>>()
+ val values = events.toAnimatedValueFlow(completionEvents = emptyFlow())
+ val value by collectLastValue(values)
+ runCurrent()
+
+ events.emit(AnimatableEvent(value = 1, startAnimating = false))
+
+ assertThat(value).isEqualTo(AnimatedValue(value = 1, isAnimating = false))
+ }
+
+ @Test
+ fun animatableEvent_startAnimation() = runTest {
+ val events = MutableSharedFlow<AnimatableEvent<Int>>()
+ val values = events.toAnimatedValueFlow(completionEvents = emptyFlow())
+ val value by collectLastValue(values)
+ runCurrent()
+
+ events.emit(AnimatableEvent(value = 1, startAnimating = true))
+
+ assertThat(value).isEqualTo(AnimatedValue(value = 1, isAnimating = true))
+ }
+
+ @Test
+ fun animatableEvent_startAnimation_alreadyAnimating() = runTest {
+ val events = MutableSharedFlow<AnimatableEvent<Int>>()
+ val values = events.toAnimatedValueFlow(completionEvents = emptyFlow())
+ val value by collectLastValue(values)
+ runCurrent()
+
+ events.emit(AnimatableEvent(value = 1, startAnimating = true))
+ events.emit(AnimatableEvent(value = 2, startAnimating = true))
+
+ assertThat(value).isEqualTo(AnimatedValue(value = 2, isAnimating = true))
+ }
+
+ @Test
+ fun animatedValue_stopAnimating() = runTest {
+ val events = MutableSharedFlow<AnimatableEvent<Int>>()
+ val stopEvent = MutableSharedFlow<Unit>()
+ val values = events.toAnimatedValueFlow(completionEvents = stopEvent)
+ val value by collectLastValue(values)
+ runCurrent()
+
+ events.emit(AnimatableEvent(value = 1, startAnimating = true))
+ stopEvent.emit(Unit)
+
+ assertThat(value).isEqualTo(AnimatedValue(value = 1, isAnimating = false))
+ }
+
+ @Test
+ fun animatedValue_stopAnimating_notAnimating() = runTest {
+ val events = MutableSharedFlow<AnimatableEvent<Int>>()
+ val stopEvent = MutableSharedFlow<Unit>()
+ val values = events.toAnimatedValueFlow(completionEvents = stopEvent)
+ values.launchIn(backgroundScope)
+ runCurrent()
+
+ events.emit(AnimatableEvent(value = 1, startAnimating = false))
+
+ assertThat(stopEvent.subscriptionCount.value).isEqualTo(0)
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/android/animation/PlatformAnimatorIsolationRule.kt b/packages/SystemUI/tests/utils/src/android/animation/PlatformAnimatorIsolationRule.kt
index 43a26f34ef2e..ca5e1d075856 100644
--- a/packages/SystemUI/tests/utils/src/android/animation/PlatformAnimatorIsolationRule.kt
+++ b/packages/SystemUI/tests/utils/src/android/animation/PlatformAnimatorIsolationRule.kt
@@ -41,7 +41,7 @@ class PlatformAnimatorIsolationRule : TestRule {
private fun onError() =
exceptionDeferrer.fail(
"Test's animations are not isolated! " +
- "Did you forget to add an AnimatorTestRule to your test class?"
+ "Did you forget to add an AnimatorTestRule as a @Rule?"
)
fun throwDeferred() = exceptionDeferrer.throwDeferred()
diff --git a/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt b/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt
index 7a97029ca6b0..95335a639ea2 100644
--- a/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt
+++ b/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt
@@ -37,7 +37,7 @@ class AndroidXAnimatorIsolationRule : TestRule {
private fun onError() =
exceptionDeferrer.fail(
"Test's animations are not isolated! " +
- "Did you forget to add an AnimatorTestRule to your test class?"
+ "Did you forget to add an AnimatorTestRule as a @Rule?"
)
fun throwDeferred() = exceptionDeferrer.throwDeferred()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt
index 813197b171ad..dc5fd953239d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt
@@ -24,6 +24,7 @@ import com.android.systemui.settings.FakeSettingsModule
import com.android.systemui.statusbar.policy.FakeConfigurationControllerModule
import com.android.systemui.statusbar.policy.FakeSplitShadeStateControllerModule
import com.android.systemui.util.concurrency.FakeExecutorModule
+import com.android.systemui.util.time.FakeSystemClockModule
import dagger.Module
@Module(
@@ -36,6 +37,7 @@ import dagger.Module
FakeSceneModule::class,
FakeSettingsModule::class,
FakeSplitShadeStateControllerModule::class,
+ FakeSystemClockModule::class,
FakeSystemUiDataLayerModule::class,
FakeUiEventLoggerModule::class,
]
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index d6632a3c5ea7..f7e0120d3843 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -15,8 +15,6 @@
*/
package com.android.systemui;
-import static com.android.systemui.animation.FakeDialogLaunchAnimatorKt.fakeDialogLaunchAnimator;
-
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -37,19 +35,15 @@ import androidx.core.animation.AndroidXAnimatorIsolationRule;
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.FakeBroadcastDispatcher;
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.phone.SystemUIDialogManager;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.ClassRule;
import org.junit.Rule;
import org.mockito.Mockito;
@@ -69,8 +63,8 @@ public abstract class SysuiTestCase {
private Handler mHandler;
// set the lowest order so it's the outermost rule
- @ClassRule(order = Integer.MIN_VALUE)
- public static AndroidXAnimatorIsolationRule mAndroidXAnimatorIsolationRule =
+ @Rule(order = Integer.MIN_VALUE)
+ public AndroidXAnimatorIsolationRule mAndroidXAnimatorIsolationRule =
new AndroidXAnimatorIsolationRule();
@Rule
@@ -94,10 +88,7 @@ public abstract class SysuiTestCase {
if (isRobolectricTest()) {
mContext = mContext.createDefaultDisplayContext();
}
- SystemUIInitializer initializer = new SystemUIInitializerImpl(mContext);
- initializer.init(true);
- mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
- Dependency.setInstance(mDependency);
+ mDependency = SysuiTestDependencyKt.installSysuiTestDependency(mContext);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(
mContext,
mContext.getMainExecutor(),
@@ -124,13 +115,6 @@ public abstract class SysuiTestCase {
// reference and are never sent to the Context. This will also prevent a real
// BroadcastDispatcher from actually registering receivers.
mDependency.injectTestDependency(BroadcastDispatcher.class, mFakeBroadcastDispatcher);
- mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
-
- // Make sure that all tests on any SystemUIDialog does not crash because this dependency
- // is missing (constructing the actual one would throw).
- // TODO(b/219008720): Remove this.
- mDependency.injectMockDependency(SystemUIDialogManager.class);
- mDependency.injectTestDependency(DialogLaunchAnimator.class, fakeDialogLaunchAnimator());
}
protected boolean shouldFailOnLeakedReceiver() {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestDependency.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestDependency.kt
new file mode 100644
index 000000000000..c791f4f70920
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestDependency.kt
@@ -0,0 +1,26 @@
+package com.android.systemui
+
+import android.annotation.SuppressLint
+import android.content.Context
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.animation.fakeDialogLaunchAnimator
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+
+@SuppressLint("VisibleForTests")
+fun installSysuiTestDependency(context: Context): TestableDependency {
+ val initializer: SystemUIInitializer = SystemUIInitializerImpl(context)
+ initializer.init(true)
+
+ val dependency = TestableDependency(initializer.sysUIComponent.createDependency())
+ Dependency.setInstance(dependency)
+
+ dependency.injectMockDependency(KeyguardUpdateMonitor::class.java)
+
+ // Make sure that all tests on any SystemUIDialog does not crash because this dependency
+ // is missing (constructing the actual one would throw).
+ // TODO(b/219008720): Remove this.
+ dependency.injectMockDependency(SystemUIDialogManager::class.java)
+ dependency.injectTestDependency(DialogLaunchAnimator::class.java, fakeDialogLaunchAnimator())
+ return dependency
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/FakeAuthenticationDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/FakeAuthenticationDataLayerModule.kt
new file mode 100644
index 000000000000..8fa6695cab99
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/FakeAuthenticationDataLayerModule.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.authentication.data
+
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepositoryModule
+import dagger.Module
+
+@Module(includes = [FakeAuthenticationRepositoryModule::class])
+object FakeAuthenticationDataLayerModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
index 4fc3e3f66e6d..ddfe79aedce6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
@@ -24,10 +24,17 @@ import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationResultModel
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
class FakeAuthenticationRepository(
private val deviceEntryRepository: FakeDeviceEntryRepository,
@@ -201,3 +208,19 @@ class FakeAuthenticationRepository(
}
}
}
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@Module(includes = [FakeAuthenticationRepositoryModule.Bindings::class])
+object FakeAuthenticationRepositoryModule {
+ @Provides
+ @SysUISingleton
+ fun provideFake(
+ deviceEntryRepository: FakeDeviceEntryRepository,
+ scope: TestScope,
+ ) = FakeAuthenticationRepository(deviceEntryRepository, currentTime = { scope.currentTime })
+
+ @Module
+ interface Bindings {
+ @Binds fun bindFake(fake: FakeAuthenticationRepository): AuthenticationRepository
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt
index 29fb52aabd39..cffbf0271c29 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.data
+import com.android.systemui.authentication.data.FakeAuthenticationDataLayerModule
import com.android.systemui.bouncer.data.repository.FakeBouncerDataLayerModule
import com.android.systemui.common.ui.data.FakeCommonDataLayerModule
import com.android.systemui.deviceentry.data.FakeDeviceEntryDataLayerModule
@@ -29,6 +30,7 @@ import dagger.Module
@Module(
includes =
[
+ FakeAuthenticationDataLayerModule::class,
FakeBouncerDataLayerModule::class,
FakeCommonDataLayerModule::class,
FakeDeviceEntryDataLayerModule::class,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt
new file mode 100644
index 000000000000..f4feee19df65
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.deviceentry.data.repository
+
+import dagger.Module
+
+@Module(includes = [FakeDeviceEntryRepositoryModule::class]) object FakeDeviceEntryDataLayerModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
index 26d95c0a0ea3..f0293489cb87 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.android.systemui.deviceentry.data.repository
import com.android.systemui.dagger.SysUISingleton
@@ -13,15 +28,13 @@ import kotlinx.coroutines.flow.asStateFlow
class FakeDeviceEntryRepository @Inject constructor() : DeviceEntryRepository {
private var isInsecureLockscreenEnabled = true
- private var isBypassEnabled = false
+
+ private val _isBypassEnabled = MutableStateFlow(false)
+ override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled
private val _isUnlocked = MutableStateFlow(false)
override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
- override fun isBypassEnabled(): Boolean {
- return isBypassEnabled
- }
-
override suspend fun isInsecureLockscreenEnabled(): Boolean {
return isInsecureLockscreenEnabled
}
@@ -35,7 +48,7 @@ class FakeDeviceEntryRepository @Inject constructor() : DeviceEntryRepository {
}
fun setBypassEnabled(isBypassEnabled: Boolean) {
- this.isBypassEnabled = isBypassEnabled
+ _isBypassEnabled.value = isBypassEnabled
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt
new file mode 100644
index 000000000000..95b5316fbab5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyevent.data.repository
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeKeyEventRepository() : KeyEventRepository {
+ private val _isPowerButtonDown = MutableStateFlow(false)
+ override val isPowerButtonDown: Flow<Boolean> = _isPowerButtonDown.asStateFlow()
+
+ fun setPowerButtonDown(isDown: Boolean) {
+ _isPowerButtonDown.value = isDown
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt
index 822edfc7f6cd..e59f642071fb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.data
import com.android.systemui.statusbar.disableflags.data.FakeStatusBarDisableFlagsDataLayerModule
+import com.android.systemui.statusbar.notification.data.FakeStatusBarNotificationsDataLayerModule
import com.android.systemui.statusbar.pipeline.data.FakeStatusBarPipelineDataLayerModule
import com.android.systemui.statusbar.policy.data.FakeStatusBarPolicyDataLayerModule
import dagger.Module
@@ -24,6 +25,7 @@ import dagger.Module
includes =
[
FakeStatusBarDisableFlagsDataLayerModule::class,
+ FakeStatusBarNotificationsDataLayerModule::class,
FakeStatusBarPipelineDataLayerModule::class,
FakeStatusBarPolicyDataLayerModule::class,
]
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt
new file mode 100644
index 000000000000..788e3aa9c41a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/FakeStatusBarNotificationsDataLayerModule.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.data
+
+import com.android.systemui.statusbar.notification.data.repository.FakeNotificationsKeyguardStateRepositoryModule
+import dagger.Module
+
+@Module(includes = [FakeNotificationsKeyguardStateRepositoryModule::class])
+object FakeStatusBarNotificationsDataLayerModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeNotificationsKeyguardViewStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeNotificationsKeyguardViewStateRepository.kt
new file mode 100644
index 000000000000..5d3cb4db9c7e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/repository/FakeNotificationsKeyguardViewStateRepository.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+
+@SysUISingleton
+class FakeNotificationsKeyguardViewStateRepository @Inject constructor() :
+ NotificationsKeyguardViewStateRepository {
+ private val _notificationsFullyHidden = MutableStateFlow(false)
+ override val areNotificationsFullyHidden: Flow<Boolean> = _notificationsFullyHidden
+
+ private val _isPulseExpanding = MutableStateFlow(false)
+ override val isPulseExpanding: Flow<Boolean> = _isPulseExpanding
+
+ fun setNotificationsFullyHidden(fullyHidden: Boolean) {
+ _notificationsFullyHidden.value = fullyHidden
+ }
+
+ fun setPulseExpanding(expanding: Boolean) {
+ _isPulseExpanding.value = expanding
+ }
+}
+
+@Module
+interface FakeNotificationsKeyguardStateRepositoryModule {
+ @Binds
+ fun bindFake(
+ fake: FakeNotificationsKeyguardViewStateRepository
+ ): NotificationsKeyguardViewStateRepository
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutorModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutorModule.kt
index 5de05c27ba2e..1f48d940f91c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutorModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/concurrency/FakeExecutorModule.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.util.concurrency
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.util.time.FakeSystemClock
import dagger.Binds
@@ -22,14 +23,12 @@ import dagger.Module
import dagger.Provides
import java.util.concurrent.Executor
-@Module(includes = [FakeExecutorModule.Bindings::class])
-class FakeExecutorModule(
- @get:Provides val clock: FakeSystemClock = FakeSystemClock(),
-) {
- @get:Provides val executor = FakeExecutor(clock)
+@Module
+interface FakeExecutorModule {
+ @Binds @Main @SysUISingleton fun bindMainExecutor(executor: FakeExecutor): Executor
- @Module
- interface Bindings {
- @Binds @Main fun bindMainExecutor(executor: FakeExecutor): Executor
+ companion object {
+ @Provides
+ fun provideFake(clock: FakeSystemClock) = FakeExecutor(clock)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockModule.kt
new file mode 100644
index 000000000000..3e3d7cbb40b5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/time/FakeSystemClockModule.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.util.time
+
+import com.android.systemui.dagger.SysUISingleton
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+
+@Module
+interface FakeSystemClockModule {
+ @Binds fun bindFake(fake: FakeSystemClock): SystemClock
+
+ companion object {
+ @Provides @SysUISingleton fun providesFake() = FakeSystemClock()
+ }
+}
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index 155dc1a68295..18f783146c72 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -49,7 +49,7 @@ android_test {
"androidx.test.core",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
resource_dirs: ["test/res"],
certificate: "platform",
diff --git a/packages/overlays/tests/Android.bp b/packages/overlays/tests/Android.bp
index b781602399a3..0244c0fe0533 100644
--- a/packages/overlays/tests/Android.bp
+++ b/packages/overlays/tests/Android.bp
@@ -34,7 +34,7 @@ android_test {
"androidx.test.rules",
"androidx.test.espresso.core",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
dxflags: ["--multi-dex"],
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 7e09b5ea9fa5..258820a5a03c 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -24,6 +24,7 @@ import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -1660,8 +1661,21 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
synchronized (mLock) {
ensureGroupStateLoadedLocked(userId);
+ final String pkg = componentName.getPackageName();
+ final ProviderId id;
+ if (!mPackageManagerInternal.isSameApp(pkg, callingUid, userId)) {
+ // If the calling process is requesting to pin appwidgets from another process,
+ // check if the calling process has the necessary permission.
+ if (!injectHasAccessWidgetsPermission(Binder.getCallingPid(), callingUid)) {
+ return false;
+ }
+ id = new ProviderId(mPackageManagerInternal.getPackageUid(
+ pkg, 0 /* flags */, userId), componentName);
+ } else {
+ id = new ProviderId(callingUid, componentName);
+ }
// Look for the widget associated with the caller.
- Provider provider = lookupProviderLocked(new ProviderId(callingUid, componentName));
+ Provider provider = lookupProviderLocked(id);
if (provider == null || provider.zombie) {
return false;
}
@@ -1675,6 +1689,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
.requestPinAppWidget(callingPackage, info, extras, resultSender, userId);
}
+ /**
+ * Returns true if the caller has the proper permission to access app widgets.
+ */
+ private boolean injectHasAccessWidgetsPermission(int callingPid, int callingUid) {
+ return mContext.checkPermission(Manifest.permission.CLEAR_APP_USER_DATA,
+ callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
+ }
+
@Override
public ParceledListSlice<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
int profileId, String packageName) {
@@ -4131,7 +4153,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
return false;
}
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public AppWidgetProviderInfo getInfoLocked(Context context) {
if (!mInfoParsed) {
// parse
@@ -4159,18 +4181,18 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
* be completely parsed and only contain placeHolder information like
* {@link AppWidgetProviderInfo#providerInfo}
*/
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public AppWidgetProviderInfo getPartialInfoLocked() {
return info;
}
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public void setPartialInfoLocked(AppWidgetProviderInfo info) {
this.info = info;
mInfoParsed = false;
}
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public void setInfoLocked(AppWidgetProviderInfo info) {
this.info = info;
mInfoParsed = true;
diff --git a/services/autofill/Android.bp b/services/autofill/Android.bp
index d43a219e6205..eb23f2f9b435 100644
--- a/services/autofill/Android.bp
+++ b/services/autofill/Android.bp
@@ -19,19 +19,4 @@ java_library_static {
defaults: ["platform_service_defaults"],
srcs: [":services.autofill-sources"],
libs: ["services.core"],
- static_libs: ["autofill_flags_java_lib"],
-}
-
-aconfig_declarations {
- name: "autofill_flags",
- package: "android.service.autofill",
- srcs: [
- "bugfixes.aconfig",
- "features.aconfig",
- ],
-}
-
-java_aconfig_library {
- name: "autofill_flags_java_lib",
- aconfig_declarations: "autofill_flags",
}
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index 123b65c039ba..b37bbd6ea27f 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -8,6 +8,13 @@ flag {
}
flag {
+ name: "fill_fields_from_current_session_only"
+ namespace: "autofill"
+ description: "Only fill autofill fields that are part of the current session."
+ bug: "270722825"
+}
+
+flag {
name: "relayout"
namespace: "autofill"
description: "Mitigation for relayout issue"
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index c7b53c55d89b..3e134992c763 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -58,6 +58,7 @@ import android.os.UserManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.autofill.FillEventHistory;
+import android.service.autofill.Flags;
import android.service.autofill.UserData;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -226,6 +227,9 @@ public final class AutofillManagerService
@GuardedBy("mFlagLock")
private int mMaxInputLengthForAutofill;
+ @GuardedBy("mFlagLock")
+ private boolean mIsFillFieldsFromCurrentSessionOnly;
+
// Default flag values for Autofill PCC
private static final String DEFAULT_PCC_FEATURE_PROVIDER_HINTS = "";
@@ -701,6 +705,7 @@ public final class AutofillManagerService
DeviceConfig.NAMESPACE_AUTOFILL,
AutofillFeatureFlags.DEVICE_CONFIG_MAX_INPUT_LENGTH_FOR_AUTOFILL,
AutofillFeatureFlags.DEFAULT_MAX_INPUT_LENGTH_FOR_AUTOFILL);
+ mIsFillFieldsFromCurrentSessionOnly = Flags.fillFieldsFromCurrentSessionOnly();
if (verbose) {
Slog.v(mTag, "setDeviceConfigProperties() for PCC: "
+ "mPccClassificationEnabled=" + mPccClassificationEnabled
@@ -1004,6 +1009,15 @@ public final class AutofillManagerService
}
}
+ /**
+ * Return if autofill should only fill in fields from current session.
+ */
+ public boolean getIsFillFieldsFromCurrentSessionOnly() {
+ synchronized (mFlagLock) {
+ return mIsFillFieldsFromCurrentSessionOnly;
+ }
+ }
+
@Nullable
@VisibleForTesting
static Map<String, String[]> getAllowedCompatModePackages(String setting) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 0220deca18c1..ae1487775b74 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2437,7 +2437,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
+ id + " destroyed");
return;
}
- fillInIntent = createAuthFillInIntentLocked(requestId, extras);
+ fillInIntent = createAuthFillInIntentLocked(requestId, extras, /* authExtras= */ null);
if (fillInIntent == null) {
forceRemoveFromServiceLocked();
return;
@@ -5558,7 +5558,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mPresentationStatsEventLogger.maybeSetAuthenticationType(
AUTHENTICATION_TYPE_DATASET_AUTHENTICATION);
setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH, false);
- final Intent fillInIntent = createAuthFillInIntentLocked(requestId, mClientState);
+ final Intent fillInIntent = createAuthFillInIntentLocked(requestId, mClientState,
+ dataset.getAuthenticationExtras());
if (fillInIntent == null) {
forceRemoveFromServiceLocked();
return;
@@ -5574,7 +5575,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// TODO: this should never be null, but we got at least one occurrence, probably due to a race.
@GuardedBy("mLock")
@Nullable
- private Intent createAuthFillInIntentLocked(int requestId, Bundle extras) {
+ private Intent createAuthFillInIntentLocked(int requestId, Bundle extras,
+ @Nullable Bundle authExtras) {
final Intent fillInIntent = new Intent();
final FillContext context = getFillContextByRequestIdLocked(requestId);
@@ -5591,6 +5593,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, context.getStructure());
fillInIntent.putExtra(AutofillManager.EXTRA_CLIENT_STATE, extras);
+ if (authExtras != null) {
+ fillInIntent.putExtra(AutofillManager.EXTRA_AUTH_STATE, authExtras);
+ }
return fillInIntent;
}
@@ -6137,9 +6142,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
continue;
}
final AutofillId viewId = dataset.getFieldIds().get(i);
+ final ViewState viewState = mViewStates.get(viewId);
+ if (mService.getMaster().getIsFillFieldsFromCurrentSessionOnly()
+ && viewState != null && viewState.id.getSessionId() != id) {
+ if (sVerbose) {
+ Slog.v(TAG, "Skipping filling view: " +
+ viewId + " as it isn't part of the current session: " + id);
+ }
+ continue;
+ }
ids.add(viewId);
values.add(dataset.getFieldValues().get(i));
- final ViewState viewState = mViewStates.get(viewId);
if (viewState != null
&& (viewState.getState() & ViewState.STATE_WAITING_DATASET_AUTH) != 0) {
if (sVerbose) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index cfe56e910b8a..5cb100a1bfa5 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -38,6 +38,7 @@ import android.companion.virtual.VirtualDeviceManager;
import android.companion.virtual.VirtualDeviceParams;
import android.companion.virtual.flags.Flags;
import android.companion.virtual.sensor.VirtualSensor;
+import android.companion.virtualnative.IVirtualDeviceManagerNative;
import android.content.AttributionSource;
import android.content.Context;
import android.content.Intent;
@@ -88,8 +89,11 @@ public class VirtualDeviceManagerService extends SystemService {
private static final String TAG = "VirtualDeviceManagerService";
+ private static final String VIRTUAL_DEVICE_NATIVE_SERVICE = "virtualdevice_native";
+
private final Object mVirtualDeviceManagerLock = new Object();
private final VirtualDeviceManagerImpl mImpl;
+ private final VirtualDeviceManagerNativeImpl mNativeImpl;
private final VirtualDeviceManagerInternal mLocalService;
private VirtualDeviceLog mVirtualDeviceLog = new VirtualDeviceLog(getContext());
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -125,6 +129,7 @@ public class VirtualDeviceManagerService extends SystemService {
public VirtualDeviceManagerService(Context context) {
super(context);
mImpl = new VirtualDeviceManagerImpl();
+ mNativeImpl = Flags.enableNativeVdm() ? new VirtualDeviceManagerNativeImpl() : null;
mLocalService = new LocalService();
}
@@ -155,6 +160,9 @@ public class VirtualDeviceManagerService extends SystemService {
@Override
public void onStart() {
publishBinderService(Context.VIRTUAL_DEVICE_SERVICE, mImpl);
+ if (Flags.enableNativeVdm()) {
+ publishBinderService(VIRTUAL_DEVICE_NATIVE_SERVICE, mNativeImpl);
+ }
publishLocalService(VirtualDeviceManagerInternal.class, mLocalService);
ActivityTaskManagerInternal activityTaskManagerInternal = getLocalService(
ActivityTaskManagerInternal.class);
@@ -590,6 +598,19 @@ public class VirtualDeviceManagerService extends SystemService {
}
}
+ final class VirtualDeviceManagerNativeImpl extends IVirtualDeviceManagerNative.Stub {
+ @Override // Binder call
+ public int[] getDeviceIdsForUid(int uid) {
+ return mLocalService
+ .getDeviceIdsForUid(uid).stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ @Override // Binder call
+ public int getDevicePolicy(int deviceId, int policyType) {
+ return mImpl.getDevicePolicy(deviceId, policyType);
+ }
+ }
+
private final class LocalService extends VirtualDeviceManagerInternal {
@GuardedBy("mVirtualDeviceManagerLock")
private final ArrayList<VirtualDisplayListener>
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index cd879083927f..8df54569cccd 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -1428,6 +1428,12 @@ public abstract class PackageManagerInternal {
@UserIdInt int userId);
/**
+ * Sends the PACKAGE_RESTARTED broadcast on the package manager handler thread.
+ */
+ public abstract void sendPackageRestartedBroadcast(@NonNull String packageName,
+ int uid, @Intent.Flags int flags);
+
+ /**
* Return a list of all historical install sessions for the given user.
*/
public abstract ParceledListSlice<PackageInstaller.SessionInfo> getHistoricalSessions(
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 330742a2d748..5fb889a23fc5 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -5023,7 +5023,7 @@ public class AccountManagerService
p.setDataPosition(0);
Bundle simulateBundle = p.readBundle();
p.recycle();
- Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
+ Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class);
if (intent != null && intent.getClass() != Intent.class) {
return false;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d3ce47c56e49..19879db1d22e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4160,26 +4160,34 @@ public class ActivityManagerService extends IActivityManager.Stub
@GuardedBy("this")
private void finishForceStopPackageLocked(final String packageName, int uid) {
- Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
- Uri.fromParts("package", packageName, null));
+ int flags = 0;
if (!mProcessesReady) {
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
- | Intent.FLAG_RECEIVER_FOREGROUND);
- }
- final int userId = UserHandle.getUserId(uid);
- final int[] broadcastAllowList =
- getPackageManagerInternal().getVisibilityAllowList(packageName, userId);
- intent.putExtra(Intent.EXTRA_UID, uid);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- broadcastIntentLocked(null /* callerApp */, null /* callerPackage */,
- null /* callerFeatureId */, intent, null /* resolvedType */,
- null /* resultToApp */, null /* resultTo */,
- 0 /* resultCode */, null /* resultData */, null /* resultExtras */,
- null /* requiredPermissions */, null /* excludedPermissions */,
- null /* excludedPackages */, OP_NONE, null /* bOptions */, false /* ordered */,
- false /* sticky */, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
- Binder.getCallingPid(), userId, BackgroundStartPrivileges.NONE,
- broadcastAllowList, null /* filterExtrasForReceiver */);
+ flags = Intent.FLAG_RECEIVER_REGISTERED_ONLY
+ | Intent.FLAG_RECEIVER_FOREGROUND;
+ }
+ if (android.content.pm.Flags.stayStopped()) {
+ // Sent async using the PM handler, to maintain ordering with PACKAGE_UNSTOPPED
+ mPackageManagerInt.sendPackageRestartedBroadcast(packageName,
+ uid, flags);
+ } else {
+ Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
+ Uri.fromParts("package", packageName, null));
+ intent.addFlags(flags);
+ final int userId = UserHandle.getUserId(uid);
+ final int[] broadcastAllowList =
+ getPackageManagerInternal().getVisibilityAllowList(packageName, userId);
+ intent.putExtra(Intent.EXTRA_UID, uid);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ broadcastIntentLocked(null /* callerApp */, null /* callerPackage */,
+ null /* callerFeatureId */, intent, null /* resolvedType */,
+ null /* resultToApp */, null /* resultTo */,
+ 0 /* resultCode */, null /* resultData */, null /* resultExtras */,
+ null /* requiredPermissions */, null /* excludedPermissions */,
+ null /* excludedPackages */, OP_NONE, null /* bOptions */, false /* ordered */,
+ false /* sticky */, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
+ Binder.getCallingPid(), userId, BackgroundStartPrivileges.NONE,
+ broadcastAllowList, null /* filterExtrasForReceiver */);
+ }
}
private void cleanupDisabledPackageComponentsLocked(
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 928b5d8f3ca7..3cf4332349d7 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1205,6 +1205,8 @@ public class AppProfiler {
trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
}
+ mLastMemoryLevel = memFactor;
+ mLastNumProcesses = mService.mProcessList.getLruSizeLOSP();
if (mService.mConstants.USE_MODERN_TRIM) {
// Modern trim is not sent based on lowmem state
// Dispatch UI_HIDDEN to processes that need it
@@ -1235,8 +1237,6 @@ public class AppProfiler {
return false;
}
- mLastMemoryLevel = memFactor;
- mLastNumProcesses = mService.mProcessList.getLruSizeLOSP();
if (memFactor != ADJ_MEM_FACTOR_NORMAL) {
if (mLowRamStartTime == 0) {
mLowRamStartTime = now;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index d8a269598bdc..3771c05a294e 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1255,11 +1255,10 @@ class ProcessRecord implements WindowProcessListener {
killProcessGroup = true;
}
if (killProcessGroup) {
- if (async) {
- ProcessList.killProcessGroup(uid, mPid);
- } else {
+ if (!async) {
Process.sendSignalToProcessGroup(uid, mPid, OsConstants.SIGKILL);
}
+ ProcessList.killProcessGroup(uid, mPid);
}
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 816043e65544..1ba1f55af71b 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -137,9 +137,11 @@ public class SettingsToPropertiesMapper {
"core_graphics",
"haptics",
"hardware_backed_security_mainline",
+ "input",
"machine_learning",
"mainline_sdk",
"media_audio",
+ "media_drm",
"media_solutions",
"nfc",
"pixel_audio_android",
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index f74b45cbdb0e..e42b66472cbe 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -875,6 +875,10 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
public void simulateVhalFingerDown(int userId, int sensorId) {
Slog.d(getTag(), "Simulate virtual HAL finger down event");
final AidlSession session = mFingerprintSensors.get(sensorId).getSessionForUser(userId);
+ if (session == null) {
+ Slog.e(getTag(), "no existing hal session found - aborting");
+ return;
+ }
final PointerContext pc = new PointerContext();
try {
session.getSession().onPointerDownWithContext(pc);
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 9e92c8d7342d..cfbe0c69b320 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -60,6 +60,9 @@ import com.android.server.display.config.LuxThrottling;
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.NonNegativeFloatToFloatPoint;
import com.android.server.display.config.Point;
+import com.android.server.display.config.PowerThrottlingConfig;
+import com.android.server.display.config.PowerThrottlingMap;
+import com.android.server.display.config.PowerThrottlingPoint;
import com.android.server.display.config.PredefinedBrightnessLimitNames;
import com.android.server.display.config.RefreshRateConfigs;
import com.android.server.display.config.RefreshRateRange;
@@ -139,6 +142,30 @@ import javax.xml.datatype.DatatypeConfigurationException;
* </screenBrightnessMap>
*
* <screenBrightnessDefault>0.65</screenBrightnessDefault>
+ * <powerThrottlingConfig>
+ * <brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed>
+ * <pollingWindowMillis>15</pollingWindowMillis>
+ * <powerThrottlingMap>
+ * <powerThrottlingPoint>
+ * <thermalStatus>severe</thermalStatus>
+ * <powerQuotaMilliWatts>200.6</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * <powerThrottlingPoint>
+ * <thermalStatus>critical</thermalStatus>
+ * <powerQuotaMilliWatts>300</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * </powerThrottlingMap>
+ * <powerThrottlingMap id="id_2"> // optional attribute, leave blank for default
+ * <powerThrottlingPoint>
+ * <thermalStatus>moderate</thermalStatus>
+ * <powerQuotaMilliWatts>400</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * <powerThrottlingPoint>
+ * <thermalStatus>severe</thermalStatus>
+ * <powerQuotaMilliWatts>250</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * </powerThrottlingMap>
+ * </powerThrottlingConfig>
*
* <thermalThrottling>
* <brightnessThrottlingMap>
@@ -669,6 +696,8 @@ public class DisplayDeviceConfig {
private List<String> mQuirks;
private boolean mIsHighBrightnessModeEnabled = false;
private HighBrightnessModeData mHbmData;
+ @Nullable
+ private PowerThrottlingConfigData mPowerThrottlingConfigData;
private DensityMapping mDensityMapping;
private String mLoadedFrom = null;
private Spline mSdrToHdrRatioSpline;
@@ -781,6 +810,9 @@ public class DisplayDeviceConfig {
private final HashMap<String, ThermalBrightnessThrottlingData>
mThermalBrightnessThrottlingDataMapByThrottlingId = new HashMap<>();
+ private final HashMap<String, PowerThrottlingData>
+ mPowerThrottlingDataMapByThrottlingId = new HashMap<>();
+
private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>>
mRefreshRateThrottlingMap = new HashMap<>();
@@ -1458,6 +1490,14 @@ public class DisplayDeviceConfig {
return hbmData;
}
+ /**
+ * @return Power throttling configuration data for the display.
+ */
+ @Nullable
+ public PowerThrottlingConfigData getPowerThrottlingConfigData() {
+ return mPowerThrottlingConfigData;
+ }
+
@NonNull
public Map<BrightnessLimitMapType, Map<Float, Float>> getLuxThrottlingData() {
return mLuxThrottlingData;
@@ -1491,6 +1531,14 @@ public class DisplayDeviceConfig {
}
/**
+ * @return power throttling configuration data for this display, for each throttling id.
+ **/
+ public HashMap<String, PowerThrottlingData>
+ getPowerThrottlingDataMapByThrottlingId() {
+ return mPowerThrottlingDataMapByThrottlingId;
+ }
+
+ /**
* @return Auto brightness darkening light debounce
*/
public long getAutoBrightnessDarkeningLightDebounce() {
@@ -1702,6 +1750,9 @@ public class DisplayDeviceConfig {
+ ", mThermalBrightnessThrottlingDataMapByThrottlingId="
+ mThermalBrightnessThrottlingDataMapByThrottlingId
+ "\n"
+ + ", mPowerThrottlingDataMapByThrottlingId="
+ + mPowerThrottlingDataMapByThrottlingId
+ + "\n"
+ "mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
+ ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
+ ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
@@ -1853,6 +1904,7 @@ public class DisplayDeviceConfig {
loadBrightnessConstraintsFromConfigXml();
loadBrightnessMap(config);
loadThermalThrottlingConfig(config);
+ loadPowerThrottlingConfigData(config);
loadHighBrightnessModeData(config);
loadLuxThrottling(config);
loadQuirks(config);
@@ -2171,6 +2223,59 @@ public class DisplayDeviceConfig {
}
}
+ private boolean loadPowerThrottlingMaps(PowerThrottlingConfig throttlingConfig) {
+ final List<PowerThrottlingMap> maps = throttlingConfig.getPowerThrottlingMap();
+ if (maps == null || maps.isEmpty()) {
+ Slog.i(TAG, "No power throttling map found");
+ return false;
+ }
+
+ for (PowerThrottlingMap map : maps) {
+ final List<PowerThrottlingPoint> points = map.getPowerThrottlingPoint();
+ // At least 1 point is guaranteed by the display device config schema
+ List<PowerThrottlingData.ThrottlingLevel> throttlingLevels =
+ new ArrayList<>(points.size());
+
+ boolean badConfig = false;
+ for (PowerThrottlingPoint point : points) {
+ ThermalStatus status = point.getThermalStatus();
+ if (!thermalStatusIsValid(status)) {
+ badConfig = true;
+ break;
+ }
+
+ throttlingLevels.add(new PowerThrottlingData.ThrottlingLevel(
+ convertThermalStatus(status),
+ point.getPowerQuotaMilliWatts().floatValue()));
+ }
+
+ if (!badConfig) {
+ String id = map.getId() == null ? DEFAULT_ID : map.getId();
+ if (mPowerThrottlingDataMapByThrottlingId.containsKey(id)) {
+ throw new RuntimeException("Power throttling data with ID " + id
+ + " already exists");
+ }
+ mPowerThrottlingDataMapByThrottlingId.put(id,
+ PowerThrottlingData.create(throttlingLevels));
+ }
+ }
+ return true;
+ }
+
+ private void loadPowerThrottlingConfigData(DisplayConfiguration config) {
+ final PowerThrottlingConfig powerThrottlingCfg = config.getPowerThrottlingConfig();
+ if (powerThrottlingCfg == null) {
+ return;
+ }
+ if (!loadPowerThrottlingMaps(powerThrottlingCfg)) {
+ return;
+ }
+ float lowestBrightnessCap = powerThrottlingCfg.getBrightnessLowestCapAllowed().floatValue();
+ int pollingWindowMillis = powerThrottlingCfg.getPollingWindowMillis().intValue();
+ mPowerThrottlingConfigData = new PowerThrottlingConfigData(lowestBrightnessCap,
+ pollingWindowMillis);
+ }
+
private void loadRefreshRateSetting(DisplayConfiguration config) {
final RefreshRateConfigs refreshRateConfigs =
(config == null) ? null : config.getRefreshRate();
@@ -3379,6 +3484,148 @@ public class DisplayDeviceConfig {
}
/**
+ * Container for Power throttling configuration data.
+ * TODO(b/302814899): extract to separate class.
+ */
+ public static class PowerThrottlingConfigData {
+ /** Lowest brightness cap allowed for this device. */
+ public final float brightnessLowestCapAllowed;
+ /** Time window for polling power in seconds. */
+ public final int pollingWindowMillis;
+ public PowerThrottlingConfigData(float brightnessLowestCapAllowed,
+ int pollingWindowMillis) {
+ this.brightnessLowestCapAllowed = brightnessLowestCapAllowed;
+ this.pollingWindowMillis = pollingWindowMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "PowerThrottlingConfigData{"
+ + "brightnessLowestCapAllowed: "
+ + brightnessLowestCapAllowed
+ + ", pollingWindowMillis: " + pollingWindowMillis
+ + "} ";
+ }
+ }
+
+ /**
+ * Container for power throttling data.
+ * TODO(b/302814899): extract to separate class and unify with ThermalBrightnessThrottlingData.
+ */
+ public static class PowerThrottlingData {
+ public List<ThrottlingLevel> throttlingLevels;
+
+ /**
+ * thermal status to power quota mapping.
+ */
+ public static class ThrottlingLevel {
+ public @PowerManager.ThermalStatus int thermalStatus;
+ public float powerQuotaMilliWatts;
+
+ public ThrottlingLevel(
+ @PowerManager.ThermalStatus int thermalStatus, float powerQuotaMilliWatts) {
+ this.thermalStatus = thermalStatus;
+ this.powerQuotaMilliWatts = powerQuotaMilliWatts;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + thermalStatus + "," + powerQuotaMilliWatts + "]";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ThrottlingLevel)) {
+ return false;
+ }
+ ThrottlingLevel otherThrottlingLevel = (ThrottlingLevel) obj;
+
+ return otherThrottlingLevel.thermalStatus == this.thermalStatus
+ && otherThrottlingLevel.powerQuotaMilliWatts == this.powerQuotaMilliWatts;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + thermalStatus;
+ result = 31 * result + Float.hashCode(powerQuotaMilliWatts);
+ return result;
+ }
+ }
+
+
+ /**
+ * Creates multiple temperature based throttling levels of power quota.
+ */
+ public static PowerThrottlingData create(
+ List<ThrottlingLevel> throttlingLevels) {
+ if (throttlingLevels == null || throttlingLevels.size() == 0) {
+ Slog.e(TAG, "PowerThrottlingData received null or empty throttling levels");
+ return null;
+ }
+
+ ThrottlingLevel prevLevel = throttlingLevels.get(0);
+ final int numLevels = throttlingLevels.size();
+ for (int i = 1; i < numLevels; i++) {
+ ThrottlingLevel thisLevel = throttlingLevels.get(i);
+
+ if (thisLevel.thermalStatus <= prevLevel.thermalStatus) {
+ Slog.e(TAG, "powerThrottlingMap must be strictly increasing, ignoring "
+ + "configuration. ThermalStatus " + thisLevel.thermalStatus + " <= "
+ + prevLevel.thermalStatus);
+ return null;
+ }
+
+ if (thisLevel.powerQuotaMilliWatts >= prevLevel.powerQuotaMilliWatts) {
+ Slog.e(TAG, "powerThrottlingMap must be strictly decreasing, ignoring "
+ + "configuration. powerQuotaMilliWatts "
+ + thisLevel.powerQuotaMilliWatts + " >= "
+ + prevLevel.powerQuotaMilliWatts);
+ return null;
+ }
+
+ prevLevel = thisLevel;
+ }
+ return new PowerThrottlingData(throttlingLevels);
+ }
+
+ @Override
+ public String toString() {
+ return "PowerThrottlingData{"
+ + "throttlingLevels:" + throttlingLevels
+ + "} ";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (!(obj instanceof PowerThrottlingData)) {
+ return false;
+ }
+
+ PowerThrottlingData otherData = (PowerThrottlingData) obj;
+ return throttlingLevels.equals(otherData.throttlingLevels);
+ }
+
+ @Override
+ public int hashCode() {
+ return throttlingLevels.hashCode();
+ }
+
+ @VisibleForTesting
+ PowerThrottlingData(List<ThrottlingLevel> inLevels) {
+ throttlingLevels = new ArrayList<>(inLevels.size());
+ for (ThrottlingLevel level : inLevels) {
+ throttlingLevels.add(new ThrottlingLevel(level.thermalStatus,
+ level.powerQuotaMilliWatts));
+ }
+ }
+ }
+
+ /**
* Container for brightness throttling data.
*/
public static class ThermalBrightnessThrottlingData {
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
index 652e6cfd67be..39f0b13f716a 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
@@ -105,16 +105,21 @@ public class HdrClamper {
public void resetHdrConfig(HdrBrightnessData data, int width, int height,
float minimumHdrPercentOfScreen, IBinder displayToken) {
mHdrBrightnessData = data;
- mHdrListener.mHdrMinPixels = (float) (width * height) * minimumHdrPercentOfScreen;
+ mHdrListener.mHdrMinPixels = minimumHdrPercentOfScreen <= 0 ? -1
+ : (float) (width * height) * minimumHdrPercentOfScreen;
if (displayToken != mRegisteredDisplayToken) { // token changed, resubscribe
if (mRegisteredDisplayToken != null) { // previous token not null, unsubscribe
mHdrListener.unregister(mRegisteredDisplayToken);
mHdrVisible = false;
+ mRegisteredDisplayToken = null;
}
- if (displayToken != null) { // new token not null, subscribe
+ // new token not null and hdr min % of the screen is set, subscribe.
+ // e.g. for virtual display, HBM data will be missing and HdrListener
+ // should not be registered
+ if (displayToken != null && mHdrListener.mHdrMinPixels > 0) {
mHdrListener.register(displayToken);
+ mRegisteredDisplayToken = displayToken;
}
- mRegisteredDisplayToken = displayToken;
}
recalculateBrightnessCap(data, mAmbientLux, mHdrVisible);
}
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index d5382cb99d22..f7b98691f3d7 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -55,6 +55,10 @@ public class DisplayManagerFlags {
Flags.FLAG_ENABLE_MODE_LIMIT_FOR_EXTERNAL_DISPLAY,
Flags::enableModeLimitForExternalDisplay);
+ private final FlagState mBackUpSmoothDisplayAndForcePeakRefreshRateFlagState = new FlagState(
+ Flags.FLAG_BACK_UP_SMOOTH_DISPLAY_AND_FORCE_PEAK_REFRESH_RATE,
+ Flags::backUpSmoothDisplayAndForcePeakRefreshRate);
+
/** Returns whether connected display management is enabled or not. */
public boolean isConnectedDisplayManagementEnabled() {
return mConnectedDisplayManagementFlagState.isEnabled();
@@ -108,6 +112,10 @@ public class DisplayManagerFlags {
return mDisplayOffloadFlagState.isEnabled();
}
+ public boolean isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled() {
+ return mBackUpSmoothDisplayAndForcePeakRefreshRateFlagState.isEnabled();
+ }
+
private static class FlagState {
private final String mName;
@@ -138,19 +146,20 @@ public class DisplayManagerFlags {
}
private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
- // TODO(b/299462337) Remove when the infrastructure is ready.
- if ((Build.IS_ENG || Build.IS_USERDEBUG)
- && SystemProperties.getBoolean("persist.sys." + flagName, false)) {
- return true;
- }
+ boolean flagValue = false;
try {
- return flagFunction.get();
+ flagValue = flagFunction.get();
} catch (Throwable ex) {
if (DEBUG) {
Slog.i(TAG, "Flags not ready yet. Return false for " + flagName, ex);
}
- return false;
}
+ // TODO(b/299462337) Remove when the infrastructure is ready.
+ if (Build.IS_ENG || Build.IS_USERDEBUG) {
+ return SystemProperties.getBoolean("persist.sys." + flagName + "-override",
+ flagValue);
+ }
+ return flagValue;
}
}
}
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 542f26cbec69..c24b3ca262be 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -72,3 +72,11 @@ flag {
bug: "299521647"
is_fixed_read_only: true
}
+
+flag {
+ name: "back_up_smooth_display_and_force_peak_refresh_rate"
+ namespace: "display_manager"
+ description: "Feature flag for backing up Smooth Display and Force Peak Refresh Rate"
+ bug: "211737588"
+ is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 71ea8cc30405..ca23844044ca 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -22,6 +22,7 @@ import static android.os.PowerManager.BRIGHTNESS_INVALID_FLOAT;
import static android.view.Display.Mode.INVALID_MODE_ID;
import static com.android.server.display.DisplayDeviceConfig.DEFAULT_LOW_REFRESH_RATE;
+import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay;
import android.annotation.IntegerRes;
import android.annotation.NonNull;
@@ -176,6 +177,8 @@ public class DisplayModeDirector {
private final boolean mIsDisplaysRefreshRatesSynchronizationEnabled;
+ private final boolean mIsBackUpSmoothDisplayAndForcePeakRefreshRateEnabled;
+
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
@NonNull DisplayManagerFlags displayManagerFlags) {
this(context, handler, new RealInjector(context), displayManagerFlags);
@@ -191,6 +194,8 @@ public class DisplayModeDirector {
.isExternalDisplayLimitModeEnabled();
mIsDisplaysRefreshRatesSynchronizationEnabled = displayManagerFlags
.isDisplaysRefreshRatesSynchronizationEnabled();
+ mIsBackUpSmoothDisplayAndForcePeakRefreshRateEnabled = displayManagerFlags
+ .isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled();
mContext = context;
mHandler = new DisplayModeDirectorHandler(handler.getLooper());
mInjector = injector;
@@ -1193,8 +1198,7 @@ public class DisplayModeDirector {
public void observe() {
final ContentResolver cr = mContext.getContentResolver();
mInjector.registerPeakRefreshRateObserver(cr, this);
- cr.registerContentObserver(mMinRefreshRateSetting, false /*notifyDescendants*/, this,
- UserHandle.USER_SYSTEM);
+ mInjector.registerMinRefreshRateObserver(cr, this);
cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
UserHandle.USER_SYSTEM);
cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/,
@@ -1292,10 +1296,34 @@ public class DisplayModeDirector {
private void updateRefreshRateSettingLocked() {
final ContentResolver cr = mContext.getContentResolver();
+ float highestRefreshRate = findHighestRefreshRateForDefaultDisplay(mContext);
+
float minRefreshRate = Settings.System.getFloatForUser(cr,
Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId());
+ if (Float.isInfinite(minRefreshRate)) {
+ // Infinity means that we want the highest possible refresh rate
+ minRefreshRate = highestRefreshRate;
+
+ if (!mIsBackUpSmoothDisplayAndForcePeakRefreshRateEnabled) {
+ // The flag had been turned off, we need to restore the original value
+ Settings.System.putFloatForUser(cr,
+ Settings.System.MIN_REFRESH_RATE, minRefreshRate, cr.getUserId());
+ }
+ }
+
float peakRefreshRate = Settings.System.getFloatForUser(cr,
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, cr.getUserId());
+ if (Float.isInfinite(peakRefreshRate)) {
+ // Infinity means that we want the highest possible refresh rate
+ peakRefreshRate = highestRefreshRate;
+
+ if (!mIsBackUpSmoothDisplayAndForcePeakRefreshRateEnabled) {
+ // The flag had been turned off, we need to restore the original value
+ Settings.System.putFloatForUser(cr,
+ Settings.System.PEAK_REFRESH_RATE, peakRefreshRate, cr.getUserId());
+ }
+ }
+
updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
}
@@ -3082,6 +3110,7 @@ public class DisplayModeDirector {
interface Injector {
Uri PEAK_REFRESH_RATE_URI = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
+ Uri MIN_REFRESH_RATE_URI = Settings.System.getUriFor(Settings.System.MIN_REFRESH_RATE);
@NonNull
DeviceConfigInterface getDeviceConfig();
@@ -3089,6 +3118,9 @@ public class DisplayModeDirector {
void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer);
+ void registerMinRefreshRateObserver(@NonNull ContentResolver cr,
+ @NonNull ContentObserver observer);
+
void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
Handler handler);
@@ -3140,6 +3172,13 @@ public class DisplayModeDirector {
}
@Override
+ public void registerMinRefreshRateObserver(@NonNull ContentResolver cr,
+ @NonNull ContentObserver observer) {
+ cr.registerContentObserver(MIN_REFRESH_RATE_URI, false /*notifyDescendants*/,
+ observer, UserHandle.USER_SYSTEM);
+ }
+
+ @Override
public void registerDisplayListener(DisplayManager.DisplayListener listener,
Handler handler) {
getDisplayManager().registerDisplayListener(listener, handler);
diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
index cd3d2f031455..0f40ca082663 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -619,8 +619,8 @@ final class UpdatableFontDir {
}
return new FontConfig(
- config.getFontFamilies(), config.getAliases(), mergedFamilies, mLastModifiedMillis,
- mConfigVersion);
+ config.getFontFamilies(), config.getAliases(), mergedFamilies,
+ config.getLocaleFallbackCustomizations(), mLastModifiedMillis, mConfigVersion);
}
private PersistentSystemFontConfig.Config readPersistentConfig() {
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index 2ede56dcecd9..a2c8748a9142 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -62,10 +62,10 @@ class GestureMonitorSpyWindow {
mWindowHandle.ownerUid = uid;
mWindowHandle.scaleFactor = 1.0f;
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
- mWindowHandle.inputConfig =
- InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;
+ mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SPY;
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_GESTURE_MONITOR);
t.setPosition(mInputSurface, 0, 0);
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 0eb620f3f4df..bad6bf0f0141 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -71,6 +71,7 @@ import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
@@ -99,7 +100,7 @@ import java.util.stream.Stream;
*
* @hide
*/
-final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
+class KeyboardLayoutManager implements InputManager.InputDeviceListener {
private static final String TAG = "KeyboardLayoutManager";
@@ -1295,7 +1296,8 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
@SuppressLint("MissingPermission")
- private List<ImeInfo> getImeInfoListForLayoutMapping() {
+ @VisibleForTesting
+ public List<ImeInfo> getImeInfoListForLayoutMapping() {
List<ImeInfo> imeInfoList = new ArrayList<>();
UserManager userManager = Objects.requireNonNull(
mContext.getSystemService(UserManager.class));
@@ -1402,7 +1404,8 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
}
- private static class ImeInfo {
+ @VisibleForTesting
+ public static class ImeInfo {
@UserIdInt int mUserId;
@NonNull InputMethodSubtypeHandle mImeSubtypeHandle;
@Nullable InputMethodSubtype mImeSubtype;
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 7726f40fa2ae..dbbbed31df76 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -57,13 +57,13 @@ final class HandwritingEventReceiverSurface {
InputConfig.NOT_FOCUSABLE
| InputConfig.NOT_TOUCHABLE
| InputConfig.SPY
- | InputConfig.INTERCEPTS_STYLUS
- | InputConfig.TRUSTED_OVERLAY;
+ | InputConfig.INTERCEPTS_STYLUS;
// Configure the surface to receive stylus events across the entire display.
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE);
t.setPosition(mInputSurface, 0, 0);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index c9528d8257c4..9dec1dff4cf0 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -63,6 +63,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.media.flags.Flags;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
@@ -161,11 +162,13 @@ class MediaRouter2ServiceImpl {
mPowerManager = mContext.getSystemService(PowerManager.class);
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
- IntentFilter screenOnOffIntentFilter = new IntentFilter();
- screenOnOffIntentFilter.addAction(ACTION_SCREEN_ON);
- screenOnOffIntentFilter.addAction(ACTION_SCREEN_OFF);
+ if (!Flags.disableScreenOffBroadcastReceiver()) {
+ IntentFilter screenOnOffIntentFilter = new IntentFilter();
+ screenOnOffIntentFilter.addAction(ACTION_SCREEN_ON);
+ screenOnOffIntentFilter.addAction(ACTION_SCREEN_OFF);
+ mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
+ }
- mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
mContext.getPackageManager().addOnPermissionsChangeListener(this::onPermissionsChanged);
MediaFeatureFlagManager.getInstance()
@@ -2779,7 +2782,8 @@ class MediaRouter2ServiceImpl {
List<ManagerRecord> managerRecords = getManagerRecords();
boolean isManagerScanning = false;
- if (service.mPowerManager.isInteractive()) {
+ if (Flags.disableScreenOffBroadcastReceiver()
+ || service.mPowerManager.isInteractive()) {
isManagerScanning = managerRecords.stream().anyMatch(manager ->
manager.mIsScanning && service.mActivityManager
.getPackageImportance(manager.mOwnerPackageName)
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index f9876299e8e0..79cd2a0b236f 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -489,6 +489,9 @@ public interface Computer extends PackageDataSnapshot {
boolean isPackageQuarantinedForUser(@NonNull String packageName, @UserIdInt int userId);
+ /** Check if the package is in a stopped state for a given user. */
+ boolean isPackageStoppedForUser(@NonNull String packageName, @UserIdInt int userId);
+
boolean isSuspendingAnyPackages(@NonNull String suspendingPackage, @UserIdInt int userId);
@NonNull
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 5d2944e17943..7db7bf538c37 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4938,7 +4938,7 @@ public class ComputerEngine implements Computer {
int userId) {
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
- false /* checkShell */, "isPackageSuspendedForUser for user " + userId);
+ false /* checkShell */, "when asking about packages for user " + userId);
final PackageStateInternal ps = mSettings.getPackage(packageName);
if (ps == null || shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId)) {
throw new IllegalArgumentException("Unknown target package: " + packageName);
@@ -4957,6 +4957,11 @@ public class ComputerEngine implements Computer {
}
@Override
+ public boolean isPackageStoppedForUser(@NonNull String packageName, @UserIdInt int userId) {
+ return getUserStageOrDefaultForUser(packageName, userId).isStopped();
+ }
+
+ @Override
public boolean isSuspendingAnyPackages(@NonNull String suspendingPackage,
@UserIdInt int userId) {
for (final PackageStateInternal packageState : getPackageStates().values()) {
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index 76203ac7650d..9a0306b77c41 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -961,6 +961,12 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub {
}
@Override
+ public final boolean isPackageStoppedForUser(@NonNull String packageName,
+ @UserIdInt int userId) {
+ return snapshot().isPackageStoppedForUser(packageName, userId);
+ }
+
+ @Override
@Deprecated
public final boolean isSafeMode() {
// allow instant applications
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 1c7024b7d239..2d192826ba9a 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -22,8 +22,6 @@ import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.os.Process.INVALID_UID;
-import static com.android.server.art.model.DexoptResult.DexContainerFileDexoptResult;
-import static com.android.server.art.model.DexoptResult.PackageDexoptResult;
import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY;
import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -58,7 +56,6 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import java.io.File;
import java.util.ArrayList;
-import java.util.LinkedHashSet;
import java.util.List;
final class InstallRequest {
@@ -150,9 +147,6 @@ final class InstallRequest {
@NonNull
private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY;
- @NonNull
- private ArrayList<String> mWarnings = new ArrayList<>();
-
// New install
InstallRequest(InstallingSession params) {
mUserId = params.getUser().getIdentifier();
@@ -664,11 +658,6 @@ final class InstallRequest {
return mUpdateBroadcastInstantUserIds;
}
- @NonNull
- public ArrayList<String> getWarnings() {
- return mWarnings;
- }
-
public void setScanFlags(int scanFlags) {
mScanFlags = scanFlags;
}
@@ -866,10 +855,6 @@ final class InstallRequest {
}
}
- public void addWarning(@NonNull String warning) {
- mWarnings.add(warning);
- }
-
public void onPrepareStarted() {
if (mPackageMetrics != null) {
mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE);
@@ -919,37 +904,22 @@ final class InstallRequest {
}
public void onDexoptFinished(DexoptResult dexoptResult) {
- // Only report external profile warnings when installing from adb. The goal is to warn app
- // developers if they have provided bad external profiles, so it's not beneficial to report
- // those warnings in the normal app install workflow.
- if (isInstallFromAdb()) {
- var externalProfileErrors = new LinkedHashSet<String>();
- for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) {
- for (DexContainerFileDexoptResult fileResult :
- packageResult.getDexContainerFileDexoptResults()) {
- externalProfileErrors.addAll(fileResult.getExternalProfileErrors());
- }
- }
- if (!externalProfileErrors.isEmpty()) {
- addWarning("Error occurred during dexopt when processing external profiles:\n "
- + String.join("\n ", externalProfileErrors));
- }
+ if (mPackageMetrics == null) {
+ return;
}
-
- // Report dexopt metrics.
- if (mPackageMetrics != null) {
- mDexoptStatus = dexoptResult.getFinalStatus();
- if (mDexoptStatus == DexoptResult.DEXOPT_PERFORMED) {
- long durationMillis = 0;
- for (PackageDexoptResult packageResult : dexoptResult.getPackageDexoptResults()) {
- for (DexContainerFileDexoptResult fileResult :
- packageResult.getDexContainerFileDexoptResults()) {
- durationMillis += fileResult.getDex2oatWallTimeMillis();
- }
- }
- mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis);
+ mDexoptStatus = dexoptResult.getFinalStatus();
+ if (mDexoptStatus != DexoptResult.DEXOPT_PERFORMED) {
+ return;
+ }
+ long durationMillis = 0;
+ for (DexoptResult.PackageDexoptResult packageResult :
+ dexoptResult.getPackageDexoptResults()) {
+ for (DexoptResult.DexContainerFileDexoptResult fileResult :
+ packageResult.getDexContainerFileDexoptResults()) {
+ durationMillis += fileResult.getDex2oatWallTimeMillis();
}
}
+ mPackageMetrics.onStepFinished(PackageMetrics.STEP_DEXOPT, durationMillis);
}
public void onInstallCompleted() {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d0e5f96f8d0f..662703992ad8 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -2930,40 +2930,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* @return a future that will be completed when the whole process is completed.
*/
private CompletableFuture<Void> install() {
- // `futures` either contains only one session (`this`) or contains one parent session
- // (`this`) and n-1 child sessions.
List<CompletableFuture<InstallResult>> futures = installNonStaged();
CompletableFuture<InstallResult>[] arr = new CompletableFuture[futures.size()];
return CompletableFuture.allOf(futures.toArray(arr)).whenComplete((r, t) -> {
if (t == null) {
setSessionApplied();
- var multiPackageWarnings = new ArrayList<String>();
- if (isMultiPackage()) {
- // This is a parent session. Collect warnings from children.
- for (CompletableFuture<InstallResult> f : futures) {
- InstallResult result = f.join();
- if (result.session != this && result.extras != null) {
- ArrayList<String> childWarnings = result.extras.getStringArrayList(
- PackageInstaller.EXTRA_WARNINGS);
- if (!ArrayUtils.isEmpty(childWarnings)) {
- multiPackageWarnings.addAll(childWarnings);
- }
- }
- }
- }
for (CompletableFuture<InstallResult> f : futures) {
InstallResult result = f.join();
- Bundle extras = result.extras;
- if (isMultiPackage() && result.session == this
- && !multiPackageWarnings.isEmpty()) {
- if (extras == null) {
- extras = new Bundle();
- }
- extras.putStringArrayList(
- PackageInstaller.EXTRA_WARNINGS, multiPackageWarnings);
- }
result.session.dispatchSessionFinished(
- INSTALL_SUCCEEDED, "Session installed", extras);
+ INSTALL_SUCCEEDED, "Session installed", result.extras);
}
} else {
PackageManagerException e = (PackageManagerException) t.getCause();
@@ -5214,10 +5189,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (!TextUtils.isEmpty(existing)) {
fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
}
- ArrayList<String> warnings = extras.getStringArrayList(PackageInstaller.EXTRA_WARNINGS);
- if (!ArrayUtils.isEmpty(warnings)) {
- fillIn.putStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS, warnings);
- }
}
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ddc8369738de..6260dd583bf9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1434,9 +1434,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
break;
}
}
- if (!request.getWarnings().isEmpty()) {
- extras.putStringArrayList(PackageInstaller.EXTRA_WARNINGS, request.getWarnings());
- }
return extras;
}
@@ -4501,6 +4498,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
boolean stopped, @UserIdInt int userId) {
if (!mUserManager.exists(userId)) return;
final int callingUid = Binder.getCallingUid();
+ boolean wasStopped = false;
if (snapshot.getInstantAppPackageName(callingUid) == null) {
final int permission = mContext.checkCallingOrSelfPermission(
Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
@@ -4522,6 +4520,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
? null : packageState.getUserStateOrDefault(userId);
if (packageState != null && packageUserState.isStopped() != stopped) {
boolean wasNotLaunched = packageUserState.isNotLaunched();
+ wasStopped = packageUserState.isStopped();
commitPackageStateMutation(null, packageName, state -> {
PackageUserStateWrite userState = state.userState(userId);
userState.setStopped(stopped);
@@ -4553,6 +4552,24 @@ public class PackageManagerService implements PackageSender, TestUtilityService
ah.setHibernatingGlobally(packageName, false);
}
});
+ // Send UNSTOPPED broadcast if necessary
+ if (wasStopped && Flags.stayStopped()) {
+ final PackageManagerInternal pmi =
+ mInjector.getLocalService(PackageManagerInternal.class);
+ final int [] userIds = resolveUserIds(userId);
+ final SparseArray<int[]> broadcastAllowList =
+ snapshotComputer().getVisibilityAllowLists(packageName, userIds);
+ final Bundle extras = new Bundle();
+ extras.putInt(Intent.EXTRA_UID, pmi.getPackageUid(packageName, 0, userId));
+ extras.putInt(Intent.EXTRA_USER_HANDLE, userId);
+ mHandler.post(() -> {
+ mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_UNSTOPPED,
+ packageName, extras,
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
+ userIds, null, broadcastAllowList, null,
+ null);
+ });
+ }
}
}
@@ -6929,6 +6946,25 @@ public class PackageManagerService implements PackageSender, TestUtilityService
public ParceledListSlice<PackageInstaller.SessionInfo> getHistoricalSessions(int userId) {
return mInstallerService.getHistoricalSessions(userId);
}
+
+ @Override
+ public void sendPackageRestartedBroadcast(@NonNull String packageName,
+ int uid, @Intent.Flags int flags) {
+ final int userId = UserHandle.getUserId(uid);
+ final int [] userIds = resolveUserIds(userId);
+ final SparseArray<int[]> broadcastAllowList =
+ snapshotComputer().getVisibilityAllowLists(packageName, userIds);
+ final Bundle extras = new Bundle();
+ extras.putInt(Intent.EXTRA_UID, uid);
+ extras.putInt(Intent.EXTRA_USER_HANDLE, userId);
+ mHandler.post(() -> {
+ mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_RESTARTED,
+ packageName, extras,
+ flags, null, null,
+ userIds, null, broadcastAllowList, null,
+ null);
+ });
+ }
}
private void setEnabledOverlayPackages(@UserIdInt int userId,
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 7264e2eff4aa..3a9272dc2003 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -4397,21 +4397,10 @@ class PackageManagerShellCommand extends ShellCommand {
session.commit(receiver.getIntentSender());
if (!session.isStaged()) {
final Intent result = receiver.getResult();
- int status = result.getIntExtra(
- PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
- List<String> warnings =
- result.getStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS);
+ final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
if (status == PackageInstaller.STATUS_SUCCESS) {
- if (!ArrayUtils.isEmpty(warnings)) {
- // Don't start the output string with "Success" because that will make adb
- // treat this as a success.
- for (String warning : warnings) {
- pw.println("Warning: " + warning);
- }
- // Treat warnings as failure to draw app developers' attention.
- status = PackageInstaller.STATUS_FAILURE;
- pw.println("Completed with warning(s)");
- } else if (logSuccess) {
+ if (logSuccess) {
pw.println("Success");
}
} else {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 68a8e40d0528..0e98158d7210 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -75,13 +75,13 @@ import android.content.pm.parsing.FrameworkParsingPackageUtils;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.multiuser.Flags;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
-import android.os.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.IProgressListener;
@@ -1559,7 +1559,7 @@ public class UserManagerService extends IUserManager.Stub {
logQuietModeEnabled(userId, enableQuietMode, callingPackage);
// Broadcast generic intents for all profiles
- if (Flags.allowPrivateProfile()) {
+ if (android.os.Flags.allowPrivateProfile()) {
broadcastProfileAvailabilityChanges(profile, parent.getUserHandle(),
enableQuietMode, false);
}
@@ -3785,6 +3785,8 @@ public class UserManagerService extends IUserManager.Stub {
@GuardedBy({"mPackagesLock"})
private void readUserListLP() {
+ // Whether guest restrictions are present on userlist.xml
+ boolean guestRestrictionsArePresentOnUserListXml = false;
try (ResilientAtomicFile file = getUserListFile()) {
FileInputStream fin = null;
try {
@@ -3834,6 +3836,7 @@ public class UserManagerService extends IUserManager.Stub {
}
}
} else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
+ guestRestrictionsArePresentOnUserListXml = true;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.END_TAG) {
if (type == XmlPullParser.START_TAG) {
@@ -3852,6 +3855,7 @@ public class UserManagerService extends IUserManager.Stub {
updateUserIds();
upgradeIfNecessaryLP();
+ updateUsersWithFeatureFlags(guestRestrictionsArePresentOnUserListXml);
} catch (Exception e) {
// Remove corrupted file and retry.
file.failRead(fin, e);
@@ -3877,6 +3881,24 @@ public class UserManagerService extends IUserManager.Stub {
}
/**
+ * Update any user formats or Xml data that need to be updated based on the current user state
+ * and the feature flag settings.
+ */
+ @GuardedBy({"mPackagesLock"})
+ private void updateUsersWithFeatureFlags(boolean guestRestrictionsArePresentOnUserListXml) {
+ // User Xml re-writes are required when guest restrictions are saved on userlist.xml but
+ // as per the feature flag it should be on the SYSTEM user's xml or guest restrictions
+ // are saved on SYSTEM user's xml but as per the flags it should not be saved there.
+ if (guestRestrictionsArePresentOnUserListXml
+ == Flags.saveGlobalAndGuestRestrictionsOnSystemUserXmlReadOnly()) {
+ for (int userId: getUserIds()) {
+ writeUserLP(getUserDataNoChecks(userId));
+ }
+ writeUserListLP();
+ }
+ }
+
+ /**
* Version of {@link #upgradeIfNecessaryLP()} that takes in the userVersion for testing
* purposes. For non-tests, use {@link #upgradeIfNecessaryLP()}.
*/
@@ -4393,9 +4415,24 @@ public class UserManagerService extends IUserManager.Stub {
UserRestrictionsUtils.writeRestrictions(serializer,
mBaseUserRestrictions.getRestrictions(userInfo.id), TAG_RESTRICTIONS);
- UserRestrictionsUtils.writeRestrictions(serializer,
- mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
- TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
+ if (Flags.saveGlobalAndGuestRestrictionsOnSystemUserXmlReadOnly()) {
+ if (userInfo.id == UserHandle.USER_SYSTEM) {
+ UserRestrictionsUtils.writeRestrictions(serializer,
+ mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
+ TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
+
+ serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
+ synchronized (mGuestRestrictions) {
+ UserRestrictionsUtils.writeRestrictions(serializer, mGuestRestrictions,
+ TAG_RESTRICTIONS);
+ }
+ serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
+ }
+ } else {
+ UserRestrictionsUtils.writeRestrictions(serializer,
+ mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
+ TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
+ }
UserRestrictionsUtils.writeRestrictions(serializer,
mDevicePolicyUserRestrictions.getRestrictions(userInfo.id),
@@ -4471,12 +4508,15 @@ public class UserManagerService extends IUserManager.Stub {
serializer.attributeInt(null, ATTR_USER_VERSION, mUserVersion);
serializer.attributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
- serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
- synchronized (mGuestRestrictions) {
- UserRestrictionsUtils
- .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
+ if (!Flags.saveGlobalAndGuestRestrictionsOnSystemUserXmlReadOnly()) {
+ serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
+ synchronized (mGuestRestrictions) {
+ UserRestrictionsUtils
+ .writeRestrictions(serializer, mGuestRestrictions,
+ TAG_RESTRICTIONS);
+ }
+ serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
}
- serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
int[] userIdsToWrite;
synchronized (mUsersLock) {
userIdsToWrite = new int[mUsers.size()];
@@ -4620,6 +4660,19 @@ public class UserManagerService extends IUserManager.Stub {
localRestrictions = UserRestrictionsUtils.readRestrictions(parser);
} else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {
globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
+ } else if (TAG_GUEST_RESTRICTIONS.equals(tag)) {
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && type != XmlPullParser.END_TAG) {
+ if (type == XmlPullParser.START_TAG) {
+ if (parser.getName().equals(TAG_RESTRICTIONS)) {
+ synchronized (mGuestRestrictions) {
+ UserRestrictionsUtils
+ .readRestrictions(parser, mGuestRestrictions);
+ }
+ }
+ break;
+ }
+ }
} else if (TAG_ACCOUNT.equals(tag)) {
type = parser.next();
if (type == XmlPullParser.TEXT) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 097656cac7f7..3a6664a72439 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -333,6 +333,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
+ // must match: config_shortPressOnSettingsBehavior in config.xml
+ static final int SHORT_PRESS_SETTINGS_NOTHING = 0;
+ static final int SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL = 1;
+ static final int LAST_SHORT_PRESS_SETTINGS_BEHAVIOR = SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL;
+
static final int PENDING_KEY_NULL = -1;
// Must match: config_shortPressOnStemPrimaryBehavior in config.xml
@@ -611,6 +616,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// What we do when the user double-taps on home
int mDoubleTapOnHomeBehavior;
+ // What we do when the user presses on settings
+ int mShortPressOnSettingsBehavior;
+
// Must match config_primaryShortPressTargetActivity in config.xml
ComponentName mPrimaryShortPressTargetActivity;
@@ -2766,6 +2774,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE;
}
+
+ mShortPressOnSettingsBehavior = res.getInteger(
+ com.android.internal.R.integer.config_shortPressOnSettingsBehavior);
+ if (mShortPressOnSettingsBehavior < SHORT_PRESS_SETTINGS_NOTHING
+ || mShortPressOnSettingsBehavior > LAST_SHORT_PRESS_SETTINGS_BEHAVIOR) {
+ mShortPressOnSettingsBehavior = SHORT_PRESS_SETTINGS_NOTHING;
+ }
}
private void updateSettings() {
@@ -3632,6 +3647,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in"
+ " interceptKeyBeforeQueueing");
return true;
+ case KeyEvent.KEYCODE_SETTINGS:
+ if (mShortPressOnSettingsBehavior == SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL) {
+ if (!down) {
+ toggleNotificationPanel();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
+ }
+ return true;
+ }
+ break;
}
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
@@ -6272,6 +6296,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print("mLongPressOnPowerBehavior=");
pw.println(longPressOnPowerBehaviorToString(mLongPressOnPowerBehavior));
pw.print(prefix);
+ pw.print("mShortPressOnSettingsBehavior=");
+ pw.println(shortPressOnSettingsBehaviorToString(mShortPressOnSettingsBehavior));
+ pw.print(prefix);
pw.print("mLongPressOnPowerAssistantTimeoutMs=");
pw.println(mLongPressOnPowerAssistantTimeoutMs);
pw.print(prefix);
@@ -6470,6 +6497,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private static String shortPressOnSettingsBehaviorToString(int behavior) {
+ switch (behavior) {
+ case SHORT_PRESS_SETTINGS_NOTHING:
+ return "SHORT_PRESS_SETTINGS_NOTHING";
+ case SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL:
+ return "SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL";
+ default:
+ return Integer.toString(behavior);
+ }
+ }
+
private static String veryLongPressOnPowerBehaviorToString(int behavior) {
switch (behavior) {
case VERY_LONG_PRESS_POWER_NOTHING:
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 9fd472057e43..12e1e2cd1e41 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -47,6 +47,7 @@ import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
@@ -1592,6 +1593,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
private void removePinnedRootTaskInSurfaceTransaction(Task rootTask) {
+ rootTask.mTransitionController.requestTransitionIfNeeded(TRANSIT_TO_BACK, 0 /* flags */,
+ rootTask, rootTask.mDisplayContent, null /* remoteTransition */,
+ null /* displayChange */);
/**
* Workaround: Force-stop all the activities in the root pinned task before we reparent them
* to the fullscreen root task. This is to guarantee that when we are removing a root task,
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 2439159164fd..73bcc8d94252 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -66,29 +66,29 @@ import java.util.Map;
public final class CompatModePackages {
/**
- * {@link CompatModePackages#DOWNSCALED_INVERSE} is the gatekeeper of all per-app buffer inverse
- * downscale changes. Enabling this change will allow the following scaling factors:
- * {@link CompatModePackages#DOWNSCALE_90}
- * {@link CompatModePackages#DOWNSCALE_85}
- * {@link CompatModePackages#DOWNSCALE_80}
- * {@link CompatModePackages#DOWNSCALE_75}
- * {@link CompatModePackages#DOWNSCALE_70}
- * {@link CompatModePackages#DOWNSCALE_65}
- * {@link CompatModePackages#DOWNSCALE_60}
- * {@link CompatModePackages#DOWNSCALE_55}
- * {@link CompatModePackages#DOWNSCALE_50}
- * {@link CompatModePackages#DOWNSCALE_45}
- * {@link CompatModePackages#DOWNSCALE_40}
- * {@link CompatModePackages#DOWNSCALE_35}
- * {@link CompatModePackages#DOWNSCALE_30}
+ * <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> is the gatekeeper of all per-app buffer
+ * inverse downscale changes. Enabling this change will allow the following scaling factors:
+ * <a href="#DOWNSCALE_90">DOWNSCALE_90</a>
+ * <a href="#DOWNSCALE_85">DOWNSCALE_85</a>
+ * <a href="#DOWNSCALE_80">DOWNSCALE_80</a>
+ * <a href="#DOWNSCALE_75">DOWNSCALE_75</a>
+ * <a href="#DOWNSCALE_70">DOWNSCALE_70</a>
+ * <a href="#DOWNSCALE_65">DOWNSCALE_65</a>
+ * <a href="#DOWNSCALE_60">DOWNSCALE_60</a>
+ * <a href="#DOWNSCALE_55">DOWNSCALE_55</a>
+ * <a href="#DOWNSCALE_50">DOWNSCALE_50</a>
+ * <a href="#DOWNSCALE_45">DOWNSCALE_45</a>
+ * <a href="#DOWNSCALE_40">DOWNSCALE_40</a>
+ * <a href="#DOWNSCALE_35">DOWNSCALE_35</a>
+ * <a href="#DOWNSCALE_30">DOWNSCALE_30</a>
*
- * If {@link CompatModePackages#DOWNSCALED_INVERSE} is enabled for an app package, then the app
- * will be forcibly resized to the lowest enabled scaling factor e.g. 1/0.8 if both 1/0.8 and
- * 1/0.7 (* 100%) were enabled.
+ * If <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> is enabled for an app package, then
+ * the app will be forcibly resized to the lowest enabled scaling factor e.g. 1/0.8 if both
+ * 1/0.8 and 1/0.7 (* 100%) were enabled.
*
- * When both {@link CompatModePackages#DOWNSCALED_INVERSE}
- * and {@link CompatModePackages#DOWNSCALED} are enabled, then
- * {@link CompatModePackages#DOWNSCALED_INVERSE} takes precedence.
+ * When both <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a>
+ * and <a href="#DOWNSCALED">DOWNSCALED</a> are enabled, then
+ * <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> takes precedence.
*/
@ChangeId
@Disabled
@@ -96,29 +96,29 @@ public final class CompatModePackages {
public static final long DOWNSCALED_INVERSE = 273564678L; // This is a Bug ID.
/**
- * {@link CompatModePackages#DOWNSCALED} is the gatekeeper of all per-app buffer downscaling
+ * <a href="#DOWNSCALED">DOWNSCALED</a> is the gatekeeper of all per-app buffer downscaling
* changes. Enabling this change will allow the following scaling factors:
- * {@link CompatModePackages#DOWNSCALE_90}
- * {@link CompatModePackages#DOWNSCALE_85}
- * {@link CompatModePackages#DOWNSCALE_80}
- * {@link CompatModePackages#DOWNSCALE_75}
- * {@link CompatModePackages#DOWNSCALE_70}
- * {@link CompatModePackages#DOWNSCALE_65}
- * {@link CompatModePackages#DOWNSCALE_60}
- * {@link CompatModePackages#DOWNSCALE_55}
- * {@link CompatModePackages#DOWNSCALE_50}
- * {@link CompatModePackages#DOWNSCALE_45}
- * {@link CompatModePackages#DOWNSCALE_40}
- * {@link CompatModePackages#DOWNSCALE_35}
- * {@link CompatModePackages#DOWNSCALE_30}
+ * <a href="#DOWNSCALE_90">DOWNSCALE_90</a>
+ * <a href="#DOWNSCALE_85">DOWNSCALE_85</a>
+ * <a href="#DOWNSCALE_80">DOWNSCALE_80</a>
+ * <a href="#DOWNSCALE_75">DOWNSCALE_75</a>
+ * <a href="#DOWNSCALE_70">DOWNSCALE_70</a>
+ * <a href="#DOWNSCALE_65">DOWNSCALE_65</a>
+ * <a href="#DOWNSCALE_60">DOWNSCALE_60</a>
+ * <a href="#DOWNSCALE_55">DOWNSCALE_55</a>
+ * <a href="#DOWNSCALE_50">DOWNSCALE_50</a>
+ * <a href="#DOWNSCALE_45">DOWNSCALE_45</a>
+ * <a href="#DOWNSCALE_40">DOWNSCALE_40</a>
+ * <a href="#DOWNSCALE_35">DOWNSCALE_35</a>
+ * <a href="#DOWNSCALE_30">DOWNSCALE_30</a>
*
- * If {@link CompatModePackages#DOWNSCALED} is enabled for an app package, then the app will be
+ * If <a href="#DOWNSCALED">DOWNSCALED</a> is enabled for an app package, then the app will be
* forcibly resized to the highest enabled scaling factor e.g. 80% if both 80% and 70% were
* enabled.
*
- * When both {@link CompatModePackages#DOWNSCALED_INVERSE}
- * and {@link CompatModePackages#DOWNSCALED} are enabled, then
- * {@link CompatModePackages#DOWNSCALED_INVERSE} takes precedence.
+ * When both <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a>
+ * and <a href="#DOWNSCALED">DOWNSCALED</a> are enabled, then
+ * <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> takes precedence.
*/
@ChangeId
@Disabled
@@ -126,12 +126,13 @@ public final class CompatModePackages {
public static final long DOWNSCALED = 168419799L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_90} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_90">DOWNSCALE_90</a> for a package will force the app to assume it's
* running on a display with 90% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 111.11% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 111.11% the vertical and horizontal resolution of
+ * the real display
*/
@ChangeId
@Disabled
@@ -139,12 +140,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_90 = 182811243L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_85} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_85">DOWNSCALE_85</a> for a package will force the app to assume it's
* running on a display with 85% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 117.65% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 117.65% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -152,12 +154,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_85 = 189969734L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_80} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_80">DOWNSCALE_80</a> for a package will force the app to assume it's
* running on a display with 80% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 125% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 125% the vertical and horizontal resolution of the real
+ * display
*/
@ChangeId
@Disabled
@@ -165,12 +168,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_80 = 176926753L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_75} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_75">DOWNSCALE_75</a> for a package will force the app to assume it's
* running on a display with 75% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 133.33% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 133.33% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -178,12 +182,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_75 = 189969779L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_70} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_70">DOWNSCALE_70</a> for a package will force the app to assume it's
* running on a display with 70% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 142.86% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 142.86% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -191,12 +196,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_70 = 176926829L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_65} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_65">DOWNSCALE_65</a> for a package will force the app to assume it's
* running on a display with 65% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 153.85% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 153.85% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -204,12 +210,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_65 = 189969744L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_60} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_60">DOWNSCALE_60</a> for a package will force the app to assume it's
* running on a display with 60% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 166.67% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 166.67% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -217,12 +224,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_60 = 176926771L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_55} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_55">DOWNSCALE_55</a> for a package will force the app to assume it's
* running on a display with 55% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 181.82% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 181.82% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -230,12 +238,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_55 = 189970036L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_50} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_50">DOWNSCALE_50</a> for a package will force the app to assume it's
* running on a display with 50% vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 200% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 200% the vertical and horizontal resolution of the real
+ * display
*/
@ChangeId
@Disabled
@@ -243,12 +252,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_50 = 176926741L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_45} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_45">DOWNSCALE_45</a> for a package will force the app to assume it's
* running on a display with 45% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 222.22% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 222.22% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -256,12 +266,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_45 = 189969782L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_40} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_40">DOWNSCALE_40</a> for a package will force the app to assume it's
* running on a display with 40% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 250% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 250% the vertical and horizontal resolution of the real
+ * display
*/
@ChangeId
@Disabled
@@ -269,12 +280,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_40 = 189970038L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_35} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_35">DOWNSCALE_35</a> for a package will force the app to assume it's
* running on a display with 35% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 285.71% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 285.71% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -282,12 +294,13 @@ public final class CompatModePackages {
public static final long DOWNSCALE_35 = 189969749L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_30} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_30">DOWNSCALE_30</a> for a package will force the app to assume it's
* running on a display with 30% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 333.33% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 333.33% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f6fe9b1dc63d..b7b5c2af0e3e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -218,6 +218,7 @@ import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.DisplayShape;
import android.view.Gravity;
+import android.view.IDecorViewGestureListener;
import android.view.IDisplayWindowInsetsController;
import android.view.ISystemGestureExclusionListener;
import android.view.IWindow;
@@ -471,6 +472,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final RemoteCallbackList<ISystemGestureExclusionListener>
mSystemGestureExclusionListeners = new RemoteCallbackList<>();
+ private final RemoteCallbackList<IDecorViewGestureListener> mDecorViewGestureListener =
+ new RemoteCallbackList<>();
private final Region mSystemGestureExclusion = new Region();
private boolean mSystemGestureExclusionWasRestricted = false;
private final Region mSystemGestureExclusionUnrestricted = new Region();
@@ -5968,6 +5971,27 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mSystemGestureExclusionListeners.unregister(listener);
}
+ void registerDecorViewGestureListener(IDecorViewGestureListener listener) {
+ mDecorViewGestureListener.register(listener);
+ }
+
+ void unregisterDecorViewGestureListener(IDecorViewGestureListener listener) {
+ mDecorViewGestureListener.unregister(listener);
+ }
+
+ void updateDecorViewGestureIntercepted(IBinder token, boolean intercepted) {
+ for (int i = mDecorViewGestureListener.beginBroadcast() - 1; i >= 0; --i) {
+ try {
+ mDecorViewGestureListener
+ .getBroadcastItem(i)
+ .onInterceptionChanged(token, intercepted);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to notify DecorViewGestureListener", e);
+ }
+ }
+ mDecorViewGestureListener.finishBroadcast();
+ }
+
void updateKeepClearAreas() {
final Set<Rect> restrictedKeepClearAreas = new ArraySet<>();
final Set<Rect> unrestrictedKeepClearAreas = new ArraySet<>();
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 0f1a1053716e..7af4aadb2f0e 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -48,7 +48,6 @@ import android.hardware.input.InputManagerGlobal;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
-import android.os.InputConfig;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -186,6 +185,10 @@ class DragState {
// Crop the input surface to the display size.
mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
+ // Make trusted overlay to not block any touches while D&D ongoing and allowing
+ // touches to pass through to windows underneath. This allows user to interact with the
+ // UI to navigate while dragging.
+ h.setTrustedOverlay(mTransaction, mInputSurface, true);
mTransaction.show(mInputSurface)
.setInputWindowInfo(mInputSurface, h)
.setLayer(mInputSurface, Integer.MAX_VALUE)
@@ -377,11 +380,6 @@ class DragState {
mDragWindowHandle.ownerUid = MY_UID;
mDragWindowHandle.scaleFactor = 1.0f;
- // InputConfig.TRUSTED_OVERLAY: To not block any touches while D&D ongoing and allowing
- // touches to pass through to windows underneath. This allows user to interact with the
- // UI to navigate while dragging.
- mDragWindowHandle.inputConfig = InputConfig.TRUSTED_OVERLAY;
-
// The drag window cannot receive new touches.
mDragWindowHandle.touchableRegion.setEmpty();
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index 39622c1c5aaf..c21930dab5eb 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -74,7 +74,7 @@ class InputConsumerImpl implements IBinder.DeathRecipient {
mWindowHandle.ownerPid = WindowManagerService.MY_PID;
mWindowHandle.ownerUid = WindowManagerService.MY_UID;
mWindowHandle.scaleFactor = 1.0f;
- mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY;
+ mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
mInputSurface = mService.makeSurfaceBuilder(
mService.mRoot.getDisplayContent(displayId).getSession())
@@ -129,12 +129,14 @@ class InputConsumerImpl implements IBinder.DeathRecipient {
void show(SurfaceControl.Transaction t, WindowContainer w) {
t.show(mInputSurface);
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setRelativeLayer(mInputSurface, w.getSurfaceControl(), 1);
}
void show(SurfaceControl.Transaction t, int layer) {
t.show(mInputSurface);
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, layer);
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 825d38b3eed7..af307ec3c2a9 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -675,6 +675,11 @@ final class InputMonitor {
w.getKeyInterceptionInfo());
if (w.mWinAnimator.hasSurface()) {
+ // Update trusted overlay changes here because they are tied to input info. Input
+ // changes can be updated even if surfaces aren't.
+ inputWindowHandle.setTrustedOverlay(mInputTransaction,
+ w.mWinAnimator.mSurfaceController.mSurfaceControl,
+ w.isWindowTrustedOverlay());
populateInputWindowHandle(inputWindowHandle, w);
setInputWindowInfoIfNeeded(mInputTransaction,
w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
@@ -732,7 +737,7 @@ final class InputMonitor {
new InputWindowHandle(null /* inputApplicationHandle */, displayId));
inputWindowHandle.setName(name);
inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
- inputWindowHandle.setTrustedOverlay(true);
+ inputWindowHandle.setTrustedOverlay(t, sc, true);
populateOverlayInputInfo(inputWindowHandle);
setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
}
diff --git a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
index 64b7a6064e45..90d81bd82087 100644
--- a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
+++ b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
@@ -195,6 +195,11 @@ class InputWindowHandleWrapper {
mChanged = true;
}
+ void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc,
+ boolean trustedOverlay) {
+ mHandle.setTrustedOverlay(t, sc, trustedOverlay);
+ }
+
void setOwnerPid(int pid) {
if (mHandle.ownerPid == pid) {
return;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index c3977d6918e3..82d4b90d06be 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -62,6 +62,7 @@ import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -244,7 +245,8 @@ public class RecentsAnimationController implements DeathRecipient {
}
@Override
- public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) {
+ public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint,
+ IResultReceiver finishCb) {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
"finish(%b): mCanceled=%b", moveHomeToTop, mCanceled);
final long token = Binder.clearCallingIdentity();
@@ -257,6 +259,13 @@ public class RecentsAnimationController implements DeathRecipient {
} finally {
Binder.restoreCallingIdentity(token);
}
+ if (finishCb != null) {
+ try {
+ finishCb.send(0, new Bundle());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to report animation finished", e);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index e6d48667ffb0..3775ccd79d4c 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -560,6 +560,16 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
@Override
+ public void reportDecorViewGestureInterceptionChanged(IWindow window, boolean intercepted) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mService.reportDecorViewGestureChanged(this, window, intercepted);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
public void reportKeepClearAreasChanged(IWindow window, List<Rect> restricted,
List<Rect> unrestricted) {
if (!mSetsUnrestrictedKeepClearAreas && !unrestricted.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 44d4c4516842..c9107e8cf5f3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -249,6 +249,7 @@ import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.ICrossWindowBlurEnabledListener;
+import android.view.IDecorViewGestureListener;
import android.view.IDisplayChangeWindowController;
import android.view.IDisplayFoldListener;
import android.view.IDisplayWindowInsetsController;
@@ -4629,8 +4630,9 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- throw new IllegalArgumentException("Trying to register visibility event "
- + "for invalid display: " + displayId);
+ throw new IllegalArgumentException(
+ "Trying to register system gesture exclusion event for invalid display: "
+ + displayId);
}
displayContent.registerSystemGestureExclusionListener(listener);
}
@@ -4642,13 +4644,64 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- throw new IllegalArgumentException("Trying to register visibility event "
- + "for invalid display: " + displayId);
+ throw new IllegalArgumentException(
+ "Trying to unregister system gesture exclusion event for invalid display: "
+ + displayId);
}
displayContent.unregisterSystemGestureExclusionListener(listener);
}
}
+ @Override
+ public void registerDecorViewGestureListener(
+ IDecorViewGestureListener listener, int displayId) {
+ if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT,
+ "registerDecorViewGestureListener()")) {
+ throw new SecurityException("Requires MONITOR_INPUT permission");
+ }
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ throw new IllegalArgumentException(
+ "Trying to register DecorView gesture event listener"
+ + "for invalid display: "
+ + displayId);
+ }
+ displayContent.registerDecorViewGestureListener(listener);
+ }
+ }
+
+ @Override
+ public void unregisterDecorViewGestureListener(
+ IDecorViewGestureListener listener, int displayId) {
+ if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT,
+ "unregisterSystemGestureExclusionListener()")) {
+ throw new SecurityException("Requires MONITOR_INPUT permission");
+ }
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ throw new IllegalArgumentException(
+ "Trying to unregister DecorView gesture event listener"
+ + "for invalid display: "
+ + displayId);
+ }
+ displayContent.unregisterDecorViewGestureListener(listener);
+ }
+ }
+
+ void reportDecorViewGestureChanged(Session session, IWindow window, boolean intercepted) {
+ synchronized (mGlobalLock) {
+ final WindowState win =
+ windowForClientLocked(session, window, false /* throwOnError */);
+ if (win == null) {
+ return;
+ }
+ win.getDisplayContent()
+ .updateDecorViewGestureIntercepted(win.mToken.token, intercepted);
+ }
+ }
+
void reportSystemGestureExclusionChanged(Session session, IWindow window,
List<Rect> exclusionRects) {
synchronized (mGlobalLock) {
@@ -8876,11 +8929,6 @@ public class WindowManagerService extends IWindowManager.Stub
h.inputConfig |= InputConfig.NOT_FOCUSABLE;
}
- // Check private trusted overlay flag to set trustedOverlay field of input window handle.
- if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
- h.inputConfig |= InputConfig.TRUSTED_OVERLAY;
- }
-
h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
h.ownerUid = callingUid;
h.ownerPid = callingPid;
@@ -8900,6 +8948,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
final SurfaceControl.Transaction t = mTransactionFactory.get();
+ // Check private trusted overlay flag to set trustedOverlay field of input window handle.
+ h.setTrustedOverlay(t, surface, (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0);
t.setInputWindowInfo(surface, h);
t.apply();
t.close();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ebef606a8d60..4beec2bc79e6 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -178,6 +178,7 @@ import static com.android.server.wm.WindowStateProto.UNRESTRICTED_KEEP_CLEAR_ARE
import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY;
import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES;
+import static com.android.window.flags.Flags.surfaceTrustedOverlay;
import android.annotation.CallSuper;
import android.annotation.NonNull;
@@ -1110,7 +1111,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mInputWindowHandle.setName(getName());
mInputWindowHandle.setPackageName(mAttrs.packageName);
mInputWindowHandle.setLayoutParamsType(mAttrs.type);
- mInputWindowHandle.setTrustedOverlay(shouldWindowHandleBeTrusted(s));
+ if (!surfaceTrustedOverlay()) {
+ mInputWindowHandle.setTrustedOverlay(isWindowTrustedOverlay());
+ }
if (DEBUG) {
Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
+ " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
@@ -1185,12 +1188,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
- boolean shouldWindowHandleBeTrusted(Session s) {
+ public boolean isWindowTrustedOverlay() {
return InputMonitor.isTrustedOverlay(mAttrs.type)
|| ((mAttrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0
- && s.mCanAddInternalSystemWindow)
+ && mSession.mCanAddInternalSystemWindow)
|| ((mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY) != 0
- && s.mCanCreateSystemApplicationOverlay);
+ && mSession.mCanCreateSystemApplicationOverlay);
}
int getTouchOcclusionMode() {
@@ -5187,6 +5190,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
updateFrameRateSelectionPriorityIfNeeded();
updateScaleIfNeeded();
mWinAnimator.prepareSurfaceLocked(getSyncTransaction());
+ if (surfaceTrustedOverlay()) {
+ getSyncTransaction().setTrustedOverlay(mSurfaceControl, isWindowTrustedOverlay());
+ }
}
super.prepareSurfaces();
}
@@ -5939,7 +5945,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
boolean isTrustedOverlay() {
- return mInputWindowHandle.isTrustedOverlay();
+ if (surfaceTrustedOverlay()) {
+ WindowState parentWindow = getParentWindow();
+ return isWindowTrustedOverlay() || (parentWindow != null
+ && parentWindow.isWindowTrustedOverlay());
+ } else {
+ return mInputWindowHandle.isTrustedOverlay();
+ }
}
public boolean receiveFocusFromTapOutside() {
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index d0a9c458a20f..debd891400b6 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -46,6 +46,8 @@
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
+ <xs:element type="powerThrottlingConfig" name="powerThrottlingConfig" minOccurs="0"
+ maxOccurs="1"/>
<xs:element type="luxThrottling" name="luxThrottling" minOccurs="0"
maxOccurs="1"/>
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
@@ -350,6 +352,43 @@
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="powerThrottlingMap">
+ <xs:sequence>
+ <xs:element name="powerThrottlingPoint" type="powerThrottlingPoint" maxOccurs="unbounded" minOccurs="1">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:string"/>
+ </xs:complexType>
+
+ <xs:complexType name="powerThrottlingPoint">
+ <xs:sequence>
+ <xs:element type="thermalStatus" name="thermalStatus">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element type="nonNegativeDecimal" name="powerQuotaMilliWatts">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="powerThrottlingConfig">
+ <xs:element type="nonNegativeDecimal" name="brightnessLowestCapAllowed">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element name="pollingWindowMillis" type="xs:nonNegativeInteger">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element type="powerThrottlingMap" name="powerThrottlingMap" maxOccurs="unbounded">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:complexType>
+
<xs:complexType name="nitsMap">
<xs:sequence>
<xs:element name="point" type="point" maxOccurs="unbounded" minOccurs="2">
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 949b1f2cb74b..2d27f0c79660 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -106,6 +106,7 @@ package com.android.server.display.config {
method public final com.android.server.display.config.SensorDetails getLightSensor();
method public com.android.server.display.config.LuxThrottling getLuxThrottling();
method @Nullable public final String getName();
+ method public com.android.server.display.config.PowerThrottlingConfig getPowerThrottlingConfig();
method public final com.android.server.display.config.SensorDetails getProxSensor();
method public com.android.server.display.config.DisplayQuirks getQuirks();
method public com.android.server.display.config.RefreshRateConfigs getRefreshRate();
@@ -138,6 +139,7 @@ package com.android.server.display.config {
method public final void setLightSensor(com.android.server.display.config.SensorDetails);
method public void setLuxThrottling(com.android.server.display.config.LuxThrottling);
method public final void setName(@Nullable String);
+ method public void setPowerThrottlingConfig(com.android.server.display.config.PowerThrottlingConfig);
method public final void setProxSensor(com.android.server.display.config.SensorDetails);
method public void setQuirks(com.android.server.display.config.DisplayQuirks);
method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs);
@@ -246,6 +248,30 @@ package com.android.server.display.config {
method public final void setValue(@NonNull java.math.BigDecimal);
}
+ public class PowerThrottlingConfig {
+ ctor public PowerThrottlingConfig();
+ method @NonNull public final java.math.BigDecimal getBrightnessLowestCapAllowed();
+ method @NonNull public final java.math.BigInteger getPollingWindowMillis();
+ method public final java.util.List<com.android.server.display.config.PowerThrottlingMap> getPowerThrottlingMap();
+ method public final void setBrightnessLowestCapAllowed(@NonNull java.math.BigDecimal);
+ method public final void setPollingWindowMillis(@NonNull java.math.BigInteger);
+ }
+
+ public class PowerThrottlingMap {
+ ctor public PowerThrottlingMap();
+ method public String getId();
+ method @NonNull public final java.util.List<com.android.server.display.config.PowerThrottlingPoint> getPowerThrottlingPoint();
+ method public void setId(String);
+ }
+
+ public class PowerThrottlingPoint {
+ ctor public PowerThrottlingPoint();
+ method @NonNull public final java.math.BigDecimal getPowerQuotaMilliWatts();
+ method @NonNull public final com.android.server.display.config.ThermalStatus getThermalStatus();
+ method public final void setPowerQuotaMilliWatts(@NonNull java.math.BigDecimal);
+ method public final void setThermalStatus(@NonNull com.android.server.display.config.ThermalStatus);
+ }
+
public enum PredefinedBrightnessLimitNames {
method public String getRawName();
enum_constant public static final com.android.server.display.config.PredefinedBrightnessLimitNames _default;
diff --git a/services/core/xsd/display-layout-config/display-layout-config.xsd b/services/core/xsd/display-layout-config/display-layout-config.xsd
index 57b5d00f75a0..4e954653bcbb 100644
--- a/services/core/xsd/display-layout-config/display-layout-config.xsd
+++ b/services/core/xsd/display-layout-config/display-layout-config.xsd
@@ -52,6 +52,7 @@
<xs:element name="address" type="xs:nonNegativeInteger"/>
<xs:element name="position" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="brightnessThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="powerThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="refreshRateThermalThrottlingMapId" type="xs:string" minOccurs="0" />
<xs:element name="leadDisplayAddress" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1" />
</xs:sequence>
diff --git a/services/core/xsd/display-layout-config/schema/current.txt b/services/core/xsd/display-layout-config/schema/current.txt
index 2d4f7a428db1..195cae5aee14 100644
--- a/services/core/xsd/display-layout-config/schema/current.txt
+++ b/services/core/xsd/display-layout-config/schema/current.txt
@@ -8,6 +8,7 @@ package com.android.server.display.config.layout {
method public String getDisplayGroup();
method public java.math.BigInteger getLeadDisplayAddress();
method public String getPosition();
+ method public String getPowerThrottlingMapId();
method public String getRefreshRateThermalThrottlingMapId();
method public String getRefreshRateZoneId();
method public boolean isDefaultDisplay();
@@ -19,6 +20,7 @@ package com.android.server.display.config.layout {
method public void setEnabled(boolean);
method public void setLeadDisplayAddress(java.math.BigInteger);
method public void setPosition(String);
+ method public void setPowerThrottlingMapId(String);
method public void setRefreshRateThermalThrottlingMapId(String);
method public void setRefreshRateZoneId(String);
}
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index a4adf5866f3d..08df65169224 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -65,6 +65,7 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageMonitor;
import com.android.server.credentials.metrics.ApiName;
import com.android.server.credentials.metrics.ApiStatus;
import com.android.server.infra.AbstractMasterSystemService;
@@ -89,7 +90,7 @@ import java.util.stream.Collectors;
*/
public final class CredentialManagerService
extends AbstractMasterSystemService<
- CredentialManagerService, CredentialManagerServiceImpl> {
+ CredentialManagerService, CredentialManagerServiceImpl> {
private static final String TAG = "CredManSysService";
private static final String PERMISSION_DENIED_ERROR = "permission_denied";
@@ -110,8 +111,7 @@ public final class CredentialManagerService
/** Cache of all ongoing request sessions per user id. */
@GuardedBy("mLock")
- private final SparseArray<Map<IBinder, RequestSession>> mRequestSessions =
- new SparseArray<>();
+ private final SparseArray<Map<IBinder, RequestSession>> mRequestSessions = new SparseArray<>();
private final SessionManager mSessionManager = new SessionManager();
@@ -123,6 +123,8 @@ public final class CredentialManagerService
null,
PACKAGE_UPDATE_POLICY_REFRESH_EAGER);
mContext = context;
+
+ mPackageMonitor.register(context, context.getMainLooper(), false);
}
@NonNull
@@ -139,8 +141,7 @@ public final class CredentialManagerService
serviceInfos.forEach(
info -> {
services.add(
- new CredentialManagerServiceImpl(this, mLock, resolvedUserId,
- info));
+ new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info));
});
return services;
}
@@ -216,8 +217,8 @@ public final class CredentialManagerService
for (CredentialManagerServiceImpl serviceToBeRemoved : servicesToBeRemoved) {
removeServiceFromCache(serviceToBeRemoved, userId);
removeServiceFromSystemServicesCache(serviceToBeRemoved, userId);
- removeServiceFromMultiModeSettings(serviceToBeRemoved.getComponentName()
- .flattenToString(), userId);
+ removeServiceFromMultiModeSettings(
+ serviceToBeRemoved.getComponentName().flattenToString(), userId);
CredentialDescriptionRegistry.forUser(userId)
.evictProviderWithPackageName(serviceToBeRemoved.getServicePackageName());
}
@@ -286,13 +287,20 @@ public final class CredentialManagerService
}
private static Set<ComponentName> getPrimaryProvidersForUserId(Context context, int userId) {
- final int resolvedUserId = ActivityManager.handleIncomingUser(
- Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, false,
- "getPrimaryProvidersForUserId", null);
- SecureSettingsServiceNameResolver resolver = new SecureSettingsServiceNameResolver(
- context, Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
- /* isMultipleMode= */ true);
+ final int resolvedUserId =
+ ActivityManager.handleIncomingUser(
+ Binder.getCallingPid(),
+ Binder.getCallingUid(),
+ userId,
+ false,
+ false,
+ "getPrimaryProvidersForUserId",
+ null);
+ SecureSettingsServiceNameResolver resolver =
+ new SecureSettingsServiceNameResolver(
+ context,
+ Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
+ /* isMultipleMode= */ true);
String[] serviceNames = resolver.readServiceNameList(resolvedUserId);
if (serviceNames == null) {
return new HashSet<ComponentName>();
@@ -329,7 +337,8 @@ public final class CredentialManagerService
final long origId = Binder.clearCallingIdentity();
try {
return DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API,
+ DeviceConfig.NAMESPACE_CREDENTIAL,
+ DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API,
false);
} finally {
Binder.restoreCallingIdentity(origId);
@@ -345,13 +354,14 @@ public final class CredentialManagerService
List<ProviderSession> providerSessions = new ArrayList<>();
for (Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult> result :
activeCredentialContainers) {
- ProviderSession providerSession = ProviderRegistryGetSession.createNewSession(
- mContext,
- UserHandle.getCallingUserId(),
- session,
- session.mClientAppInfo,
- result.second.mPackageName,
- result.first);
+ ProviderSession providerSession =
+ ProviderRegistryGetSession.createNewSession(
+ mContext,
+ UserHandle.getCallingUserId(),
+ session,
+ session.mClientAppInfo,
+ result.second.mPackageName,
+ result.first);
providerSessions.add(providerSession);
session.addProviderSession(providerSession.getComponentName(), providerSession);
}
@@ -367,23 +377,23 @@ public final class CredentialManagerService
List<ProviderSession> providerSessions = new ArrayList<>();
for (Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult> result :
activeCredentialContainers) {
- ProviderSession providerSession = ProviderRegistryGetSession.createNewSession(
- mContext,
- UserHandle.getCallingUserId(),
- session,
- session.mClientAppInfo,
- result.second.mPackageName,
- result.first);
+ ProviderSession providerSession =
+ ProviderRegistryGetSession.createNewSession(
+ mContext,
+ UserHandle.getCallingUserId(),
+ session,
+ session.mClientAppInfo,
+ result.second.mPackageName,
+ result.first);
providerSessions.add(providerSession);
session.addProviderSession(providerSession.getComponentName(), providerSession);
}
return providerSessions;
}
-
@NonNull
private Set<Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult>>
- getFilteredResultFromRegistry(List<CredentialOption> options) {
+ getFilteredResultFromRegistry(List<CredentialOption> options) {
// Session for active/provisioned credential descriptions;
CredentialDescriptionRegistry registry =
CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId());
@@ -393,10 +403,12 @@ public final class CredentialManagerService
options.stream()
.map(
getCredentialOption ->
- new HashSet<>(getCredentialOption
- .getCredentialRetrievalData()
- .getStringArrayList(
- CredentialOption.SUPPORTED_ELEMENT_KEYS)))
+ new HashSet<>(
+ getCredentialOption
+ .getCredentialRetrievalData()
+ .getStringArrayList(
+ CredentialOption
+ .SUPPORTED_ELEMENT_KEYS)))
.collect(Collectors.toSet());
// All requested credential descriptions based on the given request.
@@ -408,12 +420,14 @@ public final class CredentialManagerService
for (CredentialDescriptionRegistry.FilterResult filterResult : filterResults) {
for (CredentialOption credentialOption : options) {
- Set<String> requestedElementKeys = new HashSet<>(
- credentialOption
- .getCredentialRetrievalData()
- .getStringArrayList(CredentialOption.SUPPORTED_ELEMENT_KEYS));
- if (CredentialDescriptionRegistry.checkForMatch(filterResult.mElementKeys,
- requestedElementKeys)) {
+ Set<String> requestedElementKeys =
+ new HashSet<>(
+ credentialOption
+ .getCredentialRetrievalData()
+ .getStringArrayList(
+ CredentialOption.SUPPORTED_ELEMENT_KEYS));
+ if (CredentialDescriptionRegistry.checkForMatch(
+ filterResult.mElementKeys, requestedElementKeys)) {
result.add(new Pair<>(credentialOption, filterResult));
}
}
@@ -449,9 +463,7 @@ public final class CredentialManagerService
}
private CallingAppInfo constructCallingAppInfo(
- String realPackageName,
- int userId,
- @Nullable String origin) {
+ String realPackageName, int userId, @Nullable String origin) {
final PackageInfo packageInfo;
CallingAppInfo callingAppInfo;
try {
@@ -477,8 +489,7 @@ public final class CredentialManagerService
GetCredentialRequest request,
IGetCandidateCredentialsCallback callback,
final String callingPackage) {
- Slog.i(TAG, "starting getCandidateCredentials with callingPackage: "
- + callingPackage);
+ Slog.i(TAG, "starting getCandidateCredentials with callingPackage: " + callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
final int userId = UserHandle.getCallingUserId();
@@ -496,8 +507,7 @@ public final class CredentialManagerService
request,
constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
getEnabledProvidersForUser(userId),
- CancellationSignal.fromTransport(cancelTransport)
- );
+ CancellationSignal.fromTransport(cancelTransport));
addSessionLocked(userId, session);
List<ProviderSession> providerSessions =
@@ -531,8 +541,7 @@ public final class CredentialManagerService
IGetCredentialCallback callback,
final String callingPackage) {
final long timestampBegan = System.nanoTime();
- Slog.i(TAG, "starting executeGetCredential with callingPackage: "
- + callingPackage);
+ Slog.i(TAG, "starting executeGetCredential with callingPackage: " + callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
final int userId = UserHandle.getCallingUserId();
@@ -557,8 +566,7 @@ public final class CredentialManagerService
timestampBegan);
addSessionLocked(userId, session);
- List<ProviderSession> providerSessions =
- prepareProviderSessions(request, session);
+ List<ProviderSession> providerSessions = prepareProviderSessions(request, session);
if (providerSessions.isEmpty()) {
try {
@@ -617,15 +625,17 @@ public final class CredentialManagerService
if (providerSessions.isEmpty()) {
try {
prepareGetCredentialCallback.onResponse(
- new PrepareGetCredentialResponseInternal(PermissionUtils.hasPermission(
- mContext,
- callingPackage,
- Manifest.permission
- .CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS),
- /*credentialResultTypes=*/null,
- /*hasAuthenticationResults=*/false,
- /*hasRemoteResults=*/false,
- /*pendingIntent=*/null));
+ new PrepareGetCredentialResponseInternal(
+ PermissionUtils.hasPermission(
+ mContext,
+ callingPackage,
+ Manifest.permission
+ .CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS
+ ),
+ /* credentialResultTypes= */ null,
+ /* hasAuthenticationResults= */ false,
+ /* hasRemoteResults= */ false,
+ /* pendingIntent= */ null));
} catch (RemoteException e) {
Slog.e(
TAG,
@@ -641,27 +651,32 @@ public final class CredentialManagerService
}
private List<ProviderSession> prepareProviderSessions(
- GetCredentialRequest request,
- GetRequestSession session) {
+ GetCredentialRequest request, GetRequestSession session) {
List<ProviderSession> providerSessions;
if (isCredentialDescriptionApiEnabled()) {
List<CredentialOption> optionsThatRequireActiveCredentials =
request.getCredentialOptions().stream()
- .filter(credentialOption -> credentialOption
- .getCredentialRetrievalData()
- .getStringArrayList(
- CredentialOption
- .SUPPORTED_ELEMENT_KEYS) != null)
+ .filter(
+ credentialOption ->
+ credentialOption
+ .getCredentialRetrievalData()
+ .getStringArrayList(
+ CredentialOption
+ .SUPPORTED_ELEMENT_KEYS)
+ != null)
.toList();
List<CredentialOption> optionsThatDoNotRequireActiveCredentials =
request.getCredentialOptions().stream()
- .filter(credentialOption -> credentialOption
- .getCredentialRetrievalData()
- .getStringArrayList(
- CredentialOption
- .SUPPORTED_ELEMENT_KEYS) == null)
+ .filter(
+ credentialOption ->
+ credentialOption
+ .getCredentialRetrievalData()
+ .getStringArrayList(
+ CredentialOption
+ .SUPPORTED_ELEMENT_KEYS)
+ == null)
.toList();
List<ProviderSession> sessionsWithoutRemoteService =
@@ -706,8 +721,7 @@ public final class CredentialManagerService
ICreateCredentialCallback callback,
String callingPackage) {
final long timestampBegan = System.nanoTime();
- Slog.i(TAG, "starting executeCreateCredential with callingPackage: "
- + callingPackage);
+ Slog.i(TAG, "starting executeCreateCredential with callingPackage: " + callingPackage);
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
if (request.getOrigin() != null) {
@@ -756,8 +770,8 @@ public final class CredentialManagerService
} catch (RemoteException e) {
Slog.e(
TAG,
- "Issue invoking onError on ICreateCredentialCallback "
- + "callback: ", e);
+ "Issue invoking onError on ICreateCredentialCallback " + "callback: ",
+ e);
}
}
@@ -770,8 +784,8 @@ public final class CredentialManagerService
try {
var initMetric = session.mRequestSessionMetric.getInitialPhaseMetric();
initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime());
- MetricUtilities.logApiCalledInitialPhase(initMetric,
- session.mRequestSessionMetric.returnIncrementSequence());
+ MetricUtilities.logApiCalledInitialPhase(
+ initMetric, session.mRequestSessionMetric.returnIncrementSequence());
} catch (Exception e) {
Slog.i(TAG, "Unexpected error during metric logging: ", e);
}
@@ -779,25 +793,32 @@ public final class CredentialManagerService
@Override
public void setEnabledProviders(
- List<String> primaryProviders, List<String> providers, int userId,
+ List<String> primaryProviders,
+ List<String> providers,
+ int userId,
ISetEnabledProvidersCallback callback) {
final int callingUid = Binder.getCallingUid();
if (!hasWriteSecureSettingsPermission()) {
try {
MetricUtilities.logApiCalledSimpleV2(
- ApiName.SET_ENABLED_PROVIDERS,
- ApiStatus.FAILURE, callingUid);
+ ApiName.SET_ENABLED_PROVIDERS, ApiStatus.FAILURE, callingUid);
callback.onError(
PERMISSION_DENIED_ERROR, PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR);
} catch (RemoteException e) {
MetricUtilities.logApiCalledSimpleV2(
- ApiName.SET_ENABLED_PROVIDERS,
- ApiStatus.FAILURE, callingUid);
+ ApiName.SET_ENABLED_PROVIDERS, ApiStatus.FAILURE, callingUid);
Slog.e(TAG, "Issue with invoking response: ", e);
}
return;
}
+ // If we don't have any primary providers enabled anymore then
+ // we should erase all the providers since the feature is
+ // now disabled.
+ if (primaryProviders.isEmpty()) {
+ providers.clear();
+ }
+
userId =
ActivityManager.handleIncomingUser(
Binder.getCallingPid(),
@@ -808,17 +829,19 @@ public final class CredentialManagerService
"setEnabledProviders",
null);
- Set<String> enableProvider = new HashSet<>(providers);
- enableProvider.addAll(primaryProviders);
+ Set<String> enabledProviders = new HashSet<>(providers);
+ enabledProviders.addAll(primaryProviders);
boolean writeEnabledStatus =
- Settings.Secure.putStringForUser(getContext().getContentResolver(),
+ Settings.Secure.putStringForUser(
+ getContext().getContentResolver(),
Settings.Secure.CREDENTIAL_SERVICE,
- String.join(":", enableProvider),
+ String.join(":", enabledProviders),
userId);
boolean writePrimaryStatus =
- Settings.Secure.putStringForUser(getContext().getContentResolver(),
+ Settings.Secure.putStringForUser(
+ getContext().getContentResolver(),
Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
String.join(":", primaryProviders),
userId);
@@ -827,15 +850,13 @@ public final class CredentialManagerService
Slog.e(TAG, "Failed to store setting containing enabled or primary providers");
try {
MetricUtilities.logApiCalledSimpleV2(
- ApiName.SET_ENABLED_PROVIDERS,
- ApiStatus.FAILURE, callingUid);
+ ApiName.SET_ENABLED_PROVIDERS, ApiStatus.FAILURE, callingUid);
callback.onError(
"failed_setting_store",
"Failed to store setting containing enabled or primary providers");
} catch (RemoteException e) {
MetricUtilities.logApiCalledSimpleV2(
- ApiName.SET_ENABLED_PROVIDERS,
- ApiStatus.FAILURE, callingUid);
+ ApiName.SET_ENABLED_PROVIDERS, ApiStatus.FAILURE, callingUid);
Slog.e(TAG, "Issue with invoking error response: ", e);
return;
}
@@ -844,13 +865,11 @@ public final class CredentialManagerService
// Call the callback.
try {
MetricUtilities.logApiCalledSimpleV2(
- ApiName.SET_ENABLED_PROVIDERS,
- ApiStatus.SUCCESS, callingUid);
+ ApiName.SET_ENABLED_PROVIDERS, ApiStatus.SUCCESS, callingUid);
callback.onResponse();
} catch (RemoteException e) {
MetricUtilities.logApiCalledSimpleV2(
- ApiName.SET_ENABLED_PROVIDERS,
- ApiStatus.FAILURE, callingUid);
+ ApiName.SET_ENABLED_PROVIDERS, ApiStatus.FAILURE, callingUid);
Slog.e(TAG, "Issue with invoking response: ", e);
// TODO: Propagate failure
}
@@ -859,8 +878,10 @@ public final class CredentialManagerService
@Override
public boolean isEnabledCredentialProviderService(
ComponentName componentName, String callingPackage) {
- Slog.i(TAG, "isEnabledCredentialProviderService with componentName: "
- + componentName.flattenToString());
+ Slog.i(
+ TAG,
+ "isEnabledCredentialProviderService with componentName: "
+ + componentName.flattenToString());
// TODO(253157366): Check additional set of services.
final int userId = UserHandle.getCallingUserId();
@@ -877,7 +898,8 @@ public final class CredentialManagerService
// The component name and the package name do not match.
MetricUtilities.logApiCalledSimpleV2(
ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
- ApiStatus.FAILURE, callingUid);
+ ApiStatus.FAILURE,
+ callingUid);
Slog.w(
TAG,
"isEnabledCredentialProviderService: Component name does "
@@ -886,7 +908,8 @@ public final class CredentialManagerService
}
MetricUtilities.logApiCalledSimpleV2(
ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
- ApiStatus.SUCCESS, callingUid);
+ ApiStatus.SUCCESS,
+ callingUid);
return true;
}
}
@@ -901,13 +924,14 @@ public final class CredentialManagerService
verifyGetProvidersPermission();
final int callingUid = Binder.getCallingUid();
MetricUtilities.logApiCalledSimpleV2(
- ApiName.GET_CREDENTIAL_PROVIDER_SERVICES,
- ApiStatus.SUCCESS, callingUid);
- return CredentialProviderInfoFactory
- .getCredentialProviderServices(
- mContext, userId, providerFilter, getEnabledProvidersForUser(userId),
- getPrimaryProvidersForUserId(mContext, userId));
+ ApiName.GET_CREDENTIAL_PROVIDER_SERVICES, ApiStatus.SUCCESS, callingUid);
+ return CredentialProviderInfoFactory.getCredentialProviderServices(
+ mContext,
+ userId,
+ providerFilter,
+ getEnabledProvidersForUser(userId),
+ getPrimaryProvidersForUserId(mContext, userId));
}
@Override
@@ -917,7 +941,10 @@ public final class CredentialManagerService
final int userId = UserHandle.getCallingUserId();
return CredentialProviderInfoFactory.getCredentialProviderServicesForTesting(
- mContext, userId, providerFilter, getEnabledProvidersForUser(userId),
+ mContext,
+ userId,
+ providerFilter,
+ getEnabledProvidersForUser(userId),
getPrimaryProvidersForUserId(mContext, userId));
}
@@ -935,15 +962,22 @@ public final class CredentialManagerService
}
private Set<ComponentName> getEnabledProvidersForUser(int userId) {
- final int resolvedUserId = ActivityManager.handleIncomingUser(
- Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, false,
- "getEnabledProvidersForUser", null);
+ final int resolvedUserId =
+ ActivityManager.handleIncomingUser(
+ Binder.getCallingPid(),
+ Binder.getCallingUid(),
+ userId,
+ false,
+ false,
+ "getEnabledProvidersForUser",
+ null);
Set<ComponentName> enabledProviders = new HashSet<>();
- String directValue = Settings.Secure.getStringForUser(
- mContext.getContentResolver(), Settings.Secure.CREDENTIAL_SERVICE,
- resolvedUserId);
+ String directValue =
+ Settings.Secure.getStringForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.CREDENTIAL_SERVICE,
+ resolvedUserId);
if (!TextUtils.isEmpty(directValue)) {
String[] components = directValue.split(":");
@@ -964,8 +998,7 @@ public final class CredentialManagerService
IClearCredentialStateCallback callback,
String callingPackage) {
final long timestampBegan = System.nanoTime();
- Slog.i(TAG, "starting clearCredentialState with callingPackage: "
- + callingPackage);
+ Slog.i(TAG, "starting clearCredentialState with callingPackage: " + callingPackage);
final int userId = UserHandle.getCallingUserId();
int callingUid = Binder.getCallingUid();
enforceCallingPackage(callingPackage, callingUid);
@@ -996,13 +1029,13 @@ public final class CredentialManagerService
if (providerSessions.isEmpty()) {
try {
// TODO("Replace with properly defined error type")
- callback.onError("UNKNOWN", "No credentials available on "
- + "this device");
+ callback.onError("UNKNOWN", "No credentials available on " + "this device");
} catch (RemoteException e) {
Slog.e(
TAG,
"Issue invoking onError on IClearCredentialStateCallback "
- + "callback: ", e);
+ + "callback: ",
+ e);
}
}
@@ -1035,9 +1068,7 @@ public final class CredentialManagerService
public void unregisterCredentialDescription(
UnregisterCredentialDescriptionRequest request, String callingPackage)
throws IllegalArgumentException {
- Slog.i(TAG, "unregisterCredentialDescription with callingPackage: "
- + callingPackage);
-
+ Slog.i(TAG, "unregisterCredentialDescription with callingPackage: " + callingPackage);
if (!isCredentialDescriptionApiEnabled()) {
throw new UnsupportedOperationException("Feature not supported");
@@ -1061,18 +1092,18 @@ public final class CredentialManagerService
}
private void enforcePermissionForAllowedProviders(GetCredentialRequest request) {
- boolean containsAllowedProviders = request.getCredentialOptions()
- .stream()
- .anyMatch(option -> option.getAllowedProviders() != null
- && !option.getAllowedProviders().isEmpty());
+ boolean containsAllowedProviders =
+ request.getCredentialOptions().stream()
+ .anyMatch(
+ option ->
+ option.getAllowedProviders() != null
+ && !option.getAllowedProviders().isEmpty());
if (containsAllowedProviders) {
- mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS,
- null);
+ mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS, null);
}
}
- private void addSessionLocked(@UserIdInt int userId,
- RequestSession requestSession) {
+ private void addSessionLocked(@UserIdInt int userId, RequestSession requestSession) {
synchronized (mLock) {
mSessionManager.addSession(userId, requestSession.mRequestId, requestSession);
}
@@ -1080,11 +1111,11 @@ public final class CredentialManagerService
private void enforceCallingPackage(String callingPackage, int callingUid) {
int packageUid;
- PackageManager pm = mContext.createContextAsUser(
- UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
+ PackageManager pm =
+ mContext.createContextAsUser(UserHandle.getUserHandleForUid(callingUid), 0)
+ .getPackageManager();
try {
- packageUid = pm.getPackageUid(callingPackage,
- PackageManager.PackageInfoFlags.of(0));
+ packageUid = pm.getPackageUid(callingPackage, PackageManager.PackageInfoFlags.of(0));
} catch (PackageManager.NameNotFoundException e) {
throw new SecurityException(callingPackage + " not found");
}
@@ -1110,4 +1141,72 @@ public final class CredentialManagerService
mRequestSessions.get(userId).put(token, requestSession);
}
}
+
+ /** Updates settings when packages are removed. */
+ private final PackageMonitor mPackageMonitor =
+ new PackageMonitor() {
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ Slog.d(TAG, "onPackageRemoved: " + packageName);
+
+ // Remove any providers from the primary setting that contain the package name
+ // being removed.
+ Set<String> primaryProviders =
+ getStoredProviders(
+ Settings.Secure.CREDENTIAL_SERVICE_PRIMARY, packageName);
+ if (!Settings.Secure.putString(
+ getContext().getContentResolver(),
+ Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
+ String.join(":", primaryProviders))) {
+ Slog.w(TAG, "Failed to remove primary package: " + packageName);
+ return;
+ }
+
+ // Get the secondary providers and if there are no primary providers then
+ // we should erase all the providers from the secondary list because the
+ // feature is now disabled.
+ if (!primaryProviders.isEmpty()) {
+ return;
+ }
+
+ if (!Settings.Secure.putString(
+ getContext().getContentResolver(),
+ Settings.Secure.CREDENTIAL_SERVICE,
+ "")) {
+ Slog.w(TAG, "Failed to remove secondary package: " + packageName);
+ return;
+ }
+ }
+
+ private Set<String> getStoredProviders(String key, String packageName) {
+ // Get the current providers.
+ String rawProviders =
+ Settings.Secure.getStringForUser(
+ getContext().getContentResolver(), key,
+ UserHandle.myUserId());
+ if (rawProviders == null) {
+ Slog.w(TAG, "settings key is null: " + key);
+ return new HashSet<>();
+ }
+
+ // If the app being removed matches any of the package names from
+ // this list then don't add it in the output.
+ Set<String> providers = new HashSet<>();
+ for (String rawComponentName : rawProviders.split(":")) {
+ if (TextUtils.isEmpty(rawComponentName)
+ || rawComponentName.equals("null")) {
+ Slog.d(TAG, "provider component name is empty or null");
+ continue;
+ }
+
+ ComponentName cn = ComponentName.unflattenFromString(rawComponentName);
+ if (cn != null && !cn.getPackageName().equals(packageName)) {
+ providers.add(cn.flattenToString());
+ }
+ }
+
+ return providers;
+ }
+ };
}
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index b90f08e420e7..3c190bf7ad11 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -32,6 +32,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.ResultReceiver;
+import android.os.UserHandle;
import android.service.credentials.CredentialProviderInfoFactory;
import android.util.Slog;
@@ -171,7 +172,9 @@ public class CredentialManagerUi {
.setAction(UUID.randomUUID().toString());
//TODO: Create unique pending intent using request code and cancel any pre-existing pending
// intents
- return PendingIntent.getActivity(
- mContext, /*requestCode=*/0, intent, PendingIntent.FLAG_IMMUTABLE);
+ return PendingIntent.getActivityAsUser(
+ mContext, /*requestCode=*/0, intent,
+ PendingIntent.FLAG_IMMUTABLE, /*options=*/null,
+ UserHandle.of(mUserId));
}
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index 3eb6718c0a95..7bd1cc4ca6c8 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -31,6 +31,7 @@ import android.credentials.ui.Entry;
import android.credentials.ui.GetCredentialProviderData;
import android.credentials.ui.ProviderPendingIntentResponse;
import android.os.ICancellationSignal;
+import android.service.autofill.Flags;
import android.service.credentials.Action;
import android.service.credentials.BeginGetCredentialOption;
import android.service.credentials.BeginGetCredentialRequest;
@@ -42,6 +43,7 @@ import android.service.credentials.GetCredentialRequest;
import android.service.credentials.RemoteEntry;
import android.util.Pair;
import android.util.Slog;
+import android.view.autofill.AutofillId;
import java.util.ArrayList;
import java.util.HashMap;
@@ -379,13 +381,23 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
// but does not resolve to a valid option. For now, not skipping it because
// it may be possible that the provider adds their own extras and expects to receive
// those and complete the flow.
- if (mBeginGetOptionToCredentialOptionMap.get(id) == null) {
+ Intent intent = new Intent();
+ CredentialOption credentialOption = mBeginGetOptionToCredentialOptionMap.get(id);
+ if (credentialOption == null) {
Slog.w(TAG, "Id from Credential Entry does not resolve to a valid option");
- return new Intent();
+ return intent;
}
- return new Intent().putExtra(CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
+ AutofillId autofillId = credentialOption
+ .getCandidateQueryData()
+ .getParcelable(CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId.class);
+ if (autofillId != null && Flags.autofillCredmanIntegration()) {
+ intent.putExtra(CredentialProviderService.EXTRA_AUTOFILL_ID, autofillId);
+ }
+ return intent.putExtra(
+ CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
new GetCredentialRequest(
- mCallingAppInfo, List.of(mBeginGetOptionToCredentialOptionMap.get(id))));
+ mCallingAppInfo,
+ List.of(credentialOption)));
}
private Intent setUpFillInIntentWithQueryRequest() {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java
index 16876ac64e71..eb893fcfee1f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java
@@ -251,7 +251,14 @@ final class DevicePolicyManagerServiceShellCommand extends ShellCommand {
private int runSetDeviceOwner(PrintWriter pw) {
parseArgs();
- mService.setActiveAdmin(mComponent, /* refreshing= */ true, mUserId);
+ boolean isAdminAdded = false;
+ try {
+ mService.setActiveAdmin(mComponent, /* refreshing= */ false, mUserId);
+ isAdminAdded = true;
+ } catch (IllegalArgumentException e) {
+ pw.printf("%s was already an admin for user %d. No need to set it again.\n",
+ mComponent.flattenToShortString(), mUserId);
+ }
try {
if (!mService.setDeviceOwner(mComponent, mUserId,
@@ -260,8 +267,10 @@ final class DevicePolicyManagerServiceShellCommand extends ShellCommand {
"Can't set package " + mComponent + " as device owner.");
}
} catch (Exception e) {
- // Need to remove the admin that we just added.
- mService.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM);
+ if (isAdminAdded) {
+ // Need to remove the admin that we just added.
+ mService.removeActiveAdmin(mComponent, mUserId);
+ }
throw e;
}
diff --git a/services/foldables/devicestateprovider/tests/Android.bp b/services/foldables/devicestateprovider/tests/Android.bp
index a8db05e99179..84a6df38e0a0 100644
--- a/services/foldables/devicestateprovider/tests/Android.bp
+++ b/services/foldables/devicestateprovider/tests/Android.bp
@@ -20,11 +20,11 @@ android_test {
"foldable-device-state-provider",
"androidx.test.rules",
"junit",
- "truth-prebuilt",
+ "truth",
"mockito-target-extended-minus-junit4",
"androidx.test.uiautomator_uiautomator",
"androidx.test.ext.junit",
"testables",
],
- test_suites: ["device-tests"]
+ test_suites: ["device-tests"],
}
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index e04dd688f2a2..8b9efb312efe 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -59,7 +59,7 @@ android_robolectric_test {
"mockito-robolectric-prebuilt",
"platform-test-annotations",
"testng",
- "truth-prebuilt",
+ "truth",
],
instrumentation_for: "BackupFrameworksServicesLib",
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 36446f64bdce..ffe6dc5d1c63 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -44,7 +44,7 @@ android_test {
"service-permission.stubs.system_server",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
- "truth-prebuilt",
+ "truth",
],
libs: [
@@ -92,7 +92,7 @@ android_test {
"service-permission.stubs.system_server",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
- "truth-prebuilt",
+ "truth",
"SimpleImeTestingLib",
"SimpleImeImsLib",
],
diff --git a/services/tests/PackageManager/packageinstaller/Android.bp b/services/tests/PackageManager/packageinstaller/Android.bp
index 35d754b4adc5..e8fce8e72601 100644
--- a/services/tests/PackageManager/packageinstaller/Android.bp
+++ b/services/tests/PackageManager/packageinstaller/Android.bp
@@ -32,7 +32,7 @@ android_test {
"androidx.test.runner",
"junit",
"kotlin-test",
- "truth-prebuilt",
+ "truth",
],
platform_apis: true,
test_suites: ["device-tests"],
diff --git a/services/tests/PackageManagerComponentOverrideTests/Android.bp b/services/tests/PackageManagerComponentOverrideTests/Android.bp
index bc369701b2d4..00850a5e5be0 100644
--- a/services/tests/PackageManagerComponentOverrideTests/Android.bp
+++ b/services/tests/PackageManagerComponentOverrideTests/Android.bp
@@ -38,7 +38,7 @@ android_test {
"service-permission.stubs.system_server",
"servicestests-utils-mockito-extended",
"testng", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
index 9c4e6fd66ceb..ad7af44d4089 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
+++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
@@ -29,7 +29,7 @@ android_test {
static_libs: [
"compatibility-device-util-axt",
"androidx.test.runner",
- "truth-prebuilt",
+ "truth",
"Harrier",
],
platform_apis: true,
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index ce28682c0a25..6eacef767042 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -30,7 +30,7 @@ java_test_host {
libs: [
"tradefed",
"junit",
- "truth-prebuilt",
+ "truth",
],
static_libs: [
"ApexInstallHelper",
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
index 462c5801e952..cea9c599317d 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
@@ -38,6 +38,6 @@ android_test_helper_app {
"junit-params",
"androidx.test.ext.junit",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
index 57184748d074..ed5f2b51b9ed 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
@@ -28,6 +28,6 @@ android_test_helper_app {
"androidx.test.runner",
"junit",
"kotlin-test",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp
index a1d846e0f426..3aca1cafbf75 100644
--- a/services/tests/PackageManagerServiceTests/server/Android.bp
+++ b/services/tests/PackageManagerServiceTests/server/Android.bp
@@ -41,7 +41,7 @@ android_test {
"mockito-target-minus-junit4",
"platform-test-annotations",
"ShortcutManagerTestUtils",
- "truth-prebuilt",
+ "truth",
"testables",
"platformprotosnano",
"framework-protos",
@@ -51,7 +51,7 @@ android_test {
"servicestests-utils",
"service-permission.impl",
"testng",
- "truth-prebuilt",
+ "truth",
"junit",
"junit-params",
"platform-compat-test-rules",
diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp
index 9b3b8c35736c..8505983894a8 100644
--- a/services/tests/PackageManagerServiceTests/unit/Android.bp
+++ b/services/tests/PackageManagerServiceTests/unit/Android.bp
@@ -37,7 +37,7 @@ android_test {
"services.core",
"servicestests-utils",
"servicestests-core-utils",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
"libdexmakerjvmtiagent",
diff --git a/services/tests/RemoteProvisioningServiceTests/Android.bp b/services/tests/RemoteProvisioningServiceTests/Android.bp
index fc2c0857146b..19c913620760 100644
--- a/services/tests/RemoteProvisioningServiceTests/Android.bp
+++ b/services/tests/RemoteProvisioningServiceTests/Android.bp
@@ -30,8 +30,8 @@ android_test {
"mockito-target",
"service-rkp.impl",
"services.core",
- "truth-prebuilt",
- "truth-java8-extension-jar",
+ "truth",
+ "truth-java8-extension",
],
test_suites: [
"device-tests",
diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp
index e724e804f4e7..9dacfeabf1ef 100644
--- a/services/tests/apexsystemservices/Android.bp
+++ b/services/tests/apexsystemservices/Android.bp
@@ -34,7 +34,7 @@ java_test_host {
"compatibility-host-util",
"cts-install-lib-host",
"frameworks-base-hostutils",
- "truth-prebuilt",
+ "truth",
"modules-utils-build-testing",
],
test_suites: [
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 6ef150c80037..c37d21ae1cc0 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -179,6 +179,89 @@ public final class DisplayDeviceConfigTest {
}
@Test
+ public void testPowerThrottlingConfigFromDisplayConfig() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ DisplayDeviceConfig.PowerThrottlingConfigData powerThrottlingConfigData =
+ mDisplayDeviceConfig.getPowerThrottlingConfigData();
+ assertNotNull(powerThrottlingConfigData);
+ assertEquals(0.1f, powerThrottlingConfigData.brightnessLowestCapAllowed, SMALL_DELTA);
+ assertEquals(10, powerThrottlingConfigData.pollingWindowMillis);
+ }
+
+ @Test
+ public void testPowerThrottlingDataFromDisplayConfig() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ List<DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel>
+ defaultThrottlingLevels = new ArrayList<>();
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 800f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 600f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 400f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 200f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 100f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 50f
+ ));
+
+ DisplayDeviceConfig.PowerThrottlingData defaultThrottlingData =
+ new DisplayDeviceConfig.PowerThrottlingData(defaultThrottlingLevels);
+
+ List<DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel>
+ concurrentThrottlingLevels = new ArrayList<>();
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 800f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 600f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 400f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 200f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 100f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 50f
+ ));
+ DisplayDeviceConfig.PowerThrottlingData concurrentThrottlingData =
+ new DisplayDeviceConfig.PowerThrottlingData(concurrentThrottlingLevels);
+
+ HashMap<String, DisplayDeviceConfig.PowerThrottlingData> throttlingDataMap =
+ new HashMap<>(2);
+ throttlingDataMap.put("default", defaultThrottlingData);
+ throttlingDataMap.put("concurrent", concurrentThrottlingData);
+
+ assertEquals(throttlingDataMap,
+ mDisplayDeviceConfig.getPowerThrottlingDataMapByThrottlingId());
+ }
+
+ @Test
public void testConfigValuesFromConfigResource() {
setupDisplayDeviceConfigFromConfigResourceFile();
verifyConfigValuesFromConfigResource();
@@ -845,6 +928,64 @@ public final class DisplayDeviceConfigTest {
+ "</screenBrightnessRampSlowIncreaseIdle>\n";
}
+ private String getPowerThrottlingConfig() {
+ return "<powerThrottlingConfig >\n"
+ + "<brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed>\n"
+ + "<pollingWindowMillis>10</pollingWindowMillis>\n"
+ + "<powerThrottlingMap>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>light</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>800</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>moderate</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>600</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>severe</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>400</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>critical</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>200</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>emergency</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>100</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>shutdown</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>50</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "</powerThrottlingMap>\n"
+ + "<powerThrottlingMap id=\"concurrent\">\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>light</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>800</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>moderate</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>600</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>severe</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>400</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>critical</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>200</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>emergency</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>100</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>shutdown</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>50</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "</powerThrottlingMap>\n"
+ + "</powerThrottlingConfig>\n";
+ }
private String getScreenBrightnessRampCapsIdle() {
return "<screenBrightnessRampIncreaseMaxIdleMillis>"
+ "4000"
@@ -915,6 +1056,7 @@ public final class DisplayDeviceConfigTest {
+ "</displayBrightnessPoint>\n"
+ "</displayBrightnessMapping>\n"
+ "</autoBrightness>\n"
+ + getPowerThrottlingConfig()
+ "<highBrightnessMode enabled=\"true\">\n"
+ "<transitionPoint>" + BRIGHTNESS[1] + "</transitionPoint>\n"
+ "<minimumLux>10000</minimumLux>\n"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java b/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
new file mode 100644
index 000000000000..5c50acb13f30
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import android.hardware.display.DisplayManager;
+import android.testing.TestableContext;
+import android.view.Display;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.display.RefreshRateSettingsUtils;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RefreshRateSettingsUtilsTest {
+
+ @Rule
+ public final TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getContext());
+
+ @Mock
+ private DisplayManager mDisplayManagerMock;
+ @Mock
+ private Display mDisplayMock;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext.addMockSystemService(DisplayManager.class, mDisplayManagerMock);
+
+ Display.Mode[] modes = new Display.Mode[]{
+ new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+ /* refreshRate= */ 60),
+ new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+ /* refreshRate= */ 120),
+ new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
+ /* refreshRate= */ 90)
+ };
+
+ when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
+ when(mDisplayMock.getSupportedModes()).thenReturn(modes);
+ }
+
+ @Test
+ public void testFindHighestRefreshRateForDefaultDisplay() {
+ when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(null);
+ assertEquals(DEFAULT_REFRESH_RATE,
+ RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
+ /* delta= */ 0);
+
+ when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
+ assertEquals(120,
+ RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
+ /* delta= */ 0);
+ }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
index c63fac9832e9..ee187baf524e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
@@ -22,6 +22,9 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -97,6 +100,37 @@ public class HdrClamperTest {
}
@Test
+ public void testRegisterHdrListener() {
+ verify(mMockHdrInfoListener).register(mMockBinder);
+ }
+
+ @Test
+ public void testRegisterOtherHdrListenerWhenCalledWithOtherToken() {
+ IBinder otherBinder = mock(IBinder.class);
+ mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, MIN_HDR_PERCENT, otherBinder);
+
+ verify(mMockHdrInfoListener).unregister(mMockBinder);
+ verify(mMockHdrInfoListener).register(otherBinder);
+ }
+
+ @Test
+ public void testRegisterHdrListenerOnceWhenCalledWithSameToken() {
+ mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, MIN_HDR_PERCENT, mMockBinder);
+
+ verify(mMockHdrInfoListener, never()).unregister(mMockBinder);
+ verify(mMockHdrInfoListener, times(1)).register(mMockBinder);
+ }
+
+ @Test
+ public void testRegisterNotCalledIfHbmConfigIsMissing() {
+ IBinder otherBinder = mock(IBinder.class);
+ mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, -1, otherBinder);
+
+ verify(mMockHdrInfoListener).unregister(mMockBinder);
+ verify(mMockHdrInfoListener, never()).register(otherBinder);
+ }
+
+ @Test
public void testClamper_AmbientLuxChangesAboveLimit() {
mHdrClamper.onAmbientLuxChange(500);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index b8c18e070397..c4f72b307eb7 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -27,6 +27,7 @@ import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_R
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.server.display.mode.Vote.INVALID_SIZE;
import static com.google.common.truth.Truth.assertThat;
@@ -85,10 +86,12 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.display.BrightnessSynchronizer;
+import com.android.internal.display.RefreshRateSettingsUtils;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.Preconditions;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.display.DisplayDeviceConfig;
import com.android.server.display.TestUtils;
import com.android.server.display.feature.DisplayManagerFlags;
@@ -106,7 +109,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
@@ -252,9 +255,15 @@ public class DisplayModeDirectorTest {
@Mock
private DisplayManagerFlags mDisplayManagerFlags;
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule =
+ new ExtendedMockitoRule.Builder(this)
+ .setStrictness(Strictness.LENIENT)
+ .spyStatic(RefreshRateSettingsUtils.class)
+ .build();
+
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext);
when(mContext.getContentResolver()).thenReturn(resolver);
@@ -1470,6 +1479,94 @@ public class DisplayModeDirectorTest {
}
@Test
+ public void testPeakRefreshRate_FlagEnabled() {
+ when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
+ .thenReturn(true);
+ float highestRefreshRate = 130;
+ doReturn(highestRefreshRate).when(() ->
+ RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+ director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
+
+ Sensor lightSensor = createLightSensor();
+ SensorManager sensorManager = createMockSensorManager(lightSensor);
+ director.start(sensorManager);
+
+ setPeakRefreshRate(Float.POSITIVE_INFINITY);
+
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
+ Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
+ highestRefreshRate);
+ }
+
+ @Test
+ public void testPeakRefreshRate_FlagDisabled() {
+ when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
+ .thenReturn(false);
+ float peakRefreshRate = 130;
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+ director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
+
+ Sensor lightSensor = createLightSensor();
+ SensorManager sensorManager = createMockSensorManager(lightSensor);
+ director.start(sensorManager);
+
+ setPeakRefreshRate(peakRefreshRate);
+
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
+ Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
+ peakRefreshRate);
+ }
+
+ @Test
+ public void testMinRefreshRate_FlagEnabled() {
+ when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
+ .thenReturn(true);
+ float highestRefreshRate = 130;
+ doReturn(highestRefreshRate).when(() ->
+ RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+ director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
+
+ Sensor lightSensor = createLightSensor();
+ SensorManager sensorManager = createMockSensorManager(lightSensor);
+ director.start(sensorManager);
+
+ setMinRefreshRate(Float.POSITIVE_INFINITY);
+
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
+ Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
+ /* frameRateHigh= */ Float.POSITIVE_INFINITY);
+ }
+
+ @Test
+ public void testMinRefreshRate_FlagDisabled() {
+ when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
+ .thenReturn(false);
+ float minRefreshRate = 130;
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+ director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
+
+ Sensor lightSensor = createLightSensor();
+ SensorManager sensorManager = createMockSensorManager(lightSensor);
+ director.start(sensorManager);
+
+ setMinRefreshRate(minRefreshRate);
+
+ Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
+ Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
+ assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ minRefreshRate,
+ /* frameRateHigh= */ Float.POSITIVE_INFINITY);
+ }
+
+ @Test
public void testSensorRegistration() {
// First, configure brightness zones or DMD won't register for sensor data.
final FakeDeviceConfig config = mInjector.getDeviceConfig();
@@ -3167,6 +3264,13 @@ public class DisplayModeDirectorTest {
waitForIdleSync();
}
+ private void setMinRefreshRate(float fps) {
+ Settings.System.putFloat(mContext.getContentResolver(), Settings.System.MIN_REFRESH_RATE,
+ fps);
+ mInjector.notifyMinRefreshRateChanged();
+ waitForIdleSync();
+ }
+
private static SensorManager createMockSensorManager(Sensor... sensors) {
SensorManager sensorManager = mock(SensorManager.class);
when(sensorManager.getSensorList(anyInt())).then((invocation) -> {
@@ -3216,6 +3320,7 @@ public class DisplayModeDirectorTest {
private final SensorManagerInternal mSensorManagerInternal;
private ContentObserver mPeakRefreshRateObserver;
+ private ContentObserver mMinRefreshRateObserver;
FakesInjector() {
this(null, null, null);
@@ -3247,6 +3352,12 @@ public class DisplayModeDirectorTest {
}
@Override
+ public void registerMinRefreshRateObserver(@NonNull ContentResolver cr,
+ @NonNull ContentObserver observer) {
+ mMinRefreshRateObserver = observer;
+ }
+
+ @Override
public void registerDisplayListener(DisplayListener listener, Handler handler) {}
@Override
@@ -3318,5 +3429,12 @@ public class DisplayModeDirectorTest {
PEAK_REFRESH_RATE_URI);
}
}
+
+ void notifyMinRefreshRateChanged() {
+ if (mMinRefreshRateObserver != null) {
+ mMinRefreshRateObserver.dispatchChange(false /*selfChange*/,
+ MIN_REFRESH_RATE_URI);
+ }
+ }
}
}
diff --git a/services/tests/inprocesstests/Android.bp b/services/tests/inprocesstests/Android.bp
index 7c237ac6befb..086e84b86aca 100644
--- a/services/tests/inprocesstests/Android.bp
+++ b/services/tests/inprocesstests/Android.bp
@@ -14,7 +14,7 @@ android_test {
"androidx.test.core",
"androidx.test.rules",
"services.core",
- "truth-prebuilt",
+ "truth",
"platform-test-annotations",
],
test_suites: ["general-tests"],
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 0813bb09fd52..063af573e1f3 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -68,7 +68,7 @@ android_test {
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
"testables",
- "truth-prebuilt",
+ "truth",
// TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
"testng",
"compatibility-device-util-axt",
diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp
index 8ab45070a017..18a4f0068909 100644
--- a/services/tests/powerstatstests/Android.bp
+++ b/services/tests/powerstatstests/Android.bp
@@ -16,7 +16,7 @@ android_test {
"coretests-aidl",
"platformprotosnano",
"junit",
- "truth-prebuilt",
+ "truth",
"androidx.test.runner",
"androidx.test.ext.junit",
"androidx.test.ext.truth",
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 71f7f577d038..2ece8c74420c 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -61,7 +61,7 @@ android_test {
"mockito-target-minus-junit4",
"platform-test-annotations",
"ShortcutManagerTestUtils",
- "truth-prebuilt",
+ "truth",
"testables",
"androidx.test.uiautomator_uiautomator",
"platformprotosnano",
@@ -72,7 +72,7 @@ android_test {
// TODO: remove once Android migrates to JUnit 4.12,
// which provides assertThrows
"testng",
- "truth-prebuilt",
+ "truth",
"junit",
"junit-params",
"ActivityContext",
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 61b30a024478..e8cbcf9a6874 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -233,6 +233,7 @@ public class VirtualDeviceManagerServiceTest {
private VirtualDeviceManagerService mVdms;
private VirtualDeviceManagerInternal mLocalService;
private VirtualDeviceManagerService.VirtualDeviceManagerImpl mVdm;
+ private VirtualDeviceManagerService.VirtualDeviceManagerNativeImpl mVdmNative;
private VirtualDeviceLog mVirtualDeviceLog;
@Mock
private InputController.NativeWrapper mNativeWrapperMock;
@@ -340,6 +341,7 @@ public class VirtualDeviceManagerServiceTest {
mSetFlagsRule.disableFlags(Flags.FLAG_DYNAMIC_POLICY);
mSetFlagsRule.disableFlags(Flags.FLAG_STREAM_PERMISSIONS);
mSetFlagsRule.disableFlags(Flags.FLAG_VDM_CUSTOM_HOME);
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_NATIVE_VDM);
doReturn(true).when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt());
doNothing().when(mInputManagerInternalMock).setPointerAcceleration(anyFloat(), anyInt());
@@ -384,6 +386,7 @@ public class VirtualDeviceManagerServiceTest {
mVdms = new VirtualDeviceManagerService(mContext);
mLocalService = mVdms.getLocalServiceInstance();
mVdm = mVdms.new VirtualDeviceManagerImpl();
+ mVdmNative = mVdms.new VirtualDeviceManagerNativeImpl();
mVirtualDeviceLog = new VirtualDeviceLog(mContext);
mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1);
mSensorController = mDeviceImpl.getSensorControllerForTest();
@@ -440,24 +443,32 @@ public class VirtualDeviceManagerServiceTest {
public void getDevicePolicy_invalidDeviceId_returnsDefault() {
assertThat(mVdm.getDevicePolicy(DEVICE_ID_INVALID, POLICY_TYPE_SENSORS))
.isEqualTo(DEVICE_POLICY_DEFAULT);
+ assertThat(mVdmNative.getDevicePolicy(DEVICE_ID_INVALID, POLICY_TYPE_SENSORS))
+ .isEqualTo(DEVICE_POLICY_DEFAULT);
}
@Test
public void getDevicePolicy_defaultDeviceId_returnsDefault() {
assertThat(mVdm.getDevicePolicy(DEVICE_ID_DEFAULT, POLICY_TYPE_SENSORS))
.isEqualTo(DEVICE_POLICY_DEFAULT);
+ assertThat(mVdmNative.getDevicePolicy(DEVICE_ID_DEFAULT, POLICY_TYPE_SENSORS))
+ .isEqualTo(DEVICE_POLICY_DEFAULT);
}
@Test
public void getDevicePolicy_nonExistentDeviceId_returnsDefault() {
assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId() + 1, POLICY_TYPE_SENSORS))
.isEqualTo(DEVICE_POLICY_DEFAULT);
+ assertThat(mVdmNative.getDevicePolicy(mDeviceImpl.getDeviceId() + 1, POLICY_TYPE_SENSORS))
+ .isEqualTo(DEVICE_POLICY_DEFAULT);
}
@Test
public void getDevicePolicy_unspecifiedPolicy_returnsDefault() {
assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS))
.isEqualTo(DEVICE_POLICY_DEFAULT);
+ assertThat(mVdmNative.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS))
+ .isEqualTo(DEVICE_POLICY_DEFAULT);
}
@Test
@@ -472,6 +483,8 @@ public class VirtualDeviceManagerServiceTest {
assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS))
.isEqualTo(DEVICE_POLICY_CUSTOM);
+ assertThat(mVdmNative.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS))
+ .isEqualTo(DEVICE_POLICY_CUSTOM);
}
@Test
@@ -567,8 +580,8 @@ public class VirtualDeviceManagerServiceTest {
@Test
public void getDeviceIdsForUid_noRunningApps_returnsNull() {
- Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1);
- assertThat(deviceIds).isEmpty();
+ assertThat(mLocalService.getDeviceIdsForUid(UID_1)).isEmpty();
+ assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).isEmpty();
}
@Test
@@ -577,8 +590,8 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1).onRunningAppsChanged(
Sets.newArraySet(UID_2));
- Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1);
- assertThat(deviceIds).isEmpty();
+ assertThat(mLocalService.getDeviceIdsForUid(UID_1)).isEmpty();
+ assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).isEmpty();
}
@Test
@@ -587,8 +600,9 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1).onRunningAppsChanged(
Sets.newArraySet(UID_1));
- Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1);
- assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId());
+ int deviceId = mDeviceImpl.getDeviceId();
+ assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(deviceId);
+ assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(deviceId);
}
@Test
@@ -598,8 +612,9 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1).onRunningAppsChanged(
Sets.newArraySet(UID_1, UID_2));
- Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1);
- assertThat(deviceIds).containsExactly(mDeviceImpl.getDeviceId());
+ int deviceId = mDeviceImpl.getDeviceId();
+ assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(deviceId);
+ assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(deviceId);
}
@Test
@@ -611,8 +626,9 @@ public class VirtualDeviceManagerServiceTest {
secondDevice.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_2).onRunningAppsChanged(
Sets.newArraySet(UID_1));
- Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1);
- assertThat(deviceIds).containsExactly(secondDevice.getDeviceId());
+ int deviceId = secondDevice.getDeviceId();
+ assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(deviceId);
+ assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(deviceId);
}
@Test
@@ -628,8 +644,9 @@ public class VirtualDeviceManagerServiceTest {
secondDevice.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_2).onRunningAppsChanged(
Sets.newArraySet(UID_1, UID_2));
- Set<Integer> deviceIds = mLocalService.getDeviceIdsForUid(UID_1);
- assertThat(deviceIds).containsExactly(
+ assertThat(mLocalService.getDeviceIdsForUid(UID_1)).containsExactly(
+ mDeviceImpl.getDeviceId(), secondDevice.getDeviceId());
+ assertThat(mVdmNative.getDeviceIdsForUid(UID_1)).asList().containsExactly(
mDeviceImpl.getDeviceId(), secondDevice.getDeviceId());
}
diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
index 184c976b86bf..3de167e72ba0 100644
--- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
+++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
@@ -336,7 +336,8 @@ public final class UpdatableFontDirTest {
return new FontConfig(Collections.emptyList(),
Collections.emptyList(),
Collections.singletonList(new FontConfig.NamedFamilyList(
- Collections.singletonList(family), "sans-serif")), 0, 1);
+ Collections.singletonList(family), "sans-serif")),
+ Collections.emptyList(), 0, 1);
};
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
@@ -499,7 +500,8 @@ public final class UpdatableFontDirTest {
Collections.emptyList(),
Collections.emptyList(),
Collections.singletonList(new FontConfig.NamedFamilyList(
- Collections.singletonList(family), "sans-serif")), 0, 1);
+ Collections.singletonList(family), "sans-serif")),
+ Collections.emptyList(), 0, 1);
});
dir.loadFontFileMap();
@@ -651,7 +653,8 @@ public final class UpdatableFontDirTest {
FontFamily.Builder.VARIABLE_FONT_FAMILY_TYPE_NONE);
return new FontConfig(Collections.emptyList(), Collections.emptyList(),
Collections.singletonList(new FontConfig.NamedFamilyList(
- Collections.singletonList(family), "sans-serif")), 0, 1);
+ Collections.singletonList(family), "sans-serif")),
+ Collections.emptyList(), 0, 1);
});
dir.loadFontFileMap();
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index 9f75cf8d552e..253592c9a07d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -43,6 +43,7 @@ import android.annotation.UserIdInt;
import android.app.PropertyInvalidatedCache;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo.UserInfoFlag;
+import android.multiuser.Flags;
import android.os.Looper;
import android.os.Parcel;
import android.os.UserHandle;
@@ -124,18 +125,34 @@ public class UserManagerServiceUserInfoTest {
mUserManagerService.putUserInfo(data.info);
- // Set a global and user restriction so they get written out to the user file.
+ //Local restrictions are written to the user specific files and global restrictions
+ // are written to the SYSTEM user file.
setUserRestrictions(data.info.id, globalRestriction, localRestriction, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
mUserManagerService.writeUserLP(data, out);
- byte[] bytes = baos.toByteArray();
+ byte[] secondaryUserBytes = baos.toByteArray();
+ baos.reset();
+
+ byte[] systemUserBytes = new byte[0];
+ if (Flags.saveGlobalAndGuestRestrictionsOnSystemUserXmlReadOnly()) {
+ UserData systemUserData = new UserData();
+ systemUserData.info = mUserManagerService.getUserInfo(UserHandle.USER_SYSTEM);
+ mUserManagerService.writeUserLP(systemUserData, baos);
+ systemUserBytes = baos.toByteArray();
+ }
// Clear the restrictions to see if they are properly read in from the user file.
setUserRestrictions(data.info.id, globalRestriction, localRestriction, false);
- mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(bytes));
+ //read the secondary and SYSTEM user file to fetch local/global device policy restrictions.
+ mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(secondaryUserBytes));
+ if (Flags.saveGlobalAndGuestRestrictionsOnSystemUserXmlReadOnly()) {
+ mUserManagerService.readUserLP(UserHandle.USER_SYSTEM,
+ new ByteArrayInputStream(systemUserBytes));
+ }
+
assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(globalRestriction));
assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(localRestriction));
}
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 1d37f9da8d7a..d1f4961ab7e5 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -39,7 +39,7 @@ android_test {
"hamcrest-library",
"servicestests-utils",
"testables",
- "truth-prebuilt",
+ "truth",
// TODO: remove once Android migrates to JUnit 4.12,
// which provides assertThrows
"testng",
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index c05f81497e57..53ca704b6d86 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -23,9 +23,7 @@ import static android.service.notification.NotificationListenerService.Ranking.U
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
@@ -49,12 +47,10 @@ import android.graphics.drawable.Icon;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
-import android.os.Parcel;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.NotificationRankingUpdate;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
@@ -158,81 +154,6 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
}
}
- // Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking.
- @Test
- public void testRankingUpdate_parcel() {
- NotificationRankingUpdate nru = generateUpdate();
- Parcel parcel = Parcel.obtain();
- nru.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel);
- assertEquals(nru, nru1);
- }
-
- // Tests parceling of RankingMap and RankingMap.equals
- @Test
- public void testRankingMap_parcel() {
- RankingMap rmap = generateUpdate().getRankingMap();
- Parcel parcel = Parcel.obtain();
- rmap.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- RankingMap rmap1 = RankingMap.CREATOR.createFromParcel(parcel);
-
- detailedAssertEquals(rmap, rmap1);
- assertEquals(rmap, rmap1);
- }
-
- // Tests parceling of Ranking and Ranking.equals
- @Test
- public void testRanking_parcel() {
- Ranking ranking = generateUpdate().getRankingMap().getRawRankingObject(mKeys[0]);
- Parcel parcel = Parcel.obtain();
- ranking.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- Ranking ranking1 = new Ranking(parcel);
- detailedAssertEquals("rankings differ: ", ranking, ranking1);
- assertEquals(ranking, ranking1);
- }
-
- // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking.
- @Test
- public void testRankingUpdate_equals() {
- NotificationRankingUpdate nru = generateUpdate();
- NotificationRankingUpdate nru2 = generateUpdate();
- detailedAssertEquals(nru, nru2);
- assertEquals(nru, nru2);
- Ranking tweak = nru2.getRankingMap().getRawRankingObject(mKeys[0]);
- tweak.populate(
- tweak.getKey(),
- tweak.getRank(),
- !tweak.matchesInterruptionFilter(), // note the inversion here!
- tweak.getLockscreenVisibilityOverride(),
- tweak.getSuppressedVisualEffects(),
- tweak.getImportance(),
- tweak.getImportanceExplanation(),
- tweak.getOverrideGroupKey(),
- tweak.getChannel(),
- (ArrayList) tweak.getAdditionalPeople(),
- (ArrayList) tweak.getSnoozeCriteria(),
- tweak.canShowBadge(),
- tweak.getUserSentiment(),
- tweak.isSuspended(),
- tweak.getLastAudiblyAlertedMillis(),
- tweak.isNoisy(),
- (ArrayList) tweak.getSmartActions(),
- (ArrayList) tweak.getSmartReplies(),
- tweak.canBubble(),
- tweak.isTextChanged(),
- tweak.isConversation(),
- tweak.getConversationShortcutInfo(),
- tweak.getRankingAdjustment(),
- tweak.isBubble(),
- tweak.getProposedImportance(),
- tweak.hasSensitiveContent()
- );
- assertNotEquals(nru, nru2);
- }
-
@Test
public void testLegacyIcons_preM() {
TestListenerService service = new TestListenerService();
@@ -275,7 +196,6 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
assertNull(n.largeIcon);
}
-
// Test data
private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
@@ -461,48 +381,6 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
}
}
- private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
- detailedAssertEquals(a.getRankingMap(), b.getRankingMap());
- }
-
- private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
- assertEquals(comment, a.getKey(), b.getKey());
- assertEquals(comment, a.getRank(), b.getRank());
- assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
- assertEquals(comment, a.getLockscreenVisibilityOverride(), b.getLockscreenVisibilityOverride());
- assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
- assertEquals(comment, a.getImportance(), b.getImportance());
- assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
- assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
- assertEquals(comment, a.getChannel(), b.getChannel());
- assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
- assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
- assertEquals(comment, a.canShowBadge(), b.canShowBadge());
- assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
- assertEquals(comment, a.isSuspended(), b.isSuspended());
- assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis());
- assertEquals(comment, a.isNoisy(), b.isNoisy());
- assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
- assertEquals(comment, a.canBubble(), b.canBubble());
- assertEquals(comment, a.isConversation(), b.isConversation());
- assertEquals(comment, a.getConversationShortcutInfo().getId(),
- b.getConversationShortcutInfo().getId());
- assertActionsEqual(a.getSmartActions(), b.getSmartActions());
- assertEquals(a.getProposedImportance(), b.getProposedImportance());
- assertEquals(a.hasSensitiveContent(), b.hasSensitiveContent());
- }
-
- private void detailedAssertEquals(RankingMap a, RankingMap b) {
- Ranking arank = new Ranking();
- Ranking brank = new Ranking();
- assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
- for (String key : a.getOrderedKeys()) {
- a.getRanking(key, arank);
- b.getRanking(key, brank);
- detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
- }
- }
-
public static class TestListenerService extends NotificationListenerService {
private final IBinder binder = new LocalBinder();
public int targetSdk = 0;
diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp
index e704ebf32270..744cb63f72b3 100644
--- a/services/tests/voiceinteractiontests/Android.bp
+++ b/services/tests/voiceinteractiontests/Android.bp
@@ -43,7 +43,7 @@ android_test {
"services.soundtrigger",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
- "truth-prebuilt",
+ "truth",
],
libs: [
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index c2812a14a3eb..af39b2f027ee 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -57,12 +57,14 @@ android_test {
"platform-test-annotations",
"servicestests-utils",
"testng",
- "truth-prebuilt",
+ "truth",
"testables",
"hamcrest-library",
"platform-compat-test-rules",
"CtsSurfaceValidatorLib",
"service-sdksandbox.impl",
+ "com.android.window.flags.window-aconfig-java",
+ "flag-junit",
],
libs: [
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 42e3383987d6..762e23c8e288 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -47,6 +47,8 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION"/>
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
+ <uses-permission android:name="android.permission.MONITOR_INPUT"/>
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
<application android:debuggable="true"
@@ -104,6 +106,11 @@
android:showWhenLocked="true"
android:turnScreenOn="true" />
+ <activity android:name="android.app.Activity"
+ android:exported="true"
+ android:showWhenLocked="true"
+ android:turnScreenOn="true" />
+
<activity
android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity"
android:exported="true">
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index 0a7bb00ce1c2..71098aa5e883 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -20,6 +20,7 @@ import static com.android.server.policy.PhoneWindowManager.DOUBLE_TAP_HOME_RECEN
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ALL_APPS;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ASSIST;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_NOTIFICATION_PANEL;
+import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL;
import android.platform.test.annotations.Presubmit;
import android.view.KeyEvent;
@@ -284,6 +285,16 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
KeyboardLogEvent.APP_SWITCH, KeyEvent.KEYCODE_H, META_ON}};
}
+ @Keep
+ private static Object[][] shortPressOnSettingsTestArguments() {
+ // testName, testKeys, shortPressOnSettingsBehavior, expectedLogEvent, expectedKey,
+ // expectedModifierState
+ return new Object[][]{
+ {"SETTINGS key -> Toggle Notification panel", new int[]{KeyEvent.KEYCODE_SETTINGS},
+ SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL,
+ KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL, KeyEvent.KEYCODE_SETTINGS, 0}};
+ }
+
@Before
public void setUp() {
setUpPhoneWindowManager(/*supportSettingsUpdate*/ true);
@@ -294,6 +305,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
mPhoneWindowManager.overrideEnableBugReportTrigger(true);
mPhoneWindowManager.overrideStatusBarManagerInternal();
mPhoneWindowManager.overrideStartActivity();
+ mPhoneWindowManager.overrideSendBroadcast();
mPhoneWindowManager.overrideUserSetupComplete();
mPhoneWindowManager.setupAssistForLaunch();
mPhoneWindowManager.overrideTogglePanel();
@@ -330,4 +342,15 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
expectedKey, expectedModifierState, "Failed while executing " + testName);
}
+
+ @Test
+ @Parameters(method = "shortPressOnSettingsTestArguments")
+ public void testShortPressOnSettings(String testName, int[] testKeys,
+ int shortPressOnSettingsBehavior, KeyboardLogEvent expectedLogEvent, int expectedKey,
+ int expectedModifierState) {
+ mPhoneWindowManager.overrideShortPressOnSettingsBehavior(shortPressOnSettingsBehavior);
+ sendKeyCombination(testKeys, 0 /* duration */);
+ mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
+ expectedKey, expectedModifierState, "Failed while executing " + testName);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index ef28ffa7da8f..2244dbe8af98 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -375,6 +375,10 @@ class TestPhoneWindowManager {
mPhoneWindowManager.mDoubleTapOnHomeBehavior = behavior;
}
+ void overrideShortPressOnSettingsBehavior(int behavior) {
+ mPhoneWindowManager.mShortPressOnSettingsBehavior = behavior;
+ }
+
void overrideCanStartDreaming(boolean canDream) {
doReturn(canDream).when(mDreamManagerInternal).canStartDreaming(anyBoolean());
}
@@ -484,6 +488,10 @@ class TestPhoneWindowManager {
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
}
+ void overrideSendBroadcast() {
+ doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
+ }
+
void overrideUserSetupComplete() {
doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java b/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java
new file mode 100644
index 000000000000..ac498397eb39
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+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.server.wm.BuildUtils;
+import android.server.wm.CtsWindowInfoUtils;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.window.flags.Flags;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@Presubmit
+public class TrustedOverlayTests {
+ private static final String TAG = "TrustedOverlayTests";
+ private static final long TIMEOUT_S = 5L * BuildUtils.HW_TIMEOUT_MULTIPLIER;
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
+ @Rule
+ public TestName mName = new TestName();
+
+ @Rule
+ public final ActivityScenarioRule<Activity> mActivityRule = new ActivityScenarioRule<>(
+ Activity.class);
+
+ private Instrumentation mInstrumentation;
+ private Activity mActivity;
+
+ @Before
+ public void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mActivityRule.getScenario().onActivity(activity -> {
+ mActivity = activity;
+ });
+ }
+
+ @RequiresFlagsDisabled(Flags.FLAG_SURFACE_TRUSTED_OVERLAY)
+ @Test
+ public void setTrustedOverlayInputWindow() throws InterruptedException {
+ testTrustedOverlayChildHelper(false);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SURFACE_TRUSTED_OVERLAY)
+ public void setTrustedOverlayChildLayer() throws InterruptedException {
+ testTrustedOverlayChildHelper(true);
+ }
+
+ /**
+ * b/300659960 where setting spy window and trusted overlay were not happening in the same
+ * transaction causing the system to crash. This ensures there are no synchronization issues
+ * setting both spy window and trusted overlay.
+ */
+ @Test
+ public void setSpyWindowDoesntCrash() throws InterruptedException {
+ IBinder[] tokens = new IBinder[1];
+ CountDownLatch hostTokenReady = new CountDownLatch(1);
+ mInstrumentation.runOnMainSync(() -> {
+ WindowManager.LayoutParams params = mActivity.getWindow().getAttributes();
+ params.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+ params.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
+ mActivity.getWindow().setAttributes(params);
+
+ View rootView = mActivity.getWindow().getDecorView();
+ if (rootView.isAttachedToWindow()) {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ } else {
+ rootView.getViewTreeObserver().addOnWindowAttachListener(
+ new ViewTreeObserver.OnWindowAttachListener() {
+ @Override
+ public void onWindowAttached() {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ }
+
+ @Override
+ public void onWindowDetached() {
+ }
+ });
+ }
+ });
+
+ assertTrue("Failed to wait for host to get added",
+ hostTokenReady.await(TIMEOUT_S, TimeUnit.SECONDS));
+
+ boolean[] foundTrusted = new boolean[1];
+ CtsWindowInfoUtils.waitForWindowInfos(
+ windowInfos -> {
+ for (var windowInfo : windowInfos) {
+ if (windowInfo.windowToken == tokens[0] && windowInfo.isTrustedOverlay) {
+ foundTrusted[0] = true;
+ return true;
+ }
+ }
+ return false;
+ }, TIMEOUT_S, TimeUnit.SECONDS);
+
+ if (!foundTrusted[0]) {
+ CtsWindowInfoUtils.dumpWindowsOnScreen(TAG, mName.getMethodName());
+ }
+
+ assertTrue("Failed to find window or was not marked trusted", foundTrusted[0]);
+ }
+
+ private void testTrustedOverlayChildHelper(boolean expectedTrustedChild)
+ throws InterruptedException {
+ IBinder[] tokens = new IBinder[2];
+ CountDownLatch hostTokenReady = new CountDownLatch(1);
+ mInstrumentation.runOnMainSync(() -> {
+ mActivity.getWindow().addPrivateFlags(PRIVATE_FLAG_TRUSTED_OVERLAY);
+ View rootView = mActivity.getWindow().getDecorView();
+ if (rootView.isAttachedToWindow()) {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ } else {
+ rootView.getViewTreeObserver().addOnWindowAttachListener(
+ new ViewTreeObserver.OnWindowAttachListener() {
+ @Override
+ public void onWindowAttached() {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ }
+
+ @Override
+ public void onWindowDetached() {
+ }
+ });
+ }
+ });
+
+ assertTrue("Failed to wait for host to get added",
+ hostTokenReady.await(TIMEOUT_S, TimeUnit.SECONDS));
+
+ mInstrumentation.runOnMainSync(() -> {
+ WindowManager wm = mActivity.getSystemService(WindowManager.class);
+
+ View childView = new View(mActivity) {
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ tokens[1] = getWindowToken();
+ }
+ };
+ WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+ params.token = tokens[0];
+ params.type = TYPE_APPLICATION_PANEL;
+ wm.addView(childView, params);
+ });
+
+ boolean[] foundTrusted = new boolean[2];
+
+ CtsWindowInfoUtils.waitForWindowInfos(
+ windowInfos -> {
+ for (var windowInfo : windowInfos) {
+ if (windowInfo.windowToken == tokens[0]
+ && windowInfo.isTrustedOverlay) {
+ foundTrusted[0] = true;
+ } else if (windowInfo.windowToken == tokens[1]
+ && windowInfo.isTrustedOverlay) {
+ foundTrusted[1] = true;
+ }
+ }
+ return foundTrusted[0] && foundTrusted[1];
+ }, TIMEOUT_S, TimeUnit.SECONDS);
+
+ if (!foundTrusted[0] || !foundTrusted[1]) {
+ CtsWindowInfoUtils.dumpWindowsOnScreen(TAG, mName.getMethodName());
+ }
+
+ assertTrue("Failed to find parent window or was not marked trusted", foundTrusted[0]);
+ assertEquals("Failed to find child window or was not marked trusted", expectedTrustedChild,
+ foundTrusted[1]);
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 6cebe0af7a35..f3bf026ddc6e 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -106,6 +106,7 @@ import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
@@ -201,7 +202,8 @@ public class UsageStatsService extends SystemService implements
static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9;
private final Object mLock = new Object();
- Handler mHandler;
+ private Handler mHandler;
+ private Handler mIoHandler;
AppOpsManager mAppOps;
UserManager mUserManager;
PackageManager mPackageManager;
@@ -233,7 +235,7 @@ public class UsageStatsService extends SystemService implements
private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>();
final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray();
final SparseArray<ActivityData> mVisibleActivities = new SparseArray();
- @GuardedBy("mLock")
+ @GuardedBy("mLaunchTimeAlarmQueues") // Don't hold the main lock
private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>();
@GuardedBy("mUsageEventListeners") // Don't hold the main lock when calling out
private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners =
@@ -279,6 +281,38 @@ public class UsageStatsService extends SystemService implements
}
}
+ private final Handler.Callback mIoHandlerCallback = (msg) -> {
+ switch (msg.what) {
+ case MSG_UID_STATE_CHANGED: {
+ final int uid = msg.arg1;
+ final int procState = msg.arg2;
+
+ final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
+ synchronized (mUidToKernelCounter) {
+ final int oldCounter = mUidToKernelCounter.get(uid, 0);
+ if (newCounter != oldCounter) {
+ mUidToKernelCounter.put(uid, newCounter);
+ try {
+ FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to update counter set: " + e);
+ }
+ }
+ }
+ return true;
+ }
+ case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: {
+ final int userId = msg.arg1;
+ Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
+ "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")");
+ handleEstimatedLaunchTimesOnUserUnlock(userId);
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ return true;
+ }
+ }
+ return false;
+ };
+
private final Injector mInjector;
public UsageStatsService(Context context) {
@@ -299,6 +333,7 @@ public class UsageStatsService extends SystemService implements
mPackageManager = getContext().getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mHandler = new H(BackgroundThread.get().getLooper());
+ mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback);
mAppStandby = mInjector.getAppStandbyController(getContext());
mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext());
@@ -424,6 +459,9 @@ public class UsageStatsService extends SystemService implements
}
mUserUnlockedStates.remove(userId);
mUserState.put(userId, null); // release the service (mainly for GC)
+ }
+
+ synchronized (mLaunchTimeAlarmQueues) {
LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
if (alarmQueue != null) {
alarmQueue.removeAllAlarms();
@@ -479,10 +517,12 @@ public class UsageStatsService extends SystemService implements
}
reportEvent(unlockEvent, userId);
- mHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget();
+ mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK,
+ userId, 0).sendToTarget();
// Remove all the stats stored in system DE.
deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats"));
+
// Force a flush to disk for the current user to ensure important events are persisted.
// Note: there is a very very small chance that the system crashes between deleting
// the stats above from DE and persisting them to CE here in which case we will lose
@@ -601,7 +641,7 @@ public class UsageStatsService extends SystemService implements
private final IUidObserver mUidObserver = new UidObserver() {
@Override
public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
- mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
+ mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
}
@Override
@@ -673,16 +713,18 @@ public class UsageStatsService extends SystemService implements
callingPid, callingUid) == PackageManager.PERMISSION_GRANTED);
}
- private static void deleteRecursively(File f) {
- File[] files = f.listFiles();
- if (files != null) {
- for (File subFile : files) {
- deleteRecursively(subFile);
+ private static void deleteRecursively(final File path) {
+ if (path.isDirectory()) {
+ final File[] files = path.listFiles();
+ if (files != null) {
+ for (File subFile : files) {
+ deleteRecursively(subFile);
+ }
}
}
- if (f.exists() && !f.delete()) {
- Slog.e(TAG, "Failed to delete " + f);
+ if (path.exists() && !path.delete()) {
+ Slog.e(TAG, "Failed to delete " + path);
}
}
@@ -1244,6 +1286,9 @@ public class UsageStatsService extends SystemService implements
Slog.i(TAG, "Removing user " + userId + " and all data.");
mUserState.remove(userId);
mAppTimeLimit.onUserRemoved(userId);
+ }
+
+ synchronized (mLaunchTimeAlarmQueues) {
final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
if (alarmQueue != null) {
alarmQueue.removeAllAlarms();
@@ -1274,6 +1319,13 @@ public class UsageStatsService extends SystemService implements
}
}
+ synchronized (mLaunchTimeAlarmQueues) {
+ final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
+ if (alarmQueue != null) {
+ alarmQueue.removeAlarmForKey(packageName);
+ }
+ }
+
final int tokenRemoved;
synchronized (mLock) {
final long timeRemoved = System.currentTimeMillis();
@@ -1282,10 +1334,7 @@ public class UsageStatsService extends SystemService implements
// when the user service is initialized and package manager is queried.
return;
}
- final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
- if (alarmQueue != null) {
- alarmQueue.removeAlarmForKey(packageName);
- }
+
final UserUsageStatsService userService = mUserState.get(userId);
if (userService == null) {
return;
@@ -1495,60 +1544,63 @@ public class UsageStatsService extends SystemService implements
estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName);
mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime);
- synchronized (mLock) {
- LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
- if (alarmQueue == null) {
- alarmQueue = new LaunchTimeAlarmQueue(
- userId, getContext(), BackgroundThread.get().getLooper());
- mLaunchTimeAlarmQueues.put(userId, alarmQueue);
- }
- alarmQueue.addAlarm(packageName,
- SystemClock.elapsedRealtime() + (estimatedLaunchTime - now));
- }
+ getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName,
+ SystemClock.elapsedRealtime() + (estimatedLaunchTime - now));
}
return estimatedLaunchTime;
}
+ private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) {
+ synchronized (mLaunchTimeAlarmQueues) {
+ LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
+ if (alarmQueue == null) {
+ alarmQueue = new LaunchTimeAlarmQueue(
+ userId, getContext(), BackgroundThread.get().getLooper());
+ mLaunchTimeAlarmQueues.put(userId, alarmQueue);
+ }
+
+ return alarmQueue;
+ }
+ }
+
@CurrentTimeMillisLong
private long calculateEstimatedPackageLaunchTime(int userId, String packageName) {
- synchronized (mLock) {
- final long endTime = System.currentTimeMillis();
- final long beginTime = endTime - ONE_WEEK;
- final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS;
- final UsageEvents events = queryEarliestEventsForPackage(
- userId, beginTime, endTime, packageName, Event.ACTIVITY_RESUMED);
- if (events == null) {
- if (DEBUG) {
- Slog.d(TAG, "No events for " + userId + ":" + packageName);
- }
- return unknownTime;
+ final long endTime = System.currentTimeMillis();
+ final long beginTime = endTime - ONE_WEEK;
+ final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS;
+ final UsageEvents events = queryEarliestEventsForPackage(
+ userId, beginTime, endTime, packageName, Event.ACTIVITY_RESUMED);
+ if (events == null) {
+ if (DEBUG) {
+ Slog.d(TAG, "No events for " + userId + ":" + packageName);
+ }
+ return unknownTime;
+ }
+ final UsageEvents.Event event = new UsageEvents.Event();
+ final boolean hasMoreThan24HoursOfHistory;
+ if (events.getNextEvent(event)) {
+ hasMoreThan24HoursOfHistory = endTime - event.getTimeStamp() > ONE_DAY;
+ if (DEBUG) {
+ Slog.d(TAG, userId + ":" + packageName + " history > 24 hours="
+ + hasMoreThan24HoursOfHistory);
+ }
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, userId + ":" + packageName + " has no events");
}
- final UsageEvents.Event event = new UsageEvents.Event();
- final boolean hasMoreThan24HoursOfHistory;
- if (events.getNextEvent(event)) {
- hasMoreThan24HoursOfHistory = endTime - event.getTimeStamp() > ONE_DAY;
- if (DEBUG) {
- Slog.d(TAG, userId + ":" + packageName + " history > 24 hours="
- + hasMoreThan24HoursOfHistory);
- }
- } else {
- if (DEBUG) {
- Slog.d(TAG, userId + ":" + packageName + " has no events");
- }
- return unknownTime;
- }
- do {
- if (event.getEventType() == Event.ACTIVITY_RESUMED) {
- final long timestamp = event.getTimeStamp();
- final long nextLaunch =
- calculateNextLaunchTime(hasMoreThan24HoursOfHistory, timestamp);
- if (nextLaunch > endTime) {
- return nextLaunch;
- }
- }
- } while (events.getNextEvent(event));
return unknownTime;
}
+ do {
+ if (event.getEventType() == Event.ACTIVITY_RESUMED) {
+ final long timestamp = event.getTimeStamp();
+ final long nextLaunch =
+ calculateNextLaunchTime(hasMoreThan24HoursOfHistory, timestamp);
+ if (nextLaunch > endTime) {
+ return nextLaunch;
+ }
+ }
+ } while (events.getNextEvent(event));
+ return unknownTime;
}
@CurrentTimeMillisLong
@@ -1569,61 +1621,54 @@ public class UsageStatsService extends SystemService implements
}
private void handleEstimatedLaunchTimesOnUserUnlock(int userId) {
- synchronized (mLock) {
- final long nowElapsed = SystemClock.elapsedRealtime();
- final long now = System.currentTimeMillis();
- final long beginTime = now - ONE_WEEK;
- final UsageEvents events = queryEarliestAppEvents(
- userId, beginTime, now, Event.ACTIVITY_RESUMED);
- if (events == null) {
- return;
- }
- final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>();
- final UsageEvents.Event event = new UsageEvents.Event();
- LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId);
- if (alarmQueue == null) {
- alarmQueue = new LaunchTimeAlarmQueue(
- userId, getContext(), BackgroundThread.get().getLooper());
- mLaunchTimeAlarmQueues.put(userId, alarmQueue);
- }
- boolean changedTimes = false;
- for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent;
- unprocessedEvent = events.getNextEvent(event)) {
- final String packageName = event.getPackageName();
- if (!hasMoreThan24HoursOfHistory.containsKey(packageName)) {
- boolean hasHistory = now - event.getTimeStamp() > ONE_DAY;
- if (DEBUG) {
- Slog.d(TAG,
- userId + ":" + packageName + " history > 24 hours=" + hasHistory);
- }
- hasMoreThan24HoursOfHistory.put(packageName, hasHistory);
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ final long now = System.currentTimeMillis();
+ final long beginTime = now - ONE_WEEK;
+ final UsageEvents events = queryEarliestAppEvents(
+ userId, beginTime, now, Event.ACTIVITY_RESUMED);
+ if (events == null) {
+ return;
+ }
+ final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>();
+ final UsageEvents.Event event = new UsageEvents.Event();
+ boolean changedTimes = false;
+ final LaunchTimeAlarmQueue alarmQueue = getOrCreateLaunchTimeAlarmQueue(userId);
+ for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent;
+ unprocessedEvent = events.getNextEvent(event)) {
+ final String packageName = event.getPackageName();
+ if (!hasMoreThan24HoursOfHistory.containsKey(packageName)) {
+ boolean hasHistory = now - event.getTimeStamp() > ONE_DAY;
+ if (DEBUG) {
+ Slog.d(TAG,
+ userId + ":" + packageName + " history > 24 hours=" + hasHistory);
}
- if (event.getEventType() == Event.ACTIVITY_RESUMED) {
- long estimatedLaunchTime =
- mAppStandby.getEstimatedLaunchTime(packageName, userId);
- if (estimatedLaunchTime < now || estimatedLaunchTime == Long.MAX_VALUE) {
- //noinspection ConstantConditions
- estimatedLaunchTime = calculateNextLaunchTime(
- hasMoreThan24HoursOfHistory.get(packageName), event.getTimeStamp());
- mAppStandby.setEstimatedLaunchTime(
- packageName, userId, estimatedLaunchTime);
- }
- if (estimatedLaunchTime < now + ONE_WEEK) {
- // Before a user is unlocked, we don't know when the app will be launched,
- // so we give callers the UNKNOWN time. Now that we have a better estimate,
- // we should notify them of the change.
- if (DEBUG) {
- Slog.d(TAG, "User " + userId + " unlock resulting in"
- + " estimated launch time change for " + packageName);
- }
- changedTimes |= stageChangedEstimatedLaunchTime(userId, packageName);
+ hasMoreThan24HoursOfHistory.put(packageName, hasHistory);
+ }
+ if (event.getEventType() == Event.ACTIVITY_RESUMED) {
+ long estimatedLaunchTime =
+ mAppStandby.getEstimatedLaunchTime(packageName, userId);
+ if (estimatedLaunchTime < now || estimatedLaunchTime == Long.MAX_VALUE) {
+ //noinspection ConstantConditions
+ estimatedLaunchTime = calculateNextLaunchTime(
+ hasMoreThan24HoursOfHistory.get(packageName), event.getTimeStamp());
+ mAppStandby.setEstimatedLaunchTime(
+ packageName, userId, estimatedLaunchTime);
+ }
+ if (estimatedLaunchTime < now + ONE_WEEK) {
+ // Before a user is unlocked, we don't know when the app will be launched,
+ // so we give callers the UNKNOWN time. Now that we have a better estimate,
+ // we should notify them of the change.
+ if (DEBUG) {
+ Slog.d(TAG, "User " + userId + " unlock resulting in"
+ + " estimated launch time change for " + packageName);
}
- alarmQueue.addAlarm(packageName, nowElapsed + (estimatedLaunchTime - now));
+ changedTimes |= stageChangedEstimatedLaunchTime(userId, packageName);
}
+ alarmQueue.addAlarm(packageName, nowElapsed + (estimatedLaunchTime - now));
}
- if (changedTimes) {
- mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
- }
+ }
+ if (changedTimes) {
+ mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
}
}
@@ -1995,37 +2040,11 @@ public class UsageStatsService extends SystemService implements
case MSG_PACKAGE_REMOVED:
onPackageRemoved(msg.arg1, (String) msg.obj);
break;
- case MSG_UID_STATE_CHANGED: {
- final int uid = msg.arg1;
- final int procState = msg.arg2;
-
- final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
- synchronized (mUidToKernelCounter) {
- final int oldCounter = mUidToKernelCounter.get(uid, 0);
- if (newCounter != oldCounter) {
- mUidToKernelCounter.put(uid, newCounter);
- try {
- FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
- } catch (IOException e) {
- Slog.w(TAG, "Failed to update counter set: " + e);
- }
- }
- }
- break;
- }
case MSG_ON_START:
synchronized (mLock) {
loadGlobalComponentUsageLocked();
}
break;
- case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: {
- final int userId = msg.arg1;
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
- "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")");
- handleEstimatedLaunchTimesOnUserUnlock(userId);
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
- }
- break;
case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: {
removeMessages(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 7d9b3790c1b5..a7675d694a24 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1894,7 +1894,7 @@ public final class Call {
* Tones are both played locally for the user to hear and sent to the network to be relayed
* to the remote device.
* <p>
- * You must ensure that any call to {@link #playDtmfTone(char}) is followed by a matching
+ * You must ensure that any call to {@link #playDtmfTone(char)} is followed by a matching
* call to {@link #stopDtmfTone()} and that each tone is stopped before a new one is started.
* The play and stop commands are relayed to the underlying
* {@link android.telecom.ConnectionService} as executed; implementations may not correctly
diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java
index 50f2ad4561cc..24d39182add6 100644
--- a/telecomm/java/android/telecom/CallControl.java
+++ b/telecomm/java/android/telecom/CallControl.java
@@ -225,7 +225,7 @@ public final class CallControl {
/**
* Request start a call streaming session. On receiving valid request, telecom will bind to
- * the {@link CallStreamingService} implemented by a general call streaming sender. So that the
+ * the {@code CallStreamingService} implemented by a general call streaming sender. So that the
* call streaming sender can perform streaming local device audio to another remote device and
* control the call during streaming.
*
diff --git a/telecomm/java/android/telecom/CallControlCallback.java b/telecomm/java/android/telecom/CallControlCallback.java
index eac2e64aa2ab..0166022abeb8 100644
--- a/telecomm/java/android/telecom/CallControlCallback.java
+++ b/telecomm/java/android/telecom/CallControlCallback.java
@@ -69,7 +69,7 @@ public interface CallControlCallback {
/**
* Telecom is informing the client to answer an incoming call and set it to active.
*
- * @param videoState see {@link android.telecom.CallAttributes.CallType} for valid states
+ * @param videoState the video state
* @param wasCompleted The {@link Consumer} to be completed. If the client can answer the call
* on their end, {@link Consumer#accept(Object)} should be called with
* {@link Boolean#TRUE}.
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.java b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
index d9f89d544f40..c83804fde8fe 100644
--- a/telecomm/java/android/telecom/PhoneAccountSuggestion.java
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
@@ -68,7 +68,7 @@ public final class PhoneAccountSuggestion implements Parcelable {
/**
* Creates a new instance of {@link PhoneAccountSuggestion}. This constructor is intended for
- * use by apps implementing a {@link PhoneAccountSuggestionService}, and generally should not be
+ * use by apps implementing a {@code PhoneAccountSuggestionService}, and generally should not be
* used by dialer apps other than for testing purposes.
*
* @param handle The {@link PhoneAccountHandle} for this suggestion.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 98bbb40282c9..63e91ad414de 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5073,7 +5073,6 @@ public class CarrierConfigManager {
* MMTEL and RCS.
* <p>
* The default value for this configuration is {@code false}.
- * @see android.telephony.ims.SipDelegateManager
*/
public static final String KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL =
KEY_PREFIX + "ims_single_registration_required_bool";
@@ -5648,8 +5647,8 @@ public class CarrierConfigManager {
* <li>{@link #KEY_CAPABILITY_TYPE_SMS_INT_ARRAY}</li>
* <li>{@link #KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY}</li>
* </ul>
- * <p> The values are defined in
- * {@link ImsRegistrationImplBase.ImsRegistrationTech}
+ * <p> The values are defined as {@code REGISTRATION_TECH_*} constants in
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase}.
*
* changing mmtel_requires_provisioning_bundle requires changes to
* carrier_volte_provisioning_required_bool and vice versa
@@ -5661,12 +5660,12 @@ public class CarrierConfigManager {
/**
* List of different RAT technologies on which Provisioning for Voice calling (IR.92)
* is supported.
- * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
+ * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE
*/
public static final String KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY =
KEY_PREFIX + "capability_type_voice_int_array";
@@ -5674,12 +5673,12 @@ public class CarrierConfigManager {
/**
* List of different RAT technologies on which Provisioning for Video Telephony (IR.94)
* is supported.
- * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
+ * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO
*/
public static final String KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY =
KEY_PREFIX + "capability_type_video_int_array";
@@ -5687,24 +5686,24 @@ public class CarrierConfigManager {
/**
* List of different RAT technologies on which Provisioning for XCAP over Ut for
* supplementary services. (IR.92) is supported.
- * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
+ * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT
*/
public static final String KEY_CAPABILITY_TYPE_UT_INT_ARRAY =
KEY_PREFIX + "capability_type_ut_int_array";
/**
* List of different RAT technologies on which Provisioning for SMS (IR.92) is supported.
- * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
+ * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS
*/
public static final String KEY_CAPABILITY_TYPE_SMS_INT_ARRAY =
KEY_PREFIX + "capability_type_sms_int_array";
@@ -5712,12 +5711,12 @@ public class CarrierConfigManager {
/**
* List of different RAT technologies on which Provisioning for Call Composer
* (section 2.4 of RCC.20) is supported.
- * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_CALL_COMPOSER
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
+ * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_CALL_COMPOSER
*/
public static final String KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY =
KEY_PREFIX + "capability_type_call_composer_int_array";
@@ -5732,8 +5731,8 @@ public class CarrierConfigManager {
* <li>{@link #KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY}</li>
* <li>{@link #KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY}</li>
* </ul>
- * <p> The values are defined in
- * {@link ImsRegistrationImplBase.ImsRegistrationTech}
+ * <p> The values are defined as {@code REGISTRATION_TECH_*} constants in
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase}.
*/
public static final String KEY_RCS_REQUIRES_PROVISIONING_BUNDLE =
KEY_PREFIX + "rcs_requires_provisioning_bundle";
@@ -5742,12 +5741,11 @@ public class CarrierConfigManager {
* This carrier supports User Capability Exchange using SIP OPTIONS as defined by the
* framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS.
* If not set, this RcsFeature should not service capability requests.
- * @see RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY =
KEY_PREFIX + "capability_type_options_uce_int_array";
@@ -5757,12 +5755,11 @@ public class CarrierConfigManager {
* framework. If set, the RcsFeature should support capability exchange using a presence
* server. If not set, this RcsFeature should not publish capabilities or service capability
* requests using presence.
- * @see RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE
* <p>Possible values are,
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM}
- * {@link ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_LTE}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_CROSS_SIM}
+ * {@link android.telephony.ims.stub.ImsRegistrationImplBase#REGISTRATION_TECH_NR}
*/
public static final String KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY =
KEY_PREFIX + "capability_type_presence_uce_int_array";
@@ -9640,7 +9637,7 @@ public class CarrierConfigManager {
/**
* A list of premium capabilities the carrier supports. Applications can prompt users to
* purchase these premium capabilities from their carrier for a performance boost.
- * Valid values are any of {@link TelephonyManager.PremiumCapability}.
+ * Valid values are any of {@link TelephonyManager}'s {@code PREMIUM_CAPABILITY_*} constants.
*
* This is empty by default, indicating that no premium capabilities are supported.
*
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 631013fc485e..cb4a6e7479cf 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -625,7 +625,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
}
/**
- * @return The access network technology {@link NetworkType}.
+ * @return The access network technology network type..
*/
public @NetworkType int getAccessNetworkTechnology() {
return mAccessNetworkTechnology;
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index fa5fd875a024..8e90fe7ea975 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1364,7 +1364,7 @@ public class SubscriptionManager {
public static class OnSubscriptionsChangedListener {
/**
- * After {@link Build.VERSION_CODES.Q}, it is no longer necessary to instantiate a
+ * After {@link Build.VERSION_CODES#Q}, it is no longer necessary to instantiate a
* Handler inside of the OnSubscriptionsChangedListener in all cases, so it will only
* be done for callers that do not supply an Executor.
*/
@@ -1388,13 +1388,14 @@ public class SubscriptionManager {
/**
* Create an OnSubscriptionsChangedListener.
*
- * For callers targeting {@link Build.VERSION_CODES.P} or earlier, this can only be called
+ * For callers targeting {@link Build.VERSION_CODES#P} or earlier, this can only be called
* on a thread that already has a prepared Looper. Callers targeting Q or later should
* subsequently use {@link SubscriptionManager#addOnSubscriptionsChangedListener(
* Executor, OnSubscriptionsChangedListener)}.
*
- * On OS versions prior to {@link Build.VERSION_CODES.V} callers should assume that this
- * call will fail if invoked on a thread that does not already have a prepared looper.
+ * On OS versions prior to {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} callers should
+ * assume that this call will fail if invoked on a thread that does not already have a
+ * prepared looper.
*/
public OnSubscriptionsChangedListener() {
mCreatorLooper = Looper.myLooper();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 234ca918a144..548fa97db599 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -13132,8 +13132,8 @@ public class TelephonyManager {
* </ul>
*
* @param executor The executor on which the result listener will be called.
- * @param resultListener {@link Consumer} that will be called with the result fetched
- * from the radio of type {@link CarrierRestrictionStatus}
+ * @param resultListener {@link Consumer} that will be called with the carrier restriction
+ * status result fetched from the radio
* @throws SecurityException if the caller does not have the required permission/privileges or
* if the caller is not pre-registered.
*/
@@ -13465,7 +13465,7 @@ public class TelephonyManager {
public static final int DATA_ENABLED_REASON_THERMAL = 3;
/**
- * To indicate data was enabled or disabled due to {@link MobileDataPolicy} overrides.
+ * To indicate data was enabled or disabled due to mobile data policy overrides.
* Note that this is not a valid reason for {@link #setDataEnabledForReason(int, boolean)} and
* is only used to indicate that data enabled was changed due to an override.
*/
@@ -14571,7 +14571,7 @@ public class TelephonyManager {
* @param needValidation whether validation is needed before switch happens.
* @param executor The executor of where the callback will execute.
* @param callback Callback will be triggered once it succeeds or failed.
- * See {@link TelephonyManager.SetOpportunisticSubscriptionResult}
+ * See the {@code SET_OPPORTUNISTIC_SUB_*} constants
* for more details. Pass null if don't care about the result.
*/
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
@@ -17516,7 +17516,7 @@ public class TelephonyManager {
public @interface PurchasePremiumCapabilityResult {}
/**
- * Returns the purchase result {@link PurchasePremiumCapabilityResult} as a String.
+ * Returns the purchase result as a String.
*
* @param result The purchase premium capability result.
* @return The purchase result as a String.
@@ -17570,7 +17570,6 @@ public class TelephonyManager {
* @param capability The premium capability to purchase.
* @param executor The callback executor for the response.
* @param callback The result of the purchase request.
- * One of {@link PurchasePremiumCapabilityResult}.
* @throws SecurityException if the caller does not hold permissions
* READ_BASIC_PHONE_STATE or INTERNET.
* @see #isPremiumCapabilityAvailableForPurchase(int) to check whether the capability is valid.
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 26c17a461cf2..e9af486219f7 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -532,7 +532,7 @@ public class ApnSetting implements Parcelable {
/**
* Returns the default MTU (Maximum Transmission Unit) size in bytes of the IPv4 routes brought
* up by this APN setting. Note this value will only be used when MTU size is not provided
- * in {@link DataCallResponse#getMtuV4()} during network bring up.
+ * in {@code DataCallResponse#getMtuV4()} during network bring up.
*
* @return the MTU size in bytes of the route.
*/
@@ -542,7 +542,7 @@ public class ApnSetting implements Parcelable {
/**
* Returns the MTU size of the IPv6 mobile interface to which the APN connected. Note this value
- * will only be used when MTU size is not provided in {@link DataCallResponse#getMtuV6()}
+ * will only be used when MTU size is not provided in {@code DataCallResponse#getMtuV6()}
* during network bring up.
*
* @return the MTU size in bytes of the route.
@@ -1787,7 +1787,7 @@ public class ApnSetting implements Parcelable {
/**
* Set the default MTU (Maximum Transmission Unit) size in bytes of the IPv4 routes brought
* up by this APN setting. Note this value will only be used when MTU size is not provided
- * in {@link DataCallResponse#getMtuV4()} during network bring up.
+ * in {@code DataCallResponse#getMtuV4()} during network bring up.
*
* @param mtuV4 the MTU size in bytes of the route.
*/
@@ -1799,7 +1799,7 @@ public class ApnSetting implements Parcelable {
/**
* Set the default MTU (Maximum Transmission Unit) size in bytes of the IPv6 routes brought
* up by this APN setting. Note this value will only be used when MTU size is not provided
- * in {@link DataCallResponse#getMtuV6()} during network bring up.
+ * in {@code DataCallResponse#getMtuV6()} during network bring up.
*
* @param mtuV6 the MTU size in bytes of the route.
*/
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index ed4627631dd5..b9a7d439114a 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -249,7 +249,7 @@ public class EuiccManager {
*
* <p>{@link #EXTRA_USE_QR_SCANNER} not set or set to false: The LPA should try to get an
* activation code from the carrier app by binding to the carrier app service implementing
- * {@link android.service.euicc.EuiccService#ACTION_BIND_CARRIER_PROVISIONING_SERVICE}.
+ * {@code android.service.euicc.EuiccService#ACTION_BIND_CARRIER_PROVISIONING_SERVICE}.
* <p>{@link #EXTRA_USE_QR_SCANNER} set to true: The LPA should launch a QR scanner for the user
* to scan an eSIM profile QR code.
*
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index caee4e2ca277..2172d7de0dd7 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -561,7 +561,7 @@ public class ImsMmTelManager implements RegistrationManager {
* @param c The MmTel {@link CapabilityCallback} to be registered.
* @see #unregisterMmTelCapabilityCallback(CapabilityCallback)
* @throws ImsException if the subscription associated with this callback is valid, but
- * the {@link ImsService} associated with the subscription is not available. This can happen if
+ * the {@code ImsService} associated with the subscription is not available. This can happen if
* the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
* reason.
*/
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 4439e5c35d83..2b49bcd4e928 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -247,7 +247,7 @@ public class ImsRcsManager {
* @param c The {@link RegistrationManager.RegistrationCallback} to be added.
* @see #unregisterImsRegistrationCallback(RegistrationManager.RegistrationCallback)
* @throws ImsException if the subscription associated with this callback is valid, but
- * the {@link ImsService} associated with the subscription is not available. This can happen if
+ * the {@code ImsService} associated with the subscription is not available. This can happen if
* the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
* reason.
*/
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 37a6a7ebf953..1c5d1e940030 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -1469,9 +1469,8 @@ public class ProvisioningManager {
/**
* Get the provisioning status for the IMS MmTel capability specified.
*
- * If provisioning is not required for the queried
- * {@link MmTelFeature.MmTelCapabilities.MmTelCapability} and
- * {@link ImsRegistrationImplBase.ImsRegistrationTech} combination specified, this method will
+ * If provisioning is not required for the queried {@code capability} and
+ * {@code tech} combination specified, this method will
* always return {@code true}.
*
* <p> Requires Permission:
@@ -1503,7 +1502,7 @@ public class ProvisioningManager {
* Get the provisioning status for the IMS RCS capability specified.
*
* If provisioning is not required for the queried
- * {@link ImsRcsManager.RcsImsCapabilityFlag} or if the device does not support IMS
+ * {@code capability} or if the device does not support IMS
* this method will always return {@code true}.
*
* @see CarrierConfigManager.Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL
@@ -1533,7 +1532,7 @@ public class ProvisioningManager {
* Get the provisioning status for the IMS RCS capability specified.
*
* If provisioning is not required for the queried
- * {@link ImsRcsManager.RcsImsCapabilityFlag} or if the device does not support IMS
+ * {@code capability} or if the device does not support IMS
* this method will always return {@code true}.
*
* <p> Requires Permission:
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 873ce6064cca..b528866371cb 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -31,7 +31,6 @@ import android.os.Bundle;
import android.telephony.AccessNetworkConstants;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ims.aidl.IImsRegistrationCallback;
-import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.Log;
@@ -42,7 +41,7 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
- * Manages IMS Service registration state for associated {@link ImsFeature}s.
+ * Manages IMS Service registration state for associated {@code ImsFeature}s.
*/
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
public interface RegistrationManager {
@@ -394,7 +393,7 @@ public interface RegistrationManager {
* @param c The {@link RegistrationCallback} to be added.
* @see #unregisterImsRegistrationCallback(RegistrationCallback)
* @throws ImsException if the subscription associated with this callback is valid, but
- * the {@link ImsService} associated with the subscription is not available. This can happen if
+ * the {@code ImsService} associated with the subscription is not available. This can happen if
* the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
* reason.
*/
diff --git a/tests/BatteryStatsPerfTest/Android.bp b/tests/BatteryStatsPerfTest/Android.bp
index 5233a5b8654e..c2a70151fa13 100644
--- a/tests/BatteryStatsPerfTest/Android.bp
+++ b/tests/BatteryStatsPerfTest/Android.bp
@@ -27,7 +27,7 @@ android_test {
static_libs: [
"androidx.test.rules",
"apct-perftests-utils",
- "truth-prebuilt",
+ "truth",
],
platform_apis: true,
certificate: "platform",
diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp
index 615990f22e3c..38cb9869f165 100644
--- a/tests/BinaryTransparencyHostTest/Android.bp
+++ b/tests/BinaryTransparencyHostTest/Android.bp
@@ -30,7 +30,7 @@ java_test_host {
"compatibility-host-util",
],
static_libs: [
- "truth-prebuilt",
+ "truth",
],
data: [
":BinaryTransparencyTestApp",
diff --git a/tests/BlobStoreTestUtils/Android.bp b/tests/BlobStoreTestUtils/Android.bp
index c4faf7f4fb11..1fb73e2c0967 100644
--- a/tests/BlobStoreTestUtils/Android.bp
+++ b/tests/BlobStoreTestUtils/Android.bp
@@ -22,12 +22,12 @@ package {
}
java_library {
- name: "BlobStoreTestUtils",
- srcs: ["src/**/*.java"],
- static_libs: [
- "truth-prebuilt",
- "androidx.test.uiautomator_uiautomator",
- "androidx.test.ext.junit",
- ],
- sdk_version: "test_current",
+ name: "BlobStoreTestUtils",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "truth",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.ext.junit",
+ ],
+ sdk_version: "test_current",
}
diff --git a/tests/ChoreographerTests/Android.bp b/tests/ChoreographerTests/Android.bp
index ca3026705c63..5d49120ee702 100644
--- a/tests/ChoreographerTests/Android.bp
+++ b/tests/ChoreographerTests/Android.bp
@@ -34,7 +34,7 @@ android_test {
"androidx.test.rules",
"compatibility-device-util-axt",
"com.google.android.material_material",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
"libchoreographertests_jni",
diff --git a/tests/CtsSurfaceControlTestsStaging/Android.bp b/tests/CtsSurfaceControlTestsStaging/Android.bp
index 680952157fdc..96e4a9ea4300 100644
--- a/tests/CtsSurfaceControlTestsStaging/Android.bp
+++ b/tests/CtsSurfaceControlTestsStaging/Android.bp
@@ -37,7 +37,7 @@ android_test {
"compatibility-device-util-axt",
"com.google.android.material_material",
"SurfaceFlingerProperties",
- "truth-prebuilt",
+ "truth",
],
resource_dirs: ["src/main/res"],
certificate: "platform",
diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.bp b/tests/DynamicCodeLoggerIntegrationTests/Android.bp
index 448d46fe5e4e..3f2c80831565 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/Android.bp
+++ b/tests/DynamicCodeLoggerIntegrationTests/Android.bp
@@ -47,7 +47,7 @@ android_test {
static_libs: [
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
],
compile_multilib: "both",
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index a2ae56eaeadc..82aa85d55e4c 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -236,7 +236,7 @@ java_library {
static_libs: [
"flickerlib",
"flickerlib-helpers",
- "truth-prebuilt",
+ "truth",
"app-helpers-core",
],
}
@@ -255,7 +255,7 @@ java_library {
"flickerlib",
"flickerlib-apphelpers",
"flickerlib-helpers",
- "truth-prebuilt",
+ "truth",
"app-helpers-core",
"wm-flicker-window-extensions",
],
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index 365e00e2b652..cf2d5d69552f 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -9,6 +9,10 @@ package {
android_test {
name: "InputTests",
+ defaults: [
+ // For ExtendedMockito dependencies.
+ "modules-utils-testable-device-config-defaults",
+ ],
srcs: [
"src/**/*.java",
"src/**/*.kt",
@@ -35,7 +39,7 @@ android_test {
"services.core.unboosted",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index b64775103ab2..fa86e9c4ec0a 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -32,11 +32,16 @@ import android.os.Bundle
import android.os.test.TestLooper
import android.platform.test.annotations.Presubmit
import android.provider.Settings
+import android.util.proto.ProtoOutputStream
import android.view.InputDevice
import android.view.inputmethod.InputMethodInfo
import android.view.inputmethod.InputMethodSubtype
import androidx.test.core.R
import androidx.test.core.app.ApplicationProvider
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.internal.os.KeyboardConfiguredProto
+import com.android.internal.util.FrameworkStatsLog
+import com.android.modules.utils.testing.ExtendedMockitoRule
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
@@ -46,9 +51,9 @@ import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.mockito.ArgumentMatchers
import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.junit.MockitoJUnit
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
@@ -96,6 +101,9 @@ class KeyboardLayoutManagerTests {
private const val ENGLISH_US_LAYOUT_NAME = "keyboard_layout_english_us"
private const val ENGLISH_UK_LAYOUT_NAME = "keyboard_layout_english_uk"
private const val VENDOR_SPECIFIC_LAYOUT_NAME = "keyboard_layout_vendorId:1,productId:1"
+ const val LAYOUT_TYPE_QWERTZ = 2
+ const val LAYOUT_TYPE_QWERTY = 1
+ const val LAYOUT_TYPE_DEFAULT = 0
}
private val ENGLISH_US_LAYOUT_DESCRIPTOR = createLayoutDescriptor(ENGLISH_US_LAYOUT_NAME)
@@ -103,8 +111,10 @@ class KeyboardLayoutManagerTests {
private val VENDOR_SPECIFIC_LAYOUT_DESCRIPTOR =
createLayoutDescriptor(VENDOR_SPECIFIC_LAYOUT_NAME)
- @get:Rule
- val rule = MockitoJUnit.rule()!!
+ @JvmField
+ @Rule
+ val extendedMockitoRule = ExtendedMockitoRule.Builder(this)
+ .mockStatic(FrameworkStatsLog::class.java).build()!!
@Mock
private lateinit var iInputManager: IInputManager
@@ -145,7 +155,9 @@ class KeyboardLayoutManagerTests {
override fun finishWrite(fos: FileOutputStream?, success: Boolean) {}
})
testLooper = TestLooper()
- keyboardLayoutManager = KeyboardLayoutManager(context, native, dataStore, testLooper.looper)
+ keyboardLayoutManager = Mockito.spy(
+ KeyboardLayoutManager(context, native, dataStore, testLooper.looper)
+ )
setupInputDevices()
setupBroadcastReceiver()
setupIme()
@@ -827,6 +839,100 @@ class KeyboardLayoutManagerTests {
}
}
+ @Test
+ fun testConfigurationLogged_onInputDeviceAdded_VirtualKeyboardBasedSelection() {
+ val imeInfos = listOf(
+ KeyboardLayoutManager.ImeInfo(0, imeInfo,
+ createImeSubtypeForLanguageTagAndLayoutType("de-Latn", "qwertz")))
+ Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
+ NewSettingsApiFlag(true).use {
+ keyboardLayoutManager.onInputDeviceAdded(keyboardDevice.id)
+ ExtendedMockito.verify {
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.eq(keyboardDevice.vendorId),
+ ArgumentMatchers.eq(keyboardDevice.productId),
+ ArgumentMatchers.eq(createByteArray(
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT,
+ "German",
+ KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+ "de-Latn",
+ LAYOUT_TYPE_QWERTZ))
+ )
+ }
+ }
+ }
+
+ @Test
+ fun testConfigurationLogged_onInputDeviceAdded_DeviceBasedSelection() {
+ val imeInfos = listOf(
+ KeyboardLayoutManager.ImeInfo(0, imeInfo,
+ createImeSubtypeForLanguageTagAndLayoutType("de-Latn", "qwertz")))
+ Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
+ NewSettingsApiFlag(true).use {
+ keyboardLayoutManager.onInputDeviceAdded(englishQwertyKeyboardDevice.id)
+ ExtendedMockito.verify {
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.eq(englishQwertyKeyboardDevice.vendorId),
+ ArgumentMatchers.eq(englishQwertyKeyboardDevice.productId),
+ ArgumentMatchers.eq(createByteArray(
+ "en",
+ LAYOUT_TYPE_QWERTY,
+ "English (US)",
+ KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+ "de-Latn",
+ LAYOUT_TYPE_QWERTZ))
+ )
+ }
+ }
+ }
+
+ @Test
+ fun testConfigurationLogged_onInputDeviceAdded_DefaultSelection() {
+ val imeInfos = listOf(KeyboardLayoutManager.ImeInfo(0, imeInfo, createImeSubtype()))
+ Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
+ NewSettingsApiFlag(true).use {
+ keyboardLayoutManager.onInputDeviceAdded(keyboardDevice.id)
+ ExtendedMockito.verify {
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.eq(keyboardDevice.vendorId),
+ ArgumentMatchers.eq(keyboardDevice.productId),
+ ArgumentMatchers.eq(createByteArray(
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT,
+ "Default",
+ KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT,
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT))
+ )
+ }
+ }
+ }
+
+ @Test
+ fun testConfigurationNotLogged_onInputDeviceChanged() {
+ val imeInfos = listOf(KeyboardLayoutManager.ImeInfo(0, imeInfo, createImeSubtype()))
+ Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
+ NewSettingsApiFlag(true).use {
+ keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
+ ExtendedMockito.verify({
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.any(ByteArray::class.java)
+ )
+ }, Mockito.times(0))
+ }
+ }
+
private fun assertCorrectLayout(
device: InputDevice,
imeSubtype: InputMethodSubtype,
@@ -842,18 +948,60 @@ class KeyboardLayoutManagerTests {
}
private fun createImeSubtype(): InputMethodSubtype =
- InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(nextImeSubtypeId++).build()
+ createImeSubtypeForLanguageTagAndLayoutType(null, null)
private fun createImeSubtypeForLanguageTag(languageTag: String): InputMethodSubtype =
- InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(nextImeSubtypeId++)
- .setLanguageTag(languageTag).build()
+ createImeSubtypeForLanguageTagAndLayoutType(languageTag, null)
private fun createImeSubtypeForLanguageTagAndLayoutType(
- languageTag: String,
- layoutType: String
- ): InputMethodSubtype =
- InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(nextImeSubtypeId++)
- .setPhysicalKeyboardHint(ULocale.forLanguageTag(languageTag), layoutType).build()
+ languageTag: String?,
+ layoutType: String?
+ ): InputMethodSubtype {
+ val builder = InputMethodSubtype.InputMethodSubtypeBuilder()
+ .setSubtypeId(nextImeSubtypeId++)
+ .setIsAuxiliary(false)
+ .setSubtypeMode("keyboard")
+ if (languageTag != null && layoutType != null) {
+ builder.setPhysicalKeyboardHint(ULocale.forLanguageTag(languageTag), layoutType)
+ } else if (languageTag != null) {
+ builder.setLanguageTag(languageTag)
+ }
+ return builder.build()
+ }
+
+ private fun createByteArray(
+ expectedLanguageTag: String, expectedLayoutType: Int, expectedLayoutName: String,
+ expectedCriteria: Int, expectedImeLanguageTag: String, expectedImeLayoutType: Int): ByteArray {
+ val proto = ProtoOutputStream()
+ val keyboardLayoutConfigToken = proto.start(
+ KeyboardConfiguredProto.RepeatedKeyboardLayoutConfig.KEYBOARD_LAYOUT_CONFIG)
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.KEYBOARD_LANGUAGE_TAG,
+ expectedLanguageTag
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.KEYBOARD_LAYOUT_TYPE,
+ expectedLayoutType
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.KEYBOARD_LAYOUT_NAME,
+ expectedLayoutName
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.LAYOUT_SELECTION_CRITERIA,
+ expectedCriteria
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.IME_LANGUAGE_TAG,
+ expectedImeLanguageTag
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.IME_LAYOUT_TYPE,
+ expectedImeLayoutType
+ )
+ proto.end(keyboardLayoutConfigToken);
+ return proto.bytes
+ }
private fun hasLayout(layoutList: Array<KeyboardLayout>, layoutDesc: String): Boolean {
for (kl in layoutList) {
diff --git a/tests/InputMethodStressTest/Android.bp b/tests/InputMethodStressTest/Android.bp
index 84845c69fb27..58ceb3f3edf4 100644
--- a/tests/InputMethodStressTest/Android.bp
+++ b/tests/InputMethodStressTest/Android.bp
@@ -26,7 +26,7 @@ android_test {
"compatibility-device-util-axt",
"platform-test-annotations",
"platform-test-rules",
- "truth-prebuilt",
+ "truth",
],
test_suites: [
"general-tests",
diff --git a/tests/InputScreenshotTest/Android.bp b/tests/InputScreenshotTest/Android.bp
index eee486f99748..15aaa463cce7 100644
--- a/tests/InputScreenshotTest/Android.bp
+++ b/tests/InputScreenshotTest/Android.bp
@@ -29,7 +29,7 @@ android_test {
"androidx.lifecycle_lifecycle-livedata-ktx",
"androidx.lifecycle_lifecycle-runtime-compose",
"androidx.navigation_navigation-compose",
- "truth-prebuilt",
+ "truth",
"androidx.compose.runtime_runtime",
"androidx.test.core",
"androidx.test.ext.junit",
@@ -47,7 +47,7 @@ android_test {
"services.core.unboosted",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp
index ef45864dd93b..ddec8fa1d70a 100644
--- a/tests/Internal/Android.bp
+++ b/tests/Internal/Android.bp
@@ -19,7 +19,7 @@ android_test {
"junit",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
"platform-test-annotations",
],
java_resource_dirs: ["res"],
diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp
index 4e0b0a89d972..909ca5972552 100644
--- a/tests/LocalizationTest/Android.bp
+++ b/tests/LocalizationTest/Android.bp
@@ -34,7 +34,7 @@ android_test {
"androidx.test.ext.junit",
"androidx.test.rules",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
// For mockito extended
diff --git a/tests/MidiTests/Android.bp b/tests/MidiTests/Android.bp
index 254770d21818..fcacab3fb13c 100644
--- a/tests/MidiTests/Android.bp
+++ b/tests/MidiTests/Android.bp
@@ -31,7 +31,7 @@ android_test {
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
"services.midi",
- "truth-prebuilt",
+ "truth",
],
jni_libs: ["libdexmakerjvmtiagent"],
certificate: "platform",
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
index 1e1dc8458560..e0e6c4c43b16 100644
--- a/tests/PackageWatchdog/Android.bp
+++ b/tests/PackageWatchdog/Android.bp
@@ -32,7 +32,7 @@ android_test {
"androidx.test.rules",
"services.core",
"services.net",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
jni_libs: [
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index f0f9c4bdd721..fd992cf415cf 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -38,7 +38,7 @@ android_test {
"androidx.test.ext.junit",
"mockito-target-minus-junit4",
"testng",
- "truth-prebuilt",
+ "truth",
"platform-compat-test-rules",
],
}
diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp
index 5f91f9d0e505..f6a41c2f44b7 100644
--- a/tests/PlatformCompatGating/test-rules/Android.bp
+++ b/tests/PlatformCompatGating/test-rules/Android.bp
@@ -29,7 +29,7 @@ java_library {
static_libs: [
"junit",
"androidx.test.core",
- "truth-prebuilt",
- "core-compat-test-rules"
+ "truth",
+ "core-compat-test-rules",
],
}
diff --git a/tests/SurfaceViewBufferTests/Android.bp b/tests/SurfaceViewBufferTests/Android.bp
index 38313f85c31d..055d6258d1ac 100644
--- a/tests/SurfaceViewBufferTests/Android.bp
+++ b/tests/SurfaceViewBufferTests/Android.bp
@@ -45,7 +45,7 @@ android_test {
"kotlinx-coroutines-android",
"flickerlib",
"flickerlib-trace_processor_shell",
- "truth-prebuilt",
+ "truth",
"cts-wm-util",
"CtsSurfaceValidatorLib",
],
diff --git a/tests/TaskOrganizerTest/Android.bp b/tests/TaskOrganizerTest/Android.bp
index bf12f423f145..d2ade34148e2 100644
--- a/tests/TaskOrganizerTest/Android.bp
+++ b/tests/TaskOrganizerTest/Android.bp
@@ -43,6 +43,6 @@ android_test {
"kotlinx-coroutines-android",
"flickerlib",
"flickerlib-trace_processor_shell",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp
index 81ec265c2c29..b968e5d81148 100644
--- a/tests/TelephonyCommonTests/Android.bp
+++ b/tests/TelephonyCommonTests/Android.bp
@@ -32,11 +32,11 @@ android_test {
static_libs: [
"mockito-target-extended",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
"platform-test-annotations",
"androidx.core_core",
"androidx.fragment_fragment",
- "androidx.test.ext.junit"
+ "androidx.test.ext.junit",
],
jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
index c216bced81f0..4e75a1d02a41 100644
--- a/tests/TrustTests/Android.bp
+++ b/tests/TrustTests/Android.bp
@@ -28,7 +28,7 @@ android_test {
"flag-junit",
"mockito-target-minus-junit4",
"servicestests-utils",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.runner",
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index 9bfcc18ee301..ddb3649a8320 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -30,7 +30,7 @@ android_test {
"androidx.test.uiautomator_uiautomator",
"compatibility-device-util-axt",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
test_suites: [
"general-tests",
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index 97fbf5b32035..c02d8e96abb0 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -31,7 +31,7 @@ android_test {
"androidx.test.rules",
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
"UsbManagerTestLib",
],
jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/UsbManagerTests/lib/Android.bp b/tests/UsbManagerTests/lib/Android.bp
index 994484cd63bf..4e5a70fef0ca 100644
--- a/tests/UsbManagerTests/lib/Android.bp
+++ b/tests/UsbManagerTests/lib/Android.bp
@@ -34,7 +34,7 @@ android_library {
"services.core",
"services.net",
"services.usb",
- "truth-prebuilt",
+ "truth",
"androidx.core_core",
],
libs: [
diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp
index c60c519ec4d4..92c271165ad7 100644
--- a/tests/UsbTests/Android.bp
+++ b/tests/UsbTests/Android.bp
@@ -34,7 +34,7 @@ android_test {
"services.core",
"services.net",
"services.usb",
- "truth-prebuilt",
+ "truth",
"UsbManagerTestLib",
],
jni_libs: [
diff --git a/tests/componentalias/Android.bp b/tests/componentalias/Android.bp
index 01d34e4ff645..39037f22fdcb 100644
--- a/tests/componentalias/Android.bp
+++ b/tests/componentalias/Android.bp
@@ -25,7 +25,7 @@ java_defaults {
"androidx.test.rules",
"compatibility-device-util-axt",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.base"],
srcs: [
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 7323b0f4c14f..977b2768e702 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -220,6 +220,7 @@ genrule {
name: "aapt2-protos",
tools: [":soong_zip"],
srcs: [
+ "ApkInfo.proto",
"Configuration.proto",
"ResourcesInternal.proto",
"ResourceMetadata.proto",
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index 87da09a7b054..8c644cf83339 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -49,16 +49,19 @@ struct AnnotationRule {
kDeprecated = 0x01,
kSystemApi = 0x02,
kTestApi = 0x04,
+ kFlaggedApi = 0x08,
};
StringPiece doc_str;
uint32_t bit_mask;
StringPiece annotation;
+ bool preserve_params;
};
-static std::array<AnnotationRule, 2> sAnnotationRules = {{
- {"@SystemApi", AnnotationRule::kSystemApi, "@android.annotation.SystemApi"},
- {"@TestApi", AnnotationRule::kTestApi, "@android.annotation.TestApi"},
+static std::array<AnnotationRule, 3> sAnnotationRules = {{
+ {"@SystemApi", AnnotationRule::kSystemApi, "@android.annotation.SystemApi", true},
+ {"@TestApi", AnnotationRule::kTestApi, "@android.annotation.TestApi", false},
+ {"@FlaggedApi", AnnotationRule::kFlaggedApi, "@android.annotation.FlaggedApi", true},
}};
void AnnotationProcessor::AppendCommentLine(std::string comment) {
@@ -73,12 +76,11 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) {
std::string::size_type idx = comment.find(rule.doc_str.data());
if (idx != std::string::npos) {
// Captures all parameters associated with the specified annotation rule
- // by matching the first pair of parantheses after the rule.
- std::regex re(std::string(rule.doc_str) += "\\s*\\((.+)\\)");
+ // by matching the first pair of parentheses after the rule.
+ std::regex re(std::string(rule.doc_str).append(R"(\s*\((.+)\))"));
std::smatch match_result;
const bool is_match = std::regex_search(comment, match_result, re);
- // We currently only capture and preserve parameters for SystemApi.
- if (is_match && rule.bit_mask == AnnotationRule::kSystemApi) {
+ if (is_match && rule.preserve_params) {
annotation_parameter_map_[rule.bit_mask] = match_result[1].str();
comment.erase(comment.begin() + match_result.position(),
comment.begin() + match_result.position() + match_result.length());
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
index 6bc8902a6dcf..e98e96ba3bc3 100644
--- a/tools/aapt2/java/AnnotationProcessor_test.cpp
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -76,6 +76,36 @@ TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationParamsAndRemovesFromCommen
EXPECT_THAT(annotations, HasSubstr("This is a system API"));
}
+TEST(AnnotationProcessorTest, EmitsFlaggedApiAnnotationAndRemovesFromComment) {
+ AnnotationProcessor processor;
+ processor.AppendComment("@FlaggedApi This is a flagged API");
+
+ std::string annotations;
+ StringOutputStream out(&annotations);
+ Printer printer(&out);
+ processor.Print(&printer);
+ out.Flush();
+
+ EXPECT_THAT(annotations, HasSubstr("@android.annotation.FlaggedApi"));
+ EXPECT_THAT(annotations, Not(HasSubstr("@FlaggedApi")));
+ EXPECT_THAT(annotations, HasSubstr("This is a flagged API"));
+}
+
+TEST(AnnotationProcessorTest, EmitsFlaggedApiAnnotationParamsAndRemovesFromComment) {
+ AnnotationProcessor processor;
+ processor.AppendComment("@FlaggedApi (\"android.flags.my_flag\") This is a flagged API");
+
+ std::string annotations;
+ StringOutputStream out(&annotations);
+ Printer printer(&out);
+ processor.Print(&printer);
+ out.Flush();
+
+ EXPECT_THAT(annotations, HasSubstr("@android.annotation.FlaggedApi(\"android.flags.my_flag\")"));
+ EXPECT_THAT(annotations, Not(HasSubstr("@FlaggedApi")));
+ EXPECT_THAT(annotations, HasSubstr("This is a flagged API"));
+}
+
TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) {
AnnotationProcessor processor;
processor.AppendComment("@TestApi This is a test API");
diff --git a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
index e7fb2debfc4e..b71e5c47c70e 100644
--- a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
+++ b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
@@ -24,7 +24,7 @@ java_library_host {
],
static_libs: [
"junit",
- "truth-prebuilt",
+ "truth",
"mockito",
// http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
index 05d6a43cdb0f..f9dc305a4e3e 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
@@ -104,7 +104,7 @@ java_library_host {
],
static_libs: [
"junit",
- "truth-prebuilt",
+ "truth",
// http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/
"platform-test-annotations",
diff --git a/tools/processors/immutability/Android.bp b/tools/processors/immutability/Android.bp
index a7d69039fcb0..ecc283b0b37e 100644
--- a/tools/processors/immutability/Android.bp
+++ b/tools/processors/immutability/Android.bp
@@ -50,7 +50,7 @@ java_test_host {
static_libs: [
"compile-testing-prebuilt",
- "truth-prebuilt",
+ "truth",
"junit",
"kotlin-reflect",
"ImmutabilityAnnotationProcessorHostLibrary",
diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp
index 7059c52ddc76..9c755b7d58c2 100644
--- a/tools/processors/intdef_mappings/Android.bp
+++ b/tools/processors/intdef_mappings/Android.bp
@@ -38,7 +38,7 @@ java_test_host {
static_libs: [
"compile-testing-prebuilt",
- "truth-prebuilt",
+ "truth",
"junit",
"guava",
"libintdef-annotation-processor",
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index 7a299694741a..5a0f742372d7 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -40,7 +40,7 @@ android_test {
"frameworks-base-testutils",
"guava",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: [