summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb2
-rw-r--r--.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb2
-rw-r--r--.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb2
-rw-r--r--.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb2
-rw-r--r--apex/appsearch/Android.bp1
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java126
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java39
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java40
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java44
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java39
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java85
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java122
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java66
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java19
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java6
-rw-r--r--apex/appsearch/synced_jetpack_changeid.txt2
-rw-r--r--apex/jobscheduler/framework/java/android/app/AlarmManager.java74
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java298
-rw-r--r--apex/media/framework/java/android/media/MediaSession2.java4
-rw-r--r--api/Android.bp40
-rw-r--r--cmds/app_process/Android.bp11
-rw-r--r--cmds/app_process/version-script.txt4
-rw-r--r--core/api/test-current.txt6
-rw-r--r--core/java/android/app/Activity.java23
-rw-r--r--core/java/android/app/ActivityManagerInternal.java3
-rw-r--r--core/java/android/app/ActivityOptions.java13
-rw-r--r--core/java/android/app/AutomaticZenRule.java21
-rw-r--r--core/java/android/app/INotificationManager.aidl2
-rw-r--r--core/java/android/app/LoadedApk.java23
-rw-r--r--core/java/android/app/NotificationManager.java8
-rw-r--r--core/java/android/app/admin/DevicePolicyManagerInternal.java10
-rw-r--r--core/java/android/app/admin/DevicePolicyManagerLiteInternal.java41
-rw-r--r--core/java/android/app/usage/NetworkStatsManager.java27
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java12
-rw-r--r--core/java/android/bluetooth/OobData.java26
-rw-r--r--core/java/android/bluetooth/le/ScanFilter.java7
-rw-r--r--core/java/android/content/pm/AppSearchShortcutInfo.java2
-rw-r--r--core/java/android/content/pm/IPackageInstaller.aidl1
-rw-r--r--core/java/android/content/pm/ShortcutInfo.java33
-rw-r--r--core/java/android/content/pm/ShortcutServiceInternal.java2
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java3
-rw-r--r--core/java/android/hardware/biometrics/BiometricAuthenticator.java5
-rw-r--r--core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java97
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java19
-rw-r--r--core/java/android/hardware/camera2/params/OutputConfiguration.java25
-rw-r--r--core/java/android/hardware/camera2/params/SessionConfiguration.java8
-rw-r--r--core/java/android/hardware/camera2/params/VendorTagDescriptor.java8
-rw-r--r--core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java8
-rw-r--r--core/java/android/hardware/display/AmbientDisplayConfiguration.java9
-rw-r--r--core/java/android/net/nsd/NsdManager.java3
-rw-r--r--core/java/android/os/AggregateBatteryConsumer.java51
-rw-r--r--core/java/android/os/BatteryUsageStats.java296
-rw-r--r--core/java/android/os/BatteryUsageStatsQuery.java38
-rw-r--r--core/java/android/os/PackageTagsList.java156
-rw-r--r--core/java/android/os/PowerComponents.java183
-rw-r--r--core/java/android/os/SystemVibratorManager.java2
-rw-r--r--core/java/android/os/TEST_MAPPING22
-rw-r--r--core/java/android/os/UidBatteryConsumer.java101
-rw-r--r--core/java/android/os/UserBatteryConsumer.java42
-rw-r--r--core/java/android/os/UserManager.java19
-rw-r--r--core/java/android/os/VibrationAttributes.java5
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java15
-rw-r--r--core/java/android/speech/RecognitionService.java1
-rw-r--r--core/java/android/view/InputDevice.java7
-rw-r--r--core/java/android/view/WindowManager.java13
-rw-r--r--core/java/android/view/WindowManagerPolicyConstants.java8
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureEvent.java126
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java3
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java27
-rw-r--r--core/java/android/window/ITaskOrganizer.aidl5
-rw-r--r--core/java/android/window/SplashScreenView.java64
-rw-r--r--core/java/android/window/TaskOrganizer.java17
-rw-r--r--core/java/com/android/internal/display/BrightnessSynchronizer.java87
-rw-r--r--core/java/com/android/internal/jank/InteractionJankMonitor.java30
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java25
-rw-r--r--core/java/com/android/internal/os/BatteryUsageStatsProvider.java40
-rw-r--r--core/java/com/android/internal/os/BatteryUsageStatsStore.java285
-rw-r--r--core/java/com/android/internal/os/TEST_MAPPING14
-rw-r--r--core/java/com/android/internal/view/inline/InlineTooltipUi.java2
-rw-r--r--core/java/com/android/internal/widget/EmphasizedNotificationButton.java9
-rw-r--r--core/jni/android_util_AssetManager.cpp12
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/drawable/btn_notification_emphasized.xml20
-rw-r--r--core/res/res/layout/floating_popup_menu_button.xml2
-rw-r--r--core/res/res/values-af/strings.xml4
-rw-r--r--core/res/res/values-am/strings.xml4
-rw-r--r--core/res/res/values-ar/strings.xml4
-rw-r--r--core/res/res/values-as/strings.xml4
-rw-r--r--core/res/res/values-az/strings.xml4
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml4
-rw-r--r--core/res/res/values-be/strings.xml8
-rw-r--r--core/res/res/values-bg/strings.xml6
-rw-r--r--core/res/res/values-bn/strings.xml6
-rw-r--r--core/res/res/values-bs/strings.xml4
-rw-r--r--core/res/res/values-ca/strings.xml4
-rw-r--r--core/res/res/values-cs/strings.xml4
-rw-r--r--core/res/res/values-da/strings.xml6
-rw-r--r--core/res/res/values-de/strings.xml10
-rw-r--r--core/res/res/values-el/strings.xml4
-rw-r--r--core/res/res/values-en-rAU/strings.xml4
-rw-r--r--core/res/res/values-en-rCA/strings.xml4
-rw-r--r--core/res/res/values-en-rGB/strings.xml4
-rw-r--r--core/res/res/values-en-rIN/strings.xml4
-rw-r--r--core/res/res/values-en-rXC/strings.xml4
-rw-r--r--core/res/res/values-es-rUS/strings.xml4
-rw-r--r--core/res/res/values-es/strings.xml4
-rw-r--r--core/res/res/values-et/strings.xml4
-rw-r--r--core/res/res/values-eu/strings.xml4
-rw-r--r--core/res/res/values-fa/strings.xml4
-rw-r--r--core/res/res/values-fi/strings.xml4
-rw-r--r--core/res/res/values-fr-rCA/strings.xml12
-rw-r--r--core/res/res/values-fr/strings.xml4
-rw-r--r--core/res/res/values-gl/strings.xml4
-rw-r--r--core/res/res/values-gu/strings.xml4
-rw-r--r--core/res/res/values-hi/strings.xml4
-rw-r--r--core/res/res/values-hr/strings.xml4
-rw-r--r--core/res/res/values-hu/strings.xml4
-rw-r--r--core/res/res/values-hy/strings.xml4
-rw-r--r--core/res/res/values-in/strings.xml4
-rw-r--r--core/res/res/values-is/strings.xml4
-rw-r--r--core/res/res/values-it/strings.xml4
-rw-r--r--core/res/res/values-iw/strings.xml4
-rw-r--r--core/res/res/values-ja/strings.xml6
-rw-r--r--core/res/res/values-ka/strings.xml4
-rw-r--r--core/res/res/values-kk/strings.xml4
-rw-r--r--core/res/res/values-km/strings.xml4
-rw-r--r--core/res/res/values-kn/strings.xml6
-rw-r--r--core/res/res/values-ko/strings.xml4
-rw-r--r--core/res/res/values-ky/strings.xml4
-rw-r--r--core/res/res/values-lo/strings.xml4
-rw-r--r--core/res/res/values-lt/strings.xml6
-rw-r--r--core/res/res/values-lv/strings.xml4
-rw-r--r--core/res/res/values-mk/strings.xml6
-rw-r--r--core/res/res/values-ml/strings.xml4
-rw-r--r--core/res/res/values-mn/strings.xml4
-rw-r--r--core/res/res/values-mr/strings.xml4
-rw-r--r--core/res/res/values-ms/strings.xml4
-rw-r--r--core/res/res/values-my/strings.xml4
-rw-r--r--core/res/res/values-nb/strings.xml4
-rw-r--r--core/res/res/values-ne/strings.xml4
-rw-r--r--core/res/res/values-nl/strings.xml4
-rw-r--r--core/res/res/values-or/strings.xml4
-rw-r--r--core/res/res/values-pa/strings.xml4
-rw-r--r--core/res/res/values-pl/strings.xml4
-rw-r--r--core/res/res/values-pt-rBR/strings.xml4
-rw-r--r--core/res/res/values-pt-rPT/strings.xml4
-rw-r--r--core/res/res/values-pt/strings.xml4
-rw-r--r--core/res/res/values-ro/strings.xml4
-rw-r--r--core/res/res/values-ru/strings.xml4
-rw-r--r--core/res/res/values-si/strings.xml4
-rw-r--r--core/res/res/values-sk/strings.xml4
-rw-r--r--core/res/res/values-sl/strings.xml8
-rw-r--r--core/res/res/values-sq/strings.xml4
-rw-r--r--core/res/res/values-sr/strings.xml4
-rw-r--r--core/res/res/values-sv/strings.xml4
-rw-r--r--core/res/res/values-sw/strings.xml4
-rw-r--r--core/res/res/values-ta/strings.xml4
-rw-r--r--core/res/res/values-te/strings.xml6
-rw-r--r--core/res/res/values-th/strings.xml4
-rw-r--r--core/res/res/values-tl/strings.xml4
-rw-r--r--core/res/res/values-tr/strings.xml4
-rw-r--r--core/res/res/values-uk/strings.xml6
-rw-r--r--core/res/res/values-ur/strings.xml4
-rw-r--r--core/res/res/values-uz/strings.xml4
-rw-r--r--core/res/res/values-vi/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml4
-rw-r--r--core/res/res/values-zh-rHK/strings.xml4
-rw-r--r--core/res/res/values-zh-rTW/strings.xml8
-rw-r--r--core/res/res/values-zu/strings.xml4
-rw-r--r--core/res/res/values/colors.xml2
-rw-r--r--core/res/res/values/config.xml9
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp2
-rw-r--r--core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java76
-rw-r--r--core/tests/coretests/src/android/os/PackageTagsListTest.java52
-rw-r--r--core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java16
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java1
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java88
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java196
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java392
-rw-r--r--data/etc/car/com.android.car.cluster.home.xml1
-rw-r--r--data/etc/car/com.android.car.rotary.xml1
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java4
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java12
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java75
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEventCallback.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java54
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java45
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java14
-rw-r--r--libs/hwui/jni/Typeface.cpp102
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp34
-rw-r--r--libs/hwui/jni/fonts/Font.cpp54
-rw-r--r--libs/hwui/renderthread/CacheManager.cpp8
-rw-r--r--libs/hwui/renderthread/CacheManager.h3
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp16
-rw-r--r--libs/hwui/renderthread/CanvasContext.h1
-rw-r--r--location/java/android/location/LocationManagerInternal.java73
-rw-r--r--location/java/android/location/provider/LocationProviderBase.java16
-rw-r--r--media/java/android/media/MediaRouter.java16
-rw-r--r--packages/CtsShim/apk/arm/CtsShim.apkbin5483 -> 5488 bytes
-rw-r--r--packages/CtsShim/apk/arm/CtsShimPriv.apkbin31624 -> 31627 bytes
-rw-r--r--packages/CtsShim/apk/x86/CtsShim.apkbin5483 -> 5488 bytes
-rw-r--r--packages/CtsShim/apk/x86/CtsShimPriv.apkbin24257 -> 24260 bytes
-rw-r--r--packages/SettingsLib/IllustrationPreference/AndroidManifest.xml2
-rw-r--r--packages/SettingsLib/IllustrationPreference/res/drawable/ic_gesture_play_button.xml24
-rw-r--r--packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml46
-rw-r--r--packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/ColorUtils.java20
-rw-r--r--packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java111
-rw-r--r--packages/SettingsLib/RadioButtonPreference/res/layout/preference_radio.xml2
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-kk/strings.xml2
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-ne/strings.xml2
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-pt/strings.xml2
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml2
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-az/arrays.xml22
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml189
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml13
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml11
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml19
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml9
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml7
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java31
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java71
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/DeviceAdminStringProvider.java10
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java79
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java13
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java16
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt4
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt10
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java7
-rw-r--r--packages/SystemUI/res/drawable/rounded_bg_full_large_radius.xml3
-rw-r--r--packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml2
-rw-r--r--packages/SystemUI/res/layout/global_actions_change_panel.xml16
-rw-r--r--packages/SystemUI/res/layout/long_screenshot.xml1
-rw-r--r--packages/SystemUI/res/layout/people_space_activity.xml12
-rw-r--r--packages/SystemUI/res/layout/people_space_activity_no_conversations.xml1
-rw-r--r--packages/SystemUI/res/layout/people_space_tile_view.xml6
-rw-r--r--packages/SystemUI/res/layout/qs_tile_label.xml2
-rw-r--r--packages/SystemUI/res/layout/quick_qs_status_icons.xml11
-rw-r--r--packages/SystemUI/res/values-az/strings.xml4
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml12
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml12
-rw-r--r--packages/SystemUI/res/values-da/strings.xml2
-rw-r--r--packages/SystemUI/res/values-de/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml2
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml4
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml5
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml11
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml15
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml3
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml6
-rw-r--r--packages/SystemUI/res/values-it/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml2
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml30
-rw-r--r--packages/SystemUI/res/values-km/strings.xml2
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml12
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml12
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml29
-rw-r--r--packages/SystemUI/res/values-or/strings.xml3
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml15
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml4
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml16
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml16
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml4
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml5
-rw-r--r--packages/SystemUI/res/values-te/strings.xml15
-rw-r--r--packages/SystemUI/res/values-television/config.xml1
-rw-r--r--packages/SystemUI/res/values-th/strings.xml4
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml26
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml12
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml9
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SystemUI/res/values/attrs.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml5
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java22
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java42
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java40
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java141
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java146
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsInfoProvider.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/NotificationHelper.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java77
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt122
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/CropView.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java263
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java84
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java202
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java117
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java68
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt159
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt101
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java2
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-bn/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-gu/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-kn/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-mr/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-ne/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-pa/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-te/strings.xml21
-rw-r--r--packages/overlays/AvoidAppsInCutoutOverlay/res/values-ur/strings.xml (renamed from packages/SystemUI/res/drawable/people_space_activity_card.xml)15
-rw-r--r--packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values/config.xml4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java15
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java18
-rw-r--r--services/core/java/com/android/server/NsdService.java82
-rw-r--r--services/core/java/com/android/server/VcnManagementService.java29
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java52
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java88
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java12
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java27
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java6
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java6
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java15
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java64
-rw-r--r--services/core/java/com/android/server/appop/DiscreteRegistry.java90
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java11
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java12
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java52
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java11
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java192
-rw-r--r--services/core/java/com/android/server/display/WifiDisplayController.java5
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java103
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java8
-rw-r--r--services/core/java/com/android/server/location/eventlog/LocationEventLog.java17
-rw-r--r--services/core/java/com/android/server/location/provider/AbstractLocationProvider.java20
-rw-r--r--services/core/java/com/android/server/location/provider/LocationProviderManager.java10
-rw-r--r--services/core/java/com/android/server/location/provider/MockableLocationProvider.java29
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java9
-rw-r--r--services/core/java/com/android/server/notification/ShortcutHelper.java13
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java19
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java45
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java12
-rw-r--r--services/core/java/com/android/server/pm/ShortcutParser.java11
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java7
-rw-r--r--services/core/java/com/android/server/pm/SilentUpdatePolicy.java28
-rw-r--r--services/core/java/com/android/server/policy/AppOpsPolicy.java143
-rw-r--r--services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java21
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java24
-rw-r--r--services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java12
-rw-r--r--services/core/java/com/android/server/vibrator/RampToStepAdapter.java2
-rw-r--r--services/core/java/com/android/server/vibrator/StepToRampAdapter.java196
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationThread.java10
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java33
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java11
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java48
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java6
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java22
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java22
-rw-r--r--services/core/java/com/android/server/wm/LetterboxConfiguration.java115
-rw-r--r--services/core/java/com/android/server/wm/Task.java34
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java29
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerShellCommand.java361
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java18
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java10
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java6
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java11
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java442
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java121
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java134
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java68
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java82
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java62
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/RampToStepAdapterTest.java122
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java312
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java39
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java2
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java19
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java25
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java55
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java3
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java57
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java1
-rw-r--r--tests/UpdatableSystemFontTest/Android.bp1
-rw-r--r--tests/UpdatableSystemFontTest/EmojiRenderingTestApp/AndroidManifest.xml1
-rw-r--r--tests/UpdatableSystemFontTest/EmojiRenderingTestApp/src/com/android/emojirenderingtestapp/GetAvailableFontsTestActivity.java53
-rw-r--r--tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java21
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java16
607 files changed, 10256 insertions, 4295 deletions
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
index 80317e4634f3..748fe14cde3e 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7396576"
+ build_id: "7464984"
target: "CtsShim"
source_file: "aosp_arm64/CtsShimPriv.apk"
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
index 3605b6d0433b..15103b1f175c 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7396576"
+ build_id: "7464984"
target: "CtsShim"
source_file: "aosp_arm64/CtsShim.apk"
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
index 025ec3a9fdaf..2b9ed2fba339 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7396576"
+ build_id: "7464984"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShimPriv.apk"
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
index e19235a12f8f..d4ff3b7336b5 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7396576"
+ build_id: "7464984"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShim.apk"
}
diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp
index 9a420160d3fd..827842633942 100644
--- a/apex/appsearch/Android.bp
+++ b/apex/appsearch/Android.bp
@@ -29,6 +29,7 @@ apex {
key: "com.android.appsearch.key",
certificate: ":com.android.appsearch.certificate",
updatable: false,
+ generate_hashtree: false,
}
apex_key {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index a3b89b0f27fb..e5244296b1f4 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -179,7 +179,7 @@ public class AppSearchManagerService extends SystemService {
*/
private void handleUserRemoved(@NonNull UserHandle userHandle) {
try {
- mImplInstanceManager.removeAppSearchImplForUser(userHandle);
+ mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
mLoggerInstanceManager.removePlatformLoggerForUser(userHandle);
Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
} catch (Throwable t) {
@@ -348,19 +348,19 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- databaseName)
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setDatabase(databaseName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -480,19 +480,19 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- databaseName)
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setDatabase(databaseName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -563,19 +563,19 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- databaseName)
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setDatabase(databaseName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -631,19 +631,19 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- databaseName)
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setDatabase(databaseName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_SEARCH)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -697,20 +697,18 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- // TODO(b/173532925) database would be nulluable once we remove generalStats
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- /*database=*/ "")
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -965,19 +963,19 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- databaseName)
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setDatabase(databaseName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -1033,19 +1031,19 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(packageName,
- databaseName)
+ logger.logStats(new CallStats.Builder()
+ .setPackageName(packageName)
+ .setDatabase(databaseName)
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -1110,19 +1108,17 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- CallStats.Builder cBuilder = new CallStats.Builder(/*packageName=*/ "",
- /*databaseName=*/ "")
+ logger.logStats(new CallStats.Builder()
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_FLUSH)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
@@ -1162,21 +1158,17 @@ public class AppSearchManagerService extends SystemService {
2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
int totalLatencyMillis =
(int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
- // TODO(b/173532925) make packageName and database nullable after
- // removing generalStats
- CallStats.Builder cBuilder = new CallStats.Builder(/*packageName=*/"",
- /*database=*/ "")
+ logger.logStats(new CallStats.Builder()
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(totalLatencyMillis)
.setCallType(CallStats.CALL_TYPE_INITIALIZE)
// TODO(b/173532925) check the existing binder call latency chart
// is good enough for us:
// http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(operationSuccessCount)
- .setNumOperationsFailed(operationFailureCount);
- cBuilder.getGeneralStatsBuilder()
- .setStatusCode(statusCode)
- .setTotalLatencyMillis(totalLatencyMillis);
- logger.logStats(cBuilder.build());
+ .setNumOperationsFailed(operationFailureCount)
+ .build());
}
}
});
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
index 077527220149..2181dab90681 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -24,10 +24,12 @@ import android.content.Context;
import android.os.Environment;
import android.os.UserHandle;
import android.util.ArrayMap;
+import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
+import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
import java.io.File;
import java.util.Map;
@@ -37,9 +39,10 @@ import java.util.Objects;
* Manages the lifecycle of instances of {@link AppSearchImpl}.
*
* <p>These instances are managed per unique device-user.
+ * @hide
*/
public final class ImplInstanceManager {
- private static final String APP_SEARCH_DIR = "appSearch";
+ private static final String TAG = "AppSearchImplInstanceMa";
private static ImplInstanceManager sImplInstanceManager;
@@ -70,8 +73,11 @@ public final class ImplInstanceManager {
* <p>This folder should only be accessed after unlock.
*/
public static File getAppSearchDir(@NonNull UserHandle userHandle) {
- return new File(
- Environment.getDataSystemCeDirectory(userHandle.getIdentifier()), APP_SEARCH_DIR);
+ // Duplicates the implementation of Environment#getDataSystemCeDirectory
+ // TODO(b/191059409): Unhide Environment#getDataSystemCeDirectory and switch to it.
+ File systemCeDir = new File(Environment.getDataDirectory(), "system_ce");
+ File systemCeUserDir = new File(systemCeDir, String.valueOf(userHandle.getIdentifier()));
+ return new File(systemCeUserDir, "appSearch");
}
/**
@@ -104,25 +110,6 @@ public final class ImplInstanceManager {
}
/**
- * Remove an instance of {@link AppSearchImpl} for the given user.
- *
- * <p>This method should only be called if {@link AppSearchManagerService} receives an
- * ACTION_USER_REMOVED, which the instance of given user should be removed.
- *
- * <p>If the user is removed, the "credential encrypted" system directory where icing lives will
- * be auto-deleted. So we shouldn't worry about persist data or close the AppSearchImpl.
- *
- * @param userHandle The multi-user user handle of the user that need to be removed.
- */
- public void removeAppSearchImplForUser(@NonNull UserHandle userHandle) {
- Objects.requireNonNull(userHandle);
- synchronized (mInstancesLocked) {
- // no need to close and persist data to disk since we are removing them now.
- mInstancesLocked.remove(userHandle);
- }
- }
-
- /**
* Close and remove an instance of {@link AppSearchImpl} for the given user.
*
* <p>All mutation apply to this {@link AppSearchImpl} will be persisted to disk.
@@ -172,6 +159,12 @@ public final class ImplInstanceManager {
@Nullable AppSearchLogger logger)
throws AppSearchException {
File appSearchDir = getAppSearchDir(userHandle);
- return AppSearchImpl.create(appSearchDir, userContext, /*logger=*/ null);
+ File icingDir = new File(appSearchDir, "icing");
+ Log.i(TAG, "Creating new AppSearch instance at: " + icingDir);
+ return AppSearchImpl.create(
+ icingDir,
+ userContext,
+ /*logger=*/ null,
+ new FrameworkOptimizeStrategy());
}
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 29cb57c05eeb..4a1a9ae3546b 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -145,14 +145,14 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public final class AppSearchImpl implements Closeable {
private static final String TAG = "AppSearchImpl";
- @VisibleForTesting static final int OPTIMIZE_THRESHOLD_DOC_COUNT = 1000;
- @VisibleForTesting static final int OPTIMIZE_THRESHOLD_BYTES = 1_000_000; // 1MB
@VisibleForTesting static final int CHECK_OPTIMIZE_INTERVAL = 100;
private final ReadWriteLock mReadWriteLock = new ReentrantReadWriteLock();
private final LogUtil mLogUtil = new LogUtil(TAG);
+ private final OptimizeStrategy mOptimizeStrategy;
+
@GuardedBy("mReadWriteLock")
@VisibleForTesting
final IcingSearchEngine mIcingSearchEngineLocked;
@@ -201,10 +201,12 @@ public final class AppSearchImpl implements Closeable {
public static AppSearchImpl create(
@NonNull File icingDir,
@NonNull Context userContext,
- @Nullable AppSearchLogger logger)
+ @Nullable AppSearchLogger logger,
+ @NonNull OptimizeStrategy optimizeStrategy)
throws AppSearchException {
Objects.requireNonNull(icingDir);
Objects.requireNonNull(userContext);
+ Objects.requireNonNull(optimizeStrategy);
long totalLatencyStartMillis = SystemClock.elapsedRealtime();
InitializeStats.Builder initStatsBuilder = null;
@@ -212,7 +214,9 @@ public final class AppSearchImpl implements Closeable {
initStatsBuilder = new InitializeStats.Builder();
}
- AppSearchImpl appSearchImpl = new AppSearchImpl(icingDir, userContext, initStatsBuilder);
+ AppSearchImpl appSearchImpl =
+ new AppSearchImpl(
+ icingDir, userContext, initStatsBuilder, optimizeStrategy);
long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
appSearchImpl.initializeVisibilityStore();
@@ -236,7 +240,8 @@ public final class AppSearchImpl implements Closeable {
private AppSearchImpl(
@NonNull File icingDir,
@NonNull Context userContext,
- @Nullable InitializeStats.Builder initStatsBuilder)
+ @Nullable InitializeStats.Builder initStatsBuilder,
+ @NonNull OptimizeStrategy optimizeStrategy)
throws AppSearchException {
mReadWriteLock.writeLock().lock();
@@ -254,6 +259,7 @@ public final class AppSearchImpl implements Closeable {
Objects.hashCode(mIcingSearchEngineLocked));
mVisibilityStoreLocked = new VisibilityStore(this, userContext);
+ mOptimizeStrategy = optimizeStrategy;
// The core initialization procedure. If any part of this fails, we bail into
// resetLocked(), deleting all data (but hopefully allowing AppSearchImpl to come up).
@@ -646,9 +652,7 @@ public final class AppSearchImpl implements Closeable {
// Logging stats
if (pStatsBuilder != null) {
pStatsBuilder
- .getGeneralStatsBuilder()
- .setStatusCode(statusProtoToResultCode(putResultProto.getStatus()));
- pStatsBuilder
+ .setStatusCode(statusProtoToResultCode(putResultProto.getStatus()))
.setGenerateDocumentProtoLatencyMillis(
(int)
(generateDocumentProtoEndTimeMillis
@@ -667,9 +671,8 @@ public final class AppSearchImpl implements Closeable {
if (logger != null) {
long totalEndTimeMillis = SystemClock.elapsedRealtime();
- pStatsBuilder
- .getGeneralStatsBuilder()
- .setTotalLatencyMillis((int) (totalEndTimeMillis - totalStartTimeMillis));
+ pStatsBuilder.setTotalLatencyMillis(
+ (int) (totalEndTimeMillis - totalStartTimeMillis));
logger.logStats(pStatsBuilder.build());
}
}
@@ -812,7 +815,8 @@ public final class AppSearchImpl implements Closeable {
*
* @param queryExpression Query String to search.
* @param searchSpec Spec for setting filters, raw query etc.
- * @param callerPackageName Package name of the caller, should belong to the {@code callerUid}.
+ * @param callerPackageName Package name of the caller, should belong to the {@code
+ * userContext}.
* @param callerUid UID of the client making the globalQuery call.
* @param logger logger to collect globalQuery stats
* @return The results of performing this search. It may contain an empty list of results if no
@@ -2001,7 +2005,7 @@ public final class AppSearchImpl implements Closeable {
* resources that could be released.
*
* <p>{@link IcingSearchEngine#optimize()} should be called only if {@link
- * GetOptimizeInfoResultProto} shows there is enough resources could be released.
+ * OptimizeStrategy#shouldOptimize(GetOptimizeInfoResultProto)} return true.
*/
public void checkForOptimize() throws AppSearchException {
mReadWriteLock.writeLock().lock();
@@ -2009,9 +2013,7 @@ public final class AppSearchImpl implements Closeable {
GetOptimizeInfoResultProto optimizeInfo = getOptimizeInfoResultLocked();
checkSuccess(optimizeInfo.getStatus());
mOptimizeIntervalCountLocked = 0;
- // Second threshold, decide when to call optimize().
- if (optimizeInfo.getOptimizableDocs() >= OPTIMIZE_THRESHOLD_DOC_COUNT
- || optimizeInfo.getEstimatedOptimizableBytes() >= OPTIMIZE_THRESHOLD_BYTES) {
+ if (mOptimizeStrategy.shouldOptimize(optimizeInfo)) {
optimize();
}
} finally {
@@ -2022,11 +2024,7 @@ public final class AppSearchImpl implements Closeable {
// go/icing-library-apis.
}
- /**
- * Triggers {@link IcingSearchEngine#optimize()} directly.
- *
- * <p>This method should be only called as a scheduled task in AppSearch Platform backend.
- */
+ /** Triggers {@link IcingSearchEngine#optimize()} directly. */
public void optimize() throws AppSearchException {
mReadWriteLock.writeLock().lock();
try {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java
new file mode 100644
index 000000000000..8ec30e186306
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategy.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.appsearch.external.localstorage;
+
+import android.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import com.google.android.icing.proto.GetOptimizeInfoResultProto;
+
+/**
+ * An implementation of {@link OptimizeStrategy} will determine when to trigger {@link
+ * AppSearchImpl#optimize()} in Jetpack environment.
+ *
+ * @hide
+ */
+public class FrameworkOptimizeStrategy implements OptimizeStrategy {
+
+ @VisibleForTesting static final int DOC_COUNT_OPTIMIZE_THRESHOLD = 100_000;
+ @VisibleForTesting static final int BYTES_OPTIMIZE_THRESHOLD = 1 * 1024 * 1024 * 1024; // 1GB
+
+ @VisibleForTesting
+ static final long TIME_OPTIMIZE_THRESHOLD_MILLIS = 7 * 24 * 60 * 60 * 1000; // 1 week
+
+ @Override
+ public boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo) {
+ return optimizeInfo.getOptimizableDocs() >= DOC_COUNT_OPTIMIZE_THRESHOLD
+ || optimizeInfo.getEstimatedOptimizableBytes() >= BYTES_OPTIMIZE_THRESHOLD
+ || optimizeInfo.getTimeSinceLastOptimizeMs() >= TIME_OPTIMIZE_THRESHOLD_MILLIS;
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java
new file mode 100644
index 000000000000..6cb84bc64eb9
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/OptimizeStrategy.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appsearch.external.localstorage;
+
+import android.annotation.NonNull;
+
+import com.google.android.icing.proto.GetOptimizeInfoResultProto;
+
+/**
+ * An interface class for implementing a strategy to determine when to trigger {@link
+ * AppSearchImpl#optimize()}.
+ *
+ * @hide
+ */
+public interface OptimizeStrategy {
+
+ /**
+ * Determines whether {@link AppSearchImpl#optimize()} need to be triggered to release garbage
+ * resources in AppSearch base on the given information.
+ *
+ * @param optimizeInfo The proto object indicates the number of garbage resources in AppSearch.
+ * @return {@code true} if {@link AppSearchImpl#optimize()} need to be triggered.
+ */
+ boolean shouldOptimize(@NonNull GetOptimizeInfoResultProto optimizeInfo);
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
index ea5263aa9aa5..81fb418a6a0a 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
@@ -18,6 +18,8 @@ package com.android.server.appsearch.external.localstorage.stats;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.appsearch.AppSearchResult;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -29,9 +31,9 @@ import java.util.Objects;
* <p>This class can set which stats to log for both batch and non-batch {@link
* android.app.appsearch.AppSearchSession} calls.
*
- * <p>Some function calls like {@link android.app.appsearch.AppSearchSession#setSchema} have their
- * own detailed stats class {@link placeholder}. However, {@link CallStats} can still be used along
- * with the detailed stats class for easy aggregation/analysis with other function calls.
+ * <p>Some function calls may have their own detailed stats class like {@link PutDocumentStats}.
+ * However, {@link CallStats} can still be used along with the detailed stats class for easy
+ * aggregation/analysis with other function calls.
*
* @hide
*/
@@ -73,7 +75,16 @@ public class CallStats {
public static final int CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH = 13;
public static final int CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH = 14;
- @NonNull private final GeneralStats mGeneralStats;
+ @Nullable private final String mPackageName;
+ @Nullable private final String mDatabase;
+ /**
+ * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
+ * state.
+ */
+ @AppSearchResult.ResultCode private final int mStatusCode;
+
+ private final int mTotalLatencyMillis;
+
@CallType private final int mCallType;
private final int mEstimatedBinderLatencyMillis;
private final int mNumOperationsSucceeded;
@@ -81,17 +92,37 @@ public class CallStats {
CallStats(@NonNull Builder builder) {
Objects.requireNonNull(builder);
- mGeneralStats = Objects.requireNonNull(builder.mGeneralStatsBuilder).build();
+ mPackageName = builder.mPackageName;
+ mDatabase = builder.mDatabase;
+ mStatusCode = builder.mStatusCode;
+ mTotalLatencyMillis = builder.mTotalLatencyMillis;
mCallType = builder.mCallType;
mEstimatedBinderLatencyMillis = builder.mEstimatedBinderLatencyMillis;
mNumOperationsSucceeded = builder.mNumOperationsSucceeded;
mNumOperationsFailed = builder.mNumOperationsFailed;
}
- /** Returns general information for the call. */
- @NonNull
- public GeneralStats getGeneralStats() {
- return mGeneralStats;
+ /** Returns calling package name. */
+ @Nullable
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns calling database name. */
+ @Nullable
+ public String getDatabase() {
+ return mDatabase;
+ }
+
+ /** Returns status code for this api call. */
+ @AppSearchResult.ResultCode
+ public int getStatusCode() {
+ return mStatusCode;
+ }
+
+ /** Returns total latency of this api call in millis. */
+ public int getTotalLatencyMillis() {
+ return mTotalLatencyMillis;
}
/** Returns type of the call. */
@@ -137,23 +168,41 @@ public class CallStats {
/** Builder for {@link CallStats}. */
public static class Builder {
- @NonNull final GeneralStats.Builder mGeneralStatsBuilder;
+ @Nullable String mPackageName;
+ @Nullable String mDatabase;
+ @AppSearchResult.ResultCode int mStatusCode;
+ int mTotalLatencyMillis;
@CallType int mCallType;
int mEstimatedBinderLatencyMillis;
int mNumOperationsSucceeded;
int mNumOperationsFailed;
- /** Builder takes {@link GeneralStats.Builder}. */
- public Builder(@NonNull String packageName, @NonNull String database) {
- Objects.requireNonNull(packageName);
- Objects.requireNonNull(database);
- mGeneralStatsBuilder = new GeneralStats.Builder(packageName, database);
+ /** Sets the PackageName used by the session. */
+ @NonNull
+ public Builder setPackageName(@NonNull String packageName) {
+ mPackageName = Objects.requireNonNull(packageName);
+ return this;
+ }
+
+ /** Sets the database used by the session. */
+ @NonNull
+ public Builder setDatabase(@NonNull String database) {
+ mDatabase = Objects.requireNonNull(database);
+ return this;
}
- /** Returns {@link GeneralStats.Builder}. */
+ /** Sets the status code. */
@NonNull
- public GeneralStats.Builder getGeneralStatsBuilder() {
- return mGeneralStatsBuilder;
+ public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
+ mStatusCode = statusCode;
+ return this;
+ }
+
+ /** Sets total latency in millis. */
+ @NonNull
+ public Builder setTotalLatencyMillis(int totalLatencyMillis) {
+ mTotalLatencyMillis = totalLatencyMillis;
+ return this;
}
/** Sets type of the call. */
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java
deleted file mode 100644
index 53c1ee3f675f..000000000000
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.appsearch.external.localstorage.stats;
-
-import android.annotation.NonNull;
-import android.app.appsearch.AppSearchResult;
-
-import java.util.Objects;
-
-/**
- * A class for holding general logging information.
- *
- * <p>This class cannot be logged by {@link
- * com.android.server.appsearch.external.localstorage.AppSearchLogger} directly. It is used for
- * defining general logging information that is shared across different stats classes.
- *
- * @see PutDocumentStats
- * @see CallStats
- * @hide
- */
-public final class GeneralStats {
- /** Package name of the application. */
- @NonNull private final String mPackageName;
-
- /** Database name within AppSearch. */
- @NonNull private final String mDatabase;
-
- /**
- * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
- * state.
- */
- @AppSearchResult.ResultCode private final int mStatusCode;
-
- private final int mTotalLatencyMillis;
-
- GeneralStats(@NonNull Builder builder) {
- Objects.requireNonNull(builder);
- mPackageName = Objects.requireNonNull(builder.mPackageName);
- mDatabase = Objects.requireNonNull(builder.mDatabase);
- mStatusCode = builder.mStatusCode;
- mTotalLatencyMillis = builder.mTotalLatencyMillis;
- }
-
- /** Returns package name. */
- @NonNull
- public String getPackageName() {
- return mPackageName;
- }
-
- /** Returns database name. */
- @NonNull
- public String getDatabase() {
- return mDatabase;
- }
-
- /** Returns result code from {@link AppSearchResult#getResultCode()} */
- @AppSearchResult.ResultCode
- public int getStatusCode() {
- return mStatusCode;
- }
-
- /** Returns total latency, in milliseconds. */
- public int getTotalLatencyMillis() {
- return mTotalLatencyMillis;
- }
-
- /** Builder for {@link GeneralStats}. */
- public static class Builder {
- @NonNull final String mPackageName;
- @NonNull final String mDatabase;
- @AppSearchResult.ResultCode int mStatusCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
- int mTotalLatencyMillis;
-
- /**
- * Constructor
- *
- * @param packageName name of the package logging stats
- * @param database name of the database logging stats
- */
- public Builder(@NonNull String packageName, @NonNull String database) {
- mPackageName = Objects.requireNonNull(packageName);
- mDatabase = Objects.requireNonNull(database);
- }
-
- /** Sets status code returned from {@link AppSearchResult#getResultCode()} */
- @NonNull
- public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
- mStatusCode = statusCode;
- return this;
- }
-
- /** Sets total latency, in milliseconds. */
- @NonNull
- public Builder setTotalLatencyMillis(int totalLatencyMillis) {
- mTotalLatencyMillis = totalLatencyMillis;
- return this;
- }
-
- /**
- * Creates a new {@link GeneralStats} object from the contents of this {@link Builder}
- * instance.
- */
- @NonNull
- public GeneralStats build() {
- return new GeneralStats(/* builder= */ this);
- }
- }
-}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
index d031172d29c1..7ba181668bfd 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
@@ -17,6 +17,7 @@
package com.android.server.appsearch.external.localstorage.stats;
import android.annotation.NonNull;
+import android.app.appsearch.AppSearchResult;
import java.util.Objects;
@@ -27,8 +28,15 @@ import java.util.Objects;
* @hide
*/
public final class PutDocumentStats {
- /** {@link GeneralStats} holds the general stats. */
- @NonNull private final GeneralStats mGeneralStats;
+ @NonNull private final String mPackageName;
+ @NonNull private final String mDatabase;
+ /**
+ * The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
+ * state.
+ */
+ @AppSearchResult.ResultCode private final int mStatusCode;
+
+ private final int mTotalLatencyMillis;
/** Time used to generate a document proto from a Bundle. */
private final int mGenerateDocumentProtoLatencyMillis;
@@ -61,7 +69,10 @@ public final class PutDocumentStats {
PutDocumentStats(@NonNull Builder builder) {
Objects.requireNonNull(builder);
- mGeneralStats = Objects.requireNonNull(builder.mGeneralStatsBuilder).build();
+ mPackageName = builder.mPackageName;
+ mDatabase = builder.mDatabase;
+ mStatusCode = builder.mStatusCode;
+ mTotalLatencyMillis = builder.mTotalLatencyMillis;
mGenerateDocumentProtoLatencyMillis = builder.mGenerateDocumentProtoLatencyMillis;
mRewriteDocumentTypesLatencyMillis = builder.mRewriteDocumentTypesLatencyMillis;
mNativeLatencyMillis = builder.mNativeLatencyMillis;
@@ -73,10 +84,27 @@ public final class PutDocumentStats {
mNativeExceededMaxNumTokens = builder.mNativeExceededMaxNumTokens;
}
- /** Returns the {@link GeneralStats} object attached to this instance. */
+ /** Returns calling package name. */
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns calling database name. */
@NonNull
- public GeneralStats getGeneralStats() {
- return mGeneralStats;
+ public String getDatabase() {
+ return mDatabase;
+ }
+
+ /** Returns status code for this putDocument. */
+ @AppSearchResult.ResultCode
+ public int getStatusCode() {
+ return mStatusCode;
+ }
+
+ /** Returns total latency of this putDocument in millis. */
+ public int getTotalLatencyMillis() {
+ return mTotalLatencyMillis;
}
/** Returns time spent on generating document proto, in milliseconds. */
@@ -129,7 +157,10 @@ public final class PutDocumentStats {
/** Builder for {@link PutDocumentStats}. */
public static class Builder {
- @NonNull final GeneralStats.Builder mGeneralStatsBuilder;
+ @NonNull final String mPackageName;
+ @NonNull final String mDatabase;
+ @AppSearchResult.ResultCode int mStatusCode;
+ int mTotalLatencyMillis;
int mGenerateDocumentProtoLatencyMillis;
int mRewriteDocumentTypesLatencyMillis;
int mNativeLatencyMillis;
@@ -140,17 +171,24 @@ public final class PutDocumentStats {
int mNativeNumTokensIndexed;
boolean mNativeExceededMaxNumTokens;
- /** Builder takes {@link GeneralStats.Builder}. */
+ /** Builder for {@link PutDocumentStats} */
public Builder(@NonNull String packageName, @NonNull String database) {
- Objects.requireNonNull(packageName);
- Objects.requireNonNull(database);
- mGeneralStatsBuilder = new GeneralStats.Builder(packageName, database);
+ mPackageName = Objects.requireNonNull(packageName);
+ mDatabase = Objects.requireNonNull(database);
}
- /** Returns {@link GeneralStats.Builder}. */
+ /** Sets the status code. */
@NonNull
- public GeneralStats.Builder getGeneralStatsBuilder() {
- return mGeneralStatsBuilder;
+ public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
+ mStatusCode = statusCode;
+ return this;
+ }
+
+ /** Sets total latency in millis. */
+ @NonNull
+ public Builder setTotalLatencyMillis(int totalLatencyMillis) {
+ mTotalLatencyMillis = totalLatencyMillis;
+ return this;
}
/** Sets how much time we spend for generating document proto, in milliseconds. */
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
index 5a0199f8d78f..31fead5e6314 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
@@ -192,9 +192,8 @@ public final class PlatformLogger implements AppSearchLogger {
@GuardedBy("mLock")
private void logStatsImplLocked(@NonNull CallStats stats) {
mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
- ExtraStats extraStats = createExtraStatsLocked(stats.getGeneralStats().getPackageName(),
- stats.getCallType());
- String database = stats.getGeneralStats().getDatabase();
+ ExtraStats extraStats = createExtraStatsLocked(stats.getPackageName(), stats.getCallType());
+ String database = stats.getDatabase();
try {
int hashCodeForDatabase = calculateHashCodeMd5(database);
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_CALL_STATS_REPORTED,
@@ -202,8 +201,8 @@ public final class PlatformLogger implements AppSearchLogger {
extraStats.mSkippedSampleCount,
extraStats.mPackageUid,
hashCodeForDatabase,
- stats.getGeneralStats().getStatusCode(),
- stats.getGeneralStats().getTotalLatencyMillis(),
+ stats.getStatusCode(),
+ stats.getTotalLatencyMillis(),
stats.getCallType(),
stats.getEstimatedBinderLatencyMillis(),
stats.getNumOperationsSucceeded(),
@@ -224,9 +223,9 @@ public final class PlatformLogger implements AppSearchLogger {
@GuardedBy("mLock")
private void logStatsImplLocked(@NonNull PutDocumentStats stats) {
mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
- ExtraStats extraStats = createExtraStatsLocked(stats.getGeneralStats().getPackageName(),
- CallStats.CALL_TYPE_PUT_DOCUMENT);
- String database = stats.getGeneralStats().getDatabase();
+ ExtraStats extraStats = createExtraStatsLocked(
+ stats.getPackageName(), CallStats.CALL_TYPE_PUT_DOCUMENT);
+ String database = stats.getDatabase();
try {
int hashCodeForDatabase = calculateHashCodeMd5(database);
AppSearchStatsLog.write(AppSearchStatsLog.APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED,
@@ -234,8 +233,8 @@ public final class PlatformLogger implements AppSearchLogger {
extraStats.mSkippedSampleCount,
extraStats.mPackageUid,
hashCodeForDatabase,
- stats.getGeneralStats().getStatusCode(),
- stats.getGeneralStats().getTotalLatencyMillis(),
+ stats.getStatusCode(),
+ stats.getTotalLatencyMillis(),
stats.getGenerateDocumentProtoLatencyMillis(),
stats.getRewriteDocumentTypesLatencyMillis(),
stats.getNativeLatencyMillis(),
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
index 95ed36898c73..af09210b2c18 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java
@@ -66,8 +66,8 @@ import java.util.Set;
* @hide
*/
public class VisibilityStore {
- /** No-op user id that won't have any visibility settings. */
- public static final int NO_OP_USER_ID = -1;
+ /** No-op uid that won't have any visibility settings. */
+ public static final int NO_OP_UID = -1;
/** Version for the visibility schema */
private static final int SCHEMA_VERSION = 0;
@@ -106,7 +106,7 @@ public class VisibilityStore {
* @param userContext Context of the user that the call is being made as
*/
public VisibilityStore(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext) {
- mAppSearchImpl = appSearchImpl;
+ mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
mUserContext = Objects.requireNonNull(userContext);
}
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 395292df120a..78d39cc6deac 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-c35ced970a63a6c7b1d17f9706160579540850d6
+31a54dba5bda4d0109ea91eb1ac047c937cbaae3
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 9fa7810ab155..1efe5cb2f53e 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -662,10 +662,19 @@ public class AlarmManager {
* scheduled as exact. Applications are strongly discouraged from using exact
* alarms unnecessarily as they reduce the OS's ability to minimize battery use.
*
- * <p>
- * Starting with {@link Build.VERSION_CODES#S}, apps require the
+ * <p class="note"><strong>Note:</strong>
+ * Starting with {@link Build.VERSION_CODES#S}, apps targeting SDK level 31 or higher
+ * need to request the
* {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this
- * API.
+ * API, unless the app is exempt from battery restrictions.
+ * The user and the system can revoke this permission via the special app access screen in
+ * Settings.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Exact alarms should only be used for user-facing features.
+ * For more details, see <a
+ * href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
+ * Exact alarm permission</a>.
*
* @param type type of alarm.
* @param triggerAtMillis time in milliseconds that the alarm should go
@@ -685,6 +694,7 @@ public class AlarmManager {
* @see #ELAPSED_REALTIME_WAKEUP
* @see #RTC
* @see #RTC_WAKEUP
+ * @see Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM
*/
@RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true)
public void setExact(@AlarmType int type, long triggerAtMillis, PendingIntent operation) {
@@ -701,10 +711,21 @@ public class AlarmManager {
* invoked via the specified target Handler, or on the application's main looper
* if {@code null} is passed as the {@code targetHandler} parameter.
*
- * <p>
- * Starting with {@link Build.VERSION_CODES#S}, apps require the
+ * <p class="note"><strong>Note:</strong>
+ * Starting with {@link Build.VERSION_CODES#S}, apps targeting SDK level 31 or higher
+ * need to request the
* {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this
- * API.
+ * API, unless the app is exempt from battery restrictions.
+ * The user and the system can revoke this permission via the special app access screen in
+ * Settings.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Exact alarms should only be used for user-facing features.
+ * For more details, see <a
+ * href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
+ * Exact alarm permission</a>.
+ *
+ * @see Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM
*/
@RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true)
public void setExact(@AlarmType int type, long triggerAtMillis, String tag,
@@ -745,9 +766,21 @@ public class AlarmManager {
* This method is like {@link #setExact(int, long, PendingIntent)}, but implies
* {@link #RTC_WAKEUP}.
*
- * <p>
- * Starting from API {@link Build.VERSION_CODES#S}, using this method requires the
- * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission. Alarms scheduled via this API
+ * <p class="note"><strong>Note:</strong>
+ * Starting with {@link Build.VERSION_CODES#S}, apps targeting SDK level 31 or higher
+ * need to request the
+ * {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this
+ * API.
+ * The user and the system can revoke this permission via the special app access screen in
+ * Settings.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Exact alarms should only be used for user-facing features.
+ * For more details, see <a
+ * href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
+ * Exact alarm permission</a>.
+ *
+ * <p>Alarms scheduled via this API
* will be allowed to start a foreground service even if the app is in the background.
*
* @param info
@@ -764,6 +797,7 @@ public class AlarmManager {
* @see android.content.Context#sendBroadcast
* @see android.content.Context#registerReceiver
* @see android.content.Intent#filterEquals
+ * @see Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM
*/
@RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM)
public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
@@ -1090,11 +1124,22 @@ public class AlarmManager {
* device is idle it may take even more liberties with scheduling in order to optimize
* for battery life.</p>
*
- * <p>
- * Starting from API {@link Build.VERSION_CODES#S}, using this method requires the
- * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission, unless the app is exempt from
- * battery restrictions. Alarms scheduled via this API will be allowed to start a foreground
- * service even if the app is in the background.
+ * <p class="note"><strong>Note:</strong>
+ * Starting with {@link Build.VERSION_CODES#S}, apps targeting SDK level 31 or higher
+ * need to request the
+ * {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this
+ * API, unless the app is exempt from battery restrictions.
+ * The user and the system can revoke this permission via the special app access screen in
+ * Settings.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Exact alarms should only be used for user-facing features.
+ * For more details, see <a
+ * href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
+ * Exact alarm permission</a>.
+ *
+ * <p>Alarms scheduled via this API
+ * will be allowed to start a foreground service even if the app is in the background.
*
* @param type type of alarm.
* @param triggerAtMillis time in milliseconds that the alarm should go
@@ -1114,6 +1159,7 @@ public class AlarmManager {
* @see #ELAPSED_REALTIME_WAKEUP
* @see #RTC
* @see #RTC_WAKEUP
+ * @see Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM
*/
@RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true)
public void setExactAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 1169391d2cd2..fb5129f18417 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -136,6 +136,8 @@ import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.usage.AppStandbyInternal;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
@@ -215,9 +217,18 @@ public class AlarmManagerService extends SystemService {
final Object mLock = new Object();
- /** Immutable set of app ids that have requested SCHEDULE_EXACT_ALARM permission.*/
+ /** Immutable set of app ids requesting {@link Manifest.permission#SCHEDULE_EXACT_ALARM} */
@VisibleForTesting
volatile Set<Integer> mExactAlarmCandidates = Collections.emptySet();
+
+ /**
+ * A map from uid to the last op-mode we have seen for
+ * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}
+ */
+ @VisibleForTesting
+ @GuardedBy("mLock")
+ SparseIntArray mLastOpScheduleExactAlarm = new SparseIntArray();
+
// List of alarms per uid deferred due to user applied background restrictions on the source app
SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>();
private long mNextWakeup;
@@ -522,6 +533,9 @@ public class AlarmManagerService extends SystemService {
static final String KEY_MIN_DEVICE_IDLE_FUZZ = "min_device_idle_fuzz";
@VisibleForTesting
static final String KEY_MAX_DEVICE_IDLE_FUZZ = "max_device_idle_fuzz";
+ @VisibleForTesting
+ static final String KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED =
+ "kill_on_schedule_exact_alarm_revoked";
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
@@ -564,6 +578,8 @@ public class AlarmManagerService extends SystemService {
private static final long DEFAULT_MIN_DEVICE_IDLE_FUZZ = 2 * 60_000;
private static final long DEFAULT_MAX_DEVICE_IDLE_FUZZ = 15 * 60_000;
+ private static final boolean DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = true;
+
// Minimum futurity of a new alarm
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
@@ -644,6 +660,13 @@ public class AlarmManagerService extends SystemService {
*/
public long MAX_DEVICE_IDLE_FUZZ = DEFAULT_MAX_DEVICE_IDLE_FUZZ;
+ /**
+ * Whether or not to kill app when the permission
+ * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} is revoked.
+ */
+ public boolean KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED =
+ DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED;
+
private long mLastAllowWhileIdleWhitelistDuration = -1;
private int mVersion = 0;
@@ -816,6 +839,11 @@ public class AlarmManagerService extends SystemService {
deviceIdleFuzzBoundariesUpdated = true;
}
break;
+ case KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED:
+ KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = properties.getBoolean(
+ KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED,
+ DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED);
+ break;
default:
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
// The quotas need to be updated in order, so we can't just rely
@@ -830,17 +858,24 @@ public class AlarmManagerService extends SystemService {
}
private void updateExactAlarmDenyList(String[] newDenyList) {
+ final Set<String> newSet = Collections.unmodifiableSet(new ArraySet<>(newDenyList));
+ final Set<String> removed = new ArraySet<>(EXACT_ALARM_DENY_LIST);
+ final Set<String> added = new ArraySet<>(newDenyList);
+
+ added.removeAll(EXACT_ALARM_DENY_LIST);
+ removed.removeAll(newSet);
+ if (added.size() > 0) {
+ mHandler.obtainMessage(AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_ADDED, added)
+ .sendToTarget();
+ }
+ if (removed.size() > 0) {
+ mHandler.obtainMessage(AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED, removed)
+ .sendToTarget();
+ }
if (newDenyList.length == 0) {
EXACT_ALARM_DENY_LIST = Collections.emptySet();
} else {
- final Set<String> oldSet = EXACT_ALARM_DENY_LIST;
- final Set<String> newlyAdded = new ArraySet<>(newDenyList);
- EXACT_ALARM_DENY_LIST = Collections.unmodifiableSet(new ArraySet<>(newlyAdded));
- newlyAdded.removeAll(oldSet);
- if (newlyAdded.size() > 0) {
- mHandler.obtainMessage(AlarmHandler.EXACT_ALARM_DENY_LIST_CHANGED, newlyAdded)
- .sendToTarget();
- }
+ EXACT_ALARM_DENY_LIST = newSet;
}
}
@@ -1007,6 +1042,20 @@ public class AlarmManagerService extends SystemService {
pw.print(KEY_EXACT_ALARM_DENY_LIST, EXACT_ALARM_DENY_LIST);
pw.println();
+ pw.print(KEY_MIN_DEVICE_IDLE_FUZZ);
+ pw.print("=");
+ TimeUtils.formatDuration(MIN_DEVICE_IDLE_FUZZ, pw);
+ pw.println();
+
+ pw.print(KEY_MAX_DEVICE_IDLE_FUZZ);
+ pw.print("=");
+ TimeUtils.formatDuration(MAX_DEVICE_IDLE_FUZZ, pw);
+ pw.println();
+
+ pw.print(KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED,
+ KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED);
+ pw.println();
+
pw.decreaseIndent();
}
@@ -1667,16 +1716,57 @@ public class AlarmManagerService extends SystemService {
void refreshExactAlarmCandidates() {
final String[] candidates = mLocalPermissionManager.getAppOpPermissionPackages(
Manifest.permission.SCHEDULE_EXACT_ALARM);
- final Set<Integer> appIds = new ArraySet<>(candidates.length);
+ final Set<Integer> newAppIds = new ArraySet<>(candidates.length);
for (final String candidate : candidates) {
final int uid = mPackageManagerInternal.getPackageUid(candidate,
PackageManager.MATCH_ANY_USER, USER_SYSTEM);
if (uid > 0) {
- appIds.add(UserHandle.getAppId(uid));
+ newAppIds.add(UserHandle.getAppId(uid));
+ }
+ }
+ final ArraySet<Integer> removed = new ArraySet<>(mExactAlarmCandidates);
+ removed.removeAll(newAppIds);
+ // This code is only called on package_added and boot. The set {removed} is only expected to
+ // be non-empty when a package was updated and it removed the permission from its manifest.
+ for (int i = 0; i < removed.size(); i++) {
+ final int removedAppId = removed.valueAt(i);
+ synchronized (mLock) {
+ Slog.i(TAG, "App id " + removedAppId + " lost SCHEDULE_EXACT_ALARM on update");
+
+ final Predicate<Alarm> whichAlarms = a -> {
+ if (UserHandle.getAppId(a.uid) != removedAppId || a.windowLength != 0) {
+ return false;
+ }
+ if (!isExactAlarmChangeEnabled(a.packageName, UserHandle.getUserId(a.uid))) {
+ return false;
+ }
+ return a.alarmClock != null || !isExemptFromExactAlarmPermission(a.uid);
+ };
+ removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
}
}
// No need to lock. Assignment is always atomic.
- mExactAlarmCandidates = Collections.unmodifiableSet(appIds);
+ mExactAlarmCandidates = Collections.unmodifiableSet(newAppIds);
+ }
+
+ @Override
+ public void onUserStarting(TargetUser user) {
+ super.onUserStarting(user);
+ final int userId = user.getUserIdentifier();
+ mHandler.post(() -> {
+ for (final int appId : mExactAlarmCandidates) {
+ final int uid = UserHandle.getUid(userId, appId);
+ final AndroidPackage androidPackage = mPackageManagerInternal.getPackage(uid);
+ // It will be null if it is not installed on the starting user.
+ if (androidPackage != null) {
+ final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM,
+ uid, androidPackage.getPackageName());
+ synchronized (mLock) {
+ mLastOpScheduleExactAlarm.put(uid, mode);
+ }
+ }
+ }
+ });
}
@Override
@@ -1706,17 +1796,44 @@ public class AlarmManagerService extends SystemService {
@Override
public void opChanged(int op, int uid, String packageName)
throws RemoteException {
- if (op != AppOpsManager.OP_SCHEDULE_EXACT_ALARM) {
+ final int userId = UserHandle.getUserId(uid);
+ if (op != AppOpsManager.OP_SCHEDULE_EXACT_ALARM
+ || !isExactAlarmChangeEnabled(packageName, userId)) {
return;
}
- if (!hasScheduleExactAlarmInternal(packageName, uid)) {
+
+ final boolean requested = mExactAlarmCandidates.contains(
+ UserHandle.getAppId(uid));
+ final boolean denyListed =
+ mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
+
+ final int newMode = mAppOps.checkOpNoThrow(
+ AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName);
+
+ final int oldMode;
+ synchronized (mLock) {
+ final int index = mLastOpScheduleExactAlarm.indexOfKey(uid);
+ if (index < 0) {
+ oldMode = AppOpsManager.opToDefaultMode(
+ AppOpsManager.OP_SCHEDULE_EXACT_ALARM);
+ mLastOpScheduleExactAlarm.put(uid, newMode);
+ } else {
+ oldMode = mLastOpScheduleExactAlarm.valueAt(index);
+ mLastOpScheduleExactAlarm.setValueAt(index, newMode);
+ }
+ }
+
+ final boolean hadPermission = getScheduleExactAlarmState(requested,
+ denyListed, oldMode);
+ final boolean hasPermission = getScheduleExactAlarmState(requested,
+ denyListed, newMode);
+
+ if (hadPermission && !hasPermission) {
mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS,
uid, 0, packageName).sendToTarget();
- } else {
- // TODO(b/187206399) Make sure this won't be sent, if the app
- // already had the appop previously.
+ } else if (!hadPermission && hasPermission) {
sendScheduleExactAlarmPermissionStateChangedBroadcast(
- packageName, UserHandle.getUserId(uid));
+ packageName, userId);
}
}
});
@@ -1889,16 +2006,12 @@ public class AlarmManagerService extends SystemService {
windowLength = INTERVAL_DAY;
} else if ((flags & FLAG_PRIORITIZE) == 0 && windowLength < minAllowedWindow) {
// Prioritized alarms are exempt from minimum window limits.
- if (CompatChanges.isChangeEnabled(
+ if (!isExemptFromMinWindowRestrictions(callingUid) && CompatChanges.isChangeEnabled(
AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, callingPackage,
UserHandle.getUserHandleForUid(callingUid))) {
Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to "
+ minAllowedWindow + "ms.");
windowLength = minAllowedWindow;
- } else {
- // TODO (b/185199076): Remove temporary log to catch breaking apps.
- Slog.wtf(TAG, "Short window " + windowLength + "ms specified by "
- + callingPackage);
}
}
maxElapsed = triggerElapsed + windowLength;
@@ -2256,12 +2369,28 @@ public class AlarmManagerService extends SystemService {
}
}
+ private static boolean getScheduleExactAlarmState(boolean requested, boolean denyListed,
+ int appOpMode) {
+ if (!requested) {
+ return false;
+ }
+ if (appOpMode == AppOpsManager.MODE_DEFAULT) {
+ return !denyListed;
+ }
+ return appOpMode == AppOpsManager.MODE_ALLOWED;
+ }
+
boolean hasScheduleExactAlarmInternal(String packageName, int uid) {
+ // Not using getScheduleExactAlarmState as this can avoid some calls to AppOpsService.
+ // Not using #mLastOpScheduleExactAlarm as it may contain stale values.
+ // No locking needed as all internal containers being queried are immutable.
+
final long start = mStatLogger.getTime();
final boolean hasPermission;
- // No locking needed as all internal containers being queried are immutable.
if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) {
hasPermission = false;
+ } else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
+ hasPermission = false;
} else {
final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid,
packageName);
@@ -2276,6 +2405,13 @@ public class AlarmManagerService extends SystemService {
}
/**
+ * Returns true if the given uid can set window to be as small as it wants.
+ */
+ boolean isExemptFromMinWindowRestrictions(int uid) {
+ return isExemptFromExactAlarmPermission(uid);
+ }
+
+ /**
* Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
* allow-while-idle alarms.
*/
@@ -2368,8 +2504,7 @@ public class AlarmManagerService extends SystemService {
} else if (exact || allowWhileIdle) {
final boolean needsPermission;
boolean lowerQuota;
- if (CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION,
- callingPackage, UserHandle.of(callingUserId))) {
+ if (isExactAlarmChangeEnabled(callingPackage, callingUserId)) {
needsPermission = exact;
lowerQuota = !exact;
idleOptions = exact ? mOptsWithFgs.toBundle() : mOptsWithoutFgs.toBundle();
@@ -2524,6 +2659,11 @@ public class AlarmManagerService extends SystemService {
}
};
+ private static boolean isExactAlarmChangeEnabled(String packageName, int userId) {
+ return CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION,
+ packageName, UserHandle.of(userId));
+ }
+
void dumpImpl(IndentingPrintWriter pw) {
synchronized (mLock) {
pw.println("Current Alarm Manager state:");
@@ -2673,6 +2813,17 @@ public class AlarmManagerService extends SystemService {
pw.println("App ids requesting SCHEDULE_EXACT_ALARM: " + mExactAlarmCandidates);
pw.println();
+ pw.print("Last OP_SCHEDULE_EXACT_ALARM: [");
+ for (int i = 0; i < mLastOpScheduleExactAlarm.size(); i++) {
+ if (i > 0) {
+ pw.print(", ");
+ }
+ UserHandle.formatUid(pw, mLastOpScheduleExactAlarm.keyAt(i));
+ pw.print(":" + AppOpsManager.modeToName(mLastOpScheduleExactAlarm.valueAt(i)));
+ }
+ pw.println("]");
+
+ pw.println();
pw.println("Next alarm clock information: ");
pw.increaseIndent();
final TreeSet<Integer> users = new TreeSet<>();
@@ -3362,30 +3513,58 @@ public class AlarmManagerService extends SystemService {
}
/**
- * Called when some packages are added to the {@link Constants#EXACT_ALARM_DENY_LIST}, as this
- * may cause some of them to lose their permission.
+ * Called when the {@link Constants#EXACT_ALARM_DENY_LIST}, changes with the packages that
+ * either got added or deleted.
+ * These packages may lose or gain the SCHEDULE_EXACT_ALARM permission.
*
- * Note that these packages don't need to be installed on the device, but if they do have an
- * exact alarm scheduled and they lose the permission, this alarm will be canceled.
+ * Note that these packages don't need to be installed on the device, but if they are and they
+ * do undergo a permission change, we will handle them appropriately.
*
+ * This should not be called with the lock held as it calls out to other services.
* This is not expected to get called frequently.
*/
- void handlePackagesAddedToExactAlarmsDenyListLocked(ArraySet<String> packageNames) {
- Slog.w(TAG, "Packages " + packageNames + " added to the exact alarm deny list.");
- final Predicate<Alarm> whichAlarms = a -> {
- if (!packageNames.contains(a.packageName) || a.windowLength != 0) {
- return false;
- }
- if (!CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION,
- a.packageName, UserHandle.getUserHandleForUid(a.uid))) {
- return false;
- }
- if (a.alarmClock == null && isExemptFromExactAlarmPermission(a.uid)) {
- return false;
+ void handleChangesToExactAlarmDenyList(ArraySet<String> changedPackages, boolean added) {
+ Slog.w(TAG, "Packages " + changedPackages + (added ? " added to" : " removed from")
+ + " the exact alarm deny list.");
+
+ final int[] startedUserIds = mActivityManagerInternal.getStartedUserIds();
+
+ for (int i = 0; i < changedPackages.size(); i++) {
+ final String changedPackage = changedPackages.valueAt(i);
+ for (final int userId : startedUserIds) {
+ final int uid = mPackageManagerInternal.getPackageUid(changedPackage, 0, userId);
+ if (uid <= 0) {
+ continue;
+ }
+ if (!isExactAlarmChangeEnabled(changedPackage, userId)) {
+ continue;
+ }
+ final int appOpMode;
+ synchronized (mLock) {
+ appOpMode = mLastOpScheduleExactAlarm.get(uid,
+ AppOpsManager.opToDefaultMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM));
+ }
+ final boolean requested = mExactAlarmCandidates.contains(UserHandle.getAppId(uid));
+
+ // added: true => package was added to the deny list
+ // added: false => package was removed from the deny list
+ final boolean hadPermission = getScheduleExactAlarmState(requested, !added,
+ appOpMode);
+ final boolean hasPermission = getScheduleExactAlarmState(requested, added,
+ appOpMode);
+
+ if (hadPermission == hasPermission) {
+ continue;
+ }
+ if (added) {
+ synchronized (mLock) {
+ removeExactAlarmsOnPermissionRevokedLocked(uid, changedPackage);
+ }
+ } else {
+ sendScheduleExactAlarmPermissionStateChangedBroadcast(changedPackage, userId);
+ }
}
- return !hasScheduleExactAlarmInternal(a.packageName, a.uid);
- };
- removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
+ }
}
/**
@@ -3396,9 +3575,7 @@ public class AlarmManagerService extends SystemService {
*/
void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) {
Slog.w(TAG, "Package " + packageName + ", uid " + uid + " lost SCHEDULE_EXACT_ALARM!");
- if (!CompatChanges.isChangeEnabled(
- AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION,
- packageName, UserHandle.getUserHandleForUid(uid))) {
+ if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
return;
}
@@ -3409,6 +3586,11 @@ public class AlarmManagerService extends SystemService {
return false;
};
removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
+
+ if (mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) {
+ PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
+ "schedule_exact_alarm revoked");
+ }
}
private void removeAlarmsInternalLocked(Predicate<Alarm> whichAlarms, int reason) {
@@ -3535,6 +3717,11 @@ public class AlarmManagerService extends SystemService {
mRemovalHistory.removeAt(i);
}
}
+ for (int i = mLastOpScheduleExactAlarm.size() - 1; i >= 0; i--) {
+ if (UserHandle.getUserId(mLastOpScheduleExactAlarm.keyAt(i)) == userHandle) {
+ mLastOpScheduleExactAlarm.removeAt(i);
+ }
+ }
}
void interactiveStateChangedLocked(boolean interactive) {
@@ -4091,8 +4278,9 @@ public class AlarmManagerService extends SystemService {
public static final int CHARGING_STATUS_CHANGED = 6;
public static final int REMOVE_FOR_CANCELED = 7;
public static final int REMOVE_EXACT_ALARMS = 8;
- public static final int EXACT_ALARM_DENY_LIST_CHANGED = 9;
- public static final int REFRESH_EXACT_ALARM_CANDIDATES = 10;
+ public static final int EXACT_ALARM_DENY_LIST_PACKAGES_ADDED = 9;
+ public static final int EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED = 10;
+ public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11;
AlarmHandler() {
super(Looper.myLooper());
@@ -4179,10 +4367,11 @@ public class AlarmManagerService extends SystemService {
removeExactAlarmsOnPermissionRevokedLocked(uid, packageName);
}
break;
- case EXACT_ALARM_DENY_LIST_CHANGED:
- synchronized (mLock) {
- handlePackagesAddedToExactAlarmsDenyListLocked((ArraySet<String>) msg.obj);
- }
+ case EXACT_ALARM_DENY_LIST_PACKAGES_ADDED:
+ handleChangesToExactAlarmDenyList((ArraySet<String>) msg.obj, true);
+ break;
+ case EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED:
+ handleChangesToExactAlarmDenyList((ArraySet<String>) msg.obj, false);
break;
case REFRESH_EXACT_ALARM_CANDIDATES:
refreshExactAlarmCandidates();
@@ -4349,6 +4538,7 @@ public class AlarmManagerService extends SystemService {
case Intent.ACTION_UID_REMOVED:
mLastPriorityAlarmDispatch.delete(uid);
mRemovalHistory.delete(uid);
+ mLastOpScheduleExactAlarm.delete(uid);
return;
case Intent.ACTION_PACKAGE_REMOVED:
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
diff --git a/apex/media/framework/java/android/media/MediaSession2.java b/apex/media/framework/java/android/media/MediaSession2.java
index 7697359e7caf..e76d61cf8965 100644
--- a/apex/media/framework/java/android/media/MediaSession2.java
+++ b/apex/media/framework/java/android/media/MediaSession2.java
@@ -469,7 +469,9 @@ public class MediaSession2 implements AutoCloseable {
}
mCallbackExecutor.execute(() -> {
if (!controllerInfo.removeRequestedCommandSeqNumber(seq)) {
- resultReceiver.send(RESULT_INFO_SKIPPED, null);
+ if (resultReceiver != null) {
+ resultReceiver.send(RESULT_INFO_SKIPPED, null);
+ }
return;
}
Session2Command.Result result = mCallback.onSessionCommand(
diff --git a/api/Android.bp b/api/Android.bp
index db1f64c57e2c..a84e6a6cb031 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -69,7 +69,10 @@ genrule {
dest: "current.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/public/api",
dest: "android.txt",
},
@@ -151,7 +154,10 @@ genrule {
dest: "removed.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/public/api",
dest: "removed.txt",
},
@@ -187,7 +193,10 @@ genrule {
dest: "system-current.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/system/api",
dest: "android.txt",
},
@@ -242,7 +251,10 @@ genrule {
dest: "system-removed.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/system/api",
dest: "removed.txt",
},
@@ -279,7 +291,10 @@ genrule {
dest: "module-lib-current.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/module-lib/api",
dest: "android.txt",
},
@@ -336,7 +351,10 @@ genrule {
dest: "module-lib-removed.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/module-lib/api",
dest: "removed.txt",
},
@@ -377,7 +395,10 @@ genrule {
dest: "system-server-current.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/system-server/api",
dest: "android.txt",
},
@@ -401,7 +422,10 @@ genrule {
dest: "system-server-removed.txt",
},
{
- targets: ["sdk", "win_sdk"],
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
dir: "apistubs/android/system-server/api",
dest: "removed.txt",
},
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
index 0eff83c99282..a1575173ded6 100644
--- a/cmds/app_process/Android.bp
+++ b/cmds/app_process/Android.bp
@@ -29,7 +29,16 @@ cc_binary {
},
},
- ldflags: ["-Wl,--export-dynamic"],
+ // Symbols exported from the executable in .dynsym interpose symbols in every
+ // linker namespace, including an app's classloader namespace. Provide this
+ // version script to prevent unwanted interposition.
+ //
+ // By default, the static linker doesn't export most of an executable's symbols,
+ // but it will export a symbol that appears to override a symbol in a needed DSO.
+ // This commonly happens with C++ vaguely-linked entities, such as template
+ // functions or type_info variables. Hence, a version script is needed even for
+ // an executable.
+ version_script: "version-script.txt",
shared_libs: [
"libandroid_runtime",
diff --git a/cmds/app_process/version-script.txt b/cmds/app_process/version-script.txt
new file mode 100644
index 000000000000..a98066a67675
--- /dev/null
+++ b/cmds/app_process/version-script.txt
@@ -0,0 +1,4 @@
+{
+ local:
+ *;
+};
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 5fa75dd68ce0..80664ed0816f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1113,6 +1113,10 @@ package android.hardware.camera2 {
method @RequiresPermission(android.Manifest.permission.CAMERA_OPEN_CLOSE_LISTENER) public void onCameraOpened(@NonNull String, @NonNull String);
}
+ public abstract class CameraMetadata<TKey> {
+ field public static final int SENSOR_TEST_PATTERN_MODE_BLACK = 5; // 0x5
+ }
+
}
package android.hardware.devicestate {
@@ -2719,6 +2723,7 @@ package android.view {
public final class InputDevice implements android.os.Parcelable {
method @RequiresPermission("android.permission.DISABLE_INPUT_DEVICE") public void disable();
method @RequiresPermission("android.permission.DISABLE_INPUT_DEVICE") public void enable();
+ field public static final int ACCESSIBILITY_DEVICE_ID = -2; // 0xfffffffe
}
public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable {
@@ -3185,6 +3190,7 @@ package android.window {
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public android.window.WindowContainerToken getImeTarget(int);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]);
+ method @BinderThread public void onAppSplashScreenViewRemoved(int);
method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo, @NonNull android.view.SurfaceControl);
method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 854c9f2a5b3a..db5dcc5c264b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3866,9 +3866,26 @@ public class Activity extends ContextThemeWrapper
}
/**
- * Called when the activity has detected the user's press of the back
- * key. The default implementation simply finishes the current activity,
- * but you can override this to do whatever you want.
+ * Called when the activity has detected the user's press of the back key. The default
+ * implementation depends on the platform version:
+ *
+ * <ul>
+ * <li>On platform versions prior to {@link android.os.Build.VERSION_CODES#S}, it
+ * finishes the current activity, but you can override this to do whatever you want.
+ *
+ * <li><p>Starting with platform version {@link android.os.Build.VERSION_CODES#S}, for
+ * activities that are the root activity of the task and also declare an
+ * {@link android.content.IntentFilter} with {@link Intent#ACTION_MAIN} and
+ * {@link Intent#CATEGORY_LAUNCHER} in the manifest, the current activity and its
+ * task will be moved to the back of the activity stack instead of being finished.
+ * Other activities will simply be finished.
+ *
+ * <p>If you target version {@link android.os.Build.VERSION_CODES#S} or later and
+ * override this method, it is strongly recommended to call through to the superclass
+ * implementation after you finish handling navigation within the app.
+ * </ul>
+ *
+ * @see #moveTaskToBack(boolean)
*/
public void onBackPressed() {
if (mActionBar != null && mActionBar.collapseActionView()) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 7cb8bc0d80fd..317e51c27d90 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -254,6 +254,9 @@ public abstract class ActivityManagerInternal {
/** Returns the current user id. */
public abstract int getCurrentUserId();
+ /** Returns the currently started user ids. */
+ public abstract int[] getStartedUserIds();
+
/** Returns true if the user is running. */
public abstract boolean isUserRunning(@UserIdInt int userId, int flags);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 1ce598b5fa18..8e1f263ebf03 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -419,7 +419,7 @@ public class ActivityOptions {
private IBinder mLaunchCookie;
private IRemoteTransition mRemoteTransition;
private boolean mOverrideTaskTransition;
- private int mSplashScreenThemeResId;
+ private String mSplashScreenThemeResName;
@SplashScreen.SplashScreenStyle
private int mSplashScreenStyle;
private boolean mRemoveWithTaskOrganizer;
@@ -1174,7 +1174,7 @@ public class ActivityOptions {
mRemoteTransition = IRemoteTransition.Stub.asInterface(opts.getBinder(
KEY_REMOTE_TRANSITION));
mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
- mSplashScreenThemeResId = opts.getInt(KEY_SPLASH_SCREEN_THEME);
+ mSplashScreenThemeResName = opts.getString(KEY_SPLASH_SCREEN_THEME);
mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
@@ -1368,8 +1368,9 @@ public class ActivityOptions {
* Gets whether the activity want to be launched as other theme for the splash screen.
* @hide
*/
- public int getSplashScreenThemeResId() {
- return mSplashScreenThemeResId;
+ @Nullable
+ public String getSplashScreenThemeResName() {
+ return mSplashScreenThemeResName;
}
/**
@@ -1945,8 +1946,8 @@ public class ActivityOptions {
if (mOverrideTaskTransition) {
b.putBoolean(KEY_OVERRIDE_TASK_TRANSITION, mOverrideTaskTransition);
}
- if (mSplashScreenThemeResId != 0) {
- b.putInt(KEY_SPLASH_SCREEN_THEME, mSplashScreenThemeResId);
+ if (mSplashScreenThemeResName != null && !mSplashScreenThemeResName.isEmpty()) {
+ b.putString(KEY_SPLASH_SCREEN_THEME, mSplashScreenThemeResName);
}
if (mRemoveWithTaskOrganizer) {
b.putBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER, mRemoveWithTaskOrganizer);
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index c3272c1a770d..7a806bdf473d 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -45,6 +45,7 @@ public final class AutomaticZenRule implements Parcelable {
private long creationTime;
private ZenPolicy mZenPolicy;
private boolean mModified = false;
+ private String mPkg;
/**
* Creates an automatic zen rule.
@@ -123,6 +124,7 @@ public final class AutomaticZenRule implements Parcelable {
creationTime = source.readLong();
mZenPolicy = source.readParcelable(null);
mModified = source.readInt() == ENABLED;
+ mPkg = source.readString();
}
/**
@@ -244,6 +246,20 @@ public final class AutomaticZenRule implements Parcelable {
this.configurationActivity = componentName;
}
+ /**
+ * @hide
+ */
+ public void setPackageName(String pkgName) {
+ mPkg = pkgName;
+ }
+
+ /**
+ * @hide
+ */
+ public String getPackageName() {
+ return mPkg;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -265,6 +281,7 @@ public final class AutomaticZenRule implements Parcelable {
dest.writeLong(creationTime);
dest.writeParcelable(mZenPolicy, 0);
dest.writeInt(mModified ? ENABLED : DISABLED);
+ dest.writeString(mPkg);
}
@Override
@@ -273,6 +290,7 @@ public final class AutomaticZenRule implements Parcelable {
.append("enabled=").append(enabled)
.append(",name=").append(name)
.append(",interruptionFilter=").append(interruptionFilter)
+ .append(",pkg=").append(mPkg)
.append(",conditionId=").append(conditionId)
.append(",owner=").append(owner)
.append(",configActivity=").append(configurationActivity)
@@ -294,13 +312,14 @@ public final class AutomaticZenRule implements Parcelable {
&& Objects.equals(other.owner, owner)
&& Objects.equals(other.mZenPolicy, mZenPolicy)
&& Objects.equals(other.configurationActivity, configurationActivity)
+ && Objects.equals(other.mPkg, mPkg)
&& other.creationTime == creationTime;
}
@Override
public int hashCode() {
return Objects.hash(enabled, name, interruptionFilter, conditionId, owner,
- configurationActivity, mZenPolicy, mModified, creationTime);
+ configurationActivity, mZenPolicy, mModified, creationTime, mPkg);
}
public static final @android.annotation.NonNull Parcelable.Creator<AutomaticZenRule> CREATOR
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index f33adb3c01d1..098492c8234b 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -207,7 +207,7 @@ interface INotificationManager
void setNotificationPolicyAccessGrantedForUser(String pkg, int userId, boolean granted);
AutomaticZenRule getAutomaticZenRule(String id);
List<ZenModeConfig.ZenRule> getZenRules();
- String addAutomaticZenRule(in AutomaticZenRule automaticZenRule);
+ String addAutomaticZenRule(in AutomaticZenRule automaticZenRule, String pkg);
boolean updateAutomaticZenRule(String id, in AutomaticZenRule automaticZenRule);
boolean removeAutomaticZenRule(String id);
boolean removeAutomaticZenRules(String packageName);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 62b5ec872320..9ed76c1c13d1 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -932,6 +932,21 @@ public final class LoadedApk {
boolean registerAppInfoToArt = false;
if (mDefaultClassLoader == null) {
+ // Setup the dex reporter to notify package manager
+ // of any relevant dex loads. The idle maintenance job will use the information
+ // reported to optimize the loaded dex files.
+ // Note that we only need one global reporter per app.
+ // Make sure we do this before creating the main app classloader for the first time
+ // so that we can capture the complete application startup.
+ //
+ // We should not do this in a zygote context (where mActivityThread will be null),
+ // thus we'll guard against it.
+ // Also, the system server reporter (SystemServerDexLoadReporter) is already registered
+ // when system server starts, so we don't need to do it here again.
+ if (mActivityThread != null && !ActivityThread.isSystem()) {
+ BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
+ }
+
// Temporarily disable logging of disk reads on the Looper thread
// as this is early and necessary.
StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
@@ -1047,14 +1062,6 @@ public final class LoadedApk {
}
private void registerAppInfoToArt() {
- // Setup the dex reporter to notify package manager
- // of any relevant dex loads. The idle maintenance job will use the information
- // reported to optimize the loaded dex files.
- // Note that we only need one global reporter per app.
- // Make sure we do this before invoking app code for the first time so that we
- // can capture the complete application startup.
- BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
-
// Only set up profile support if the loaded apk has the same uid as the
// current process.
// Currently, we do not support profiling across different apps.
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index da03a3da820a..ccf1edb3fecc 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1182,10 +1182,12 @@ public class NotificationManager {
List<ZenModeConfig.ZenRule> rules = service.getZenRules();
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
for (ZenModeConfig.ZenRule rule : rules) {
- ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
+ AutomaticZenRule azr = new AutomaticZenRule(rule.name, rule.component,
rule.configurationActivity, rule.conditionId, rule.zenPolicy,
zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
- rule.creationTime));
+ rule.creationTime);
+ azr.setPackageName(rule.pkg);
+ ruleMap.put(rule.id, azr);
}
return ruleMap;
} catch (RemoteException e) {
@@ -1226,7 +1228,7 @@ public class NotificationManager {
public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
INotificationManager service = getService();
try {
- return service.addAutomaticZenRule(automaticZenRule);
+ return service.addAutomaticZenRule(automaticZenRule, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index a9bec98ce405..a0d2977cf09a 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -18,7 +18,6 @@ package android.app.admin;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.admin.DevicePolicyManager.OperationSafetyReason;
import android.content.ComponentName;
import android.content.Intent;
import android.os.UserHandle;
@@ -256,13 +255,4 @@ public abstract class DevicePolicyManagerInternal {
* {@link #supportsResetOp(int)} is true.
*/
public abstract void resetOp(int op, String packageName, @UserIdInt int userId);
-
- /**
- * Notifies the system that an unsafe operation reason has changed.
- *
- * @throws IllegalArgumentException if {@code checker} is not the same as set on
- * {@code DevicePolicyManagerService}.
- */
- public abstract void notifyUnsafeOperationStateChanged(DevicePolicySafetyChecker checker,
- @OperationSafetyReason int reason, boolean isSafe);
}
diff --git a/core/java/android/app/admin/DevicePolicyManagerLiteInternal.java b/core/java/android/app/admin/DevicePolicyManagerLiteInternal.java
new file mode 100644
index 000000000000..ccb99470d372
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyManagerLiteInternal.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.app.admin.DevicePolicyManager.OperationSafetyReason;
+
+/**
+ * Device policy manager local system service interface for methods that don't require the
+ * {@code device_admin} feature.
+ *
+ * Maintenance note: if you need to expose information from DPMS to lower level services such as
+ * PM/UM/AM/etc, then exposing it from DevicePolicyManagerInternal is not safe because it may cause
+ * lock order inversion. Consider using {@link DevicePolicyCache} instead.
+ *
+ * @hide Only for use within the system server.
+ */
+public interface DevicePolicyManagerLiteInternal {
+
+ /**
+ * Notifies the system that an unsafe operation reason has changed.
+ *
+ * @throws IllegalArgumentException if {@code checker} is not the same as set on
+ * {@code DevicePolicyManagerService.setDevicePolicySafetyChecker()}.
+ */
+ void notifyUnsafeOperationStateChanged(DevicePolicySafetyChecker checker,
+ @OperationSafetyReason int reason, boolean isSafe);
+}
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index fe99f8532aaa..8a6c85d54896 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -48,6 +48,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.DataUnit;
import android.util.Log;
@@ -214,6 +215,10 @@ public class NetworkStatsManager {
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -255,6 +260,10 @@ public class NetworkStatsManager {
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -300,6 +309,10 @@ public class NetworkStatsManager {
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -388,6 +401,10 @@ public class NetworkStatsManager {
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -450,6 +467,10 @@ public class NetworkStatsManager {
* null} value when querying for the mobile network type to receive usage
* for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param startTime Start of period. Defined in terms of "Unix time", see
* {@link java.lang.System#currentTimeMillis}.
* @param endTime End of period. Defined in terms of "Unix time", see
@@ -531,6 +552,10 @@ public class NetworkStatsManager {
* null} value when registering for the mobile network type to receive
* notifications for all mobile networks. For additional details see {@link
* TelephonyManager#getSubscriberId()}.
+ * <p>Starting with API level 31, calling apps can provide a
+ * {@code subscriberId} with wifi network type to receive usage for
+ * wifi networks which is under the given subscription if applicable.
+ * Otherwise, pass {@code null} when querying all wifi networks.
* @param thresholdBytes Threshold in bytes to be notified on.
* @param callback The {@link UsageCallback} that the system will call when data usage
* has exceeded the specified threshold.
@@ -644,7 +669,7 @@ public class NetworkStatsManager {
: NetworkTemplate.buildTemplateMobileAll(subscriberId);
break;
case ConnectivityManager.TYPE_WIFI:
- template = subscriberId == null
+ template = TextUtils.isEmpty(subscriberId)
? NetworkTemplate.buildTemplateWifiWildcard()
: NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
subscriberId);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 054b63fbad50..ded5e6e27a68 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -17,6 +17,8 @@
package android.bluetooth;
+import static java.util.Objects.requireNonNull;
+
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -62,8 +64,6 @@ import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
-import com.android.internal.util.Preconditions;
-
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -3314,8 +3314,8 @@ public final class BluetoothAdapter {
*/
WrappedOobDataCallback(@NonNull OobDataCallback callback,
@NonNull @CallbackExecutor Executor executor) {
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(executor);
+ requireNonNull(callback);
+ requireNonNull(executor);
mCallback = callback;
mExecutor = executor;
}
@@ -3385,7 +3385,7 @@ public final class BluetoothAdapter {
!= BluetoothDevice.TRANSPORT_LE) {
throw new IllegalArgumentException("Invalid transport '" + transport + "'!");
}
- Preconditions.checkNotNull(callback);
+ requireNonNull(callback);
if (!isEnabled()) {
Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!");
callback.onError(BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED);
@@ -3522,7 +3522,7 @@ public final class BluetoothAdapter {
* @hide
*/
public static boolean isAddressRandomStatic(@NonNull String address) {
- Preconditions.checkNotNull(address);
+ requireNonNull(address);
return checkBluetoothAddress(address)
&& (Integer.parseInt(address.split(":")[5], 16) & 0b11) == 0b11;
}
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 2dfa91dcba3e..4e5ede74ce46 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import static java.util.Objects.requireNonNull;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -23,8 +25,6 @@ import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import com.android.internal.util.Preconditions;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -214,7 +214,7 @@ public final class OobData implements Parcelable {
@NonNull
@SystemApi
public LeBuilder setDeviceName(@NonNull byte[] deviceName) {
- Preconditions.checkNotNull(deviceName);
+ requireNonNull(deviceName);
this.mDeviceName = deviceName;
return this;
}
@@ -308,8 +308,8 @@ public final class OobData implements Parcelable {
@SystemApi
public LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
@LeRole int leDeviceRole) {
- Preconditions.checkNotNull(confirmationHash);
- Preconditions.checkNotNull(deviceAddressWithType);
+ requireNonNull(confirmationHash);
+ requireNonNull(deviceAddressWithType);
if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
throw new IllegalArgumentException("confirmationHash must be "
+ OobData.CONFIRMATION_OCTETS + " octets in length.");
@@ -344,7 +344,7 @@ public final class OobData implements Parcelable {
@NonNull
@SystemApi
public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) {
- Preconditions.checkNotNull(leTemporaryKey);
+ requireNonNull(leTemporaryKey);
if (leTemporaryKey.length != LE_TK_OCTETS) {
throw new IllegalArgumentException("leTemporaryKey must be "
+ LE_TK_OCTETS + " octets in length.");
@@ -366,7 +366,7 @@ public final class OobData implements Parcelable {
@NonNull
@SystemApi
public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
- Preconditions.checkNotNull(randomizerHash);
+ requireNonNull(randomizerHash);
if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
throw new IllegalArgumentException("randomizerHash must be "
+ OobData.RANDOMIZER_OCTETS + " octets in length.");
@@ -534,9 +534,9 @@ public final class OobData implements Parcelable {
@SystemApi
public ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
@NonNull byte[] deviceAddressWithType) {
- Preconditions.checkNotNull(confirmationHash);
- Preconditions.checkNotNull(classicLength);
- Preconditions.checkNotNull(deviceAddressWithType);
+ requireNonNull(confirmationHash);
+ requireNonNull(classicLength);
+ requireNonNull(deviceAddressWithType);
if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
throw new IllegalArgumentException("confirmationHash must be "
+ OobData.CONFIRMATION_OCTETS + " octets in length.");
@@ -567,7 +567,7 @@ public final class OobData implements Parcelable {
@NonNull
@SystemApi
public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
- Preconditions.checkNotNull(randomizerHash);
+ requireNonNull(randomizerHash);
if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
throw new IllegalArgumentException("randomizerHash must be "
+ OobData.RANDOMIZER_OCTETS + " octets in length.");
@@ -592,7 +592,7 @@ public final class OobData implements Parcelable {
@NonNull
@SystemApi
public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) {
- Preconditions.checkNotNull(deviceName);
+ requireNonNull(deviceName);
this.mDeviceName = deviceName;
return this;
}
@@ -617,7 +617,7 @@ public final class OobData implements Parcelable {
@NonNull
@SystemApi
public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
- Preconditions.checkNotNull(classOfDevice);
+ requireNonNull(classOfDevice);
if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
throw new IllegalArgumentException("classOfDevice must be "
+ OobData.CLASS_OF_DEVICE_OCTETS + " octets in length.");
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index dfef47ddc16e..cb3bf297670f 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -16,6 +16,8 @@
package android.bluetooth.le;
+import static java.util.Objects.requireNonNull;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -27,7 +29,6 @@ import android.os.ParcelUuid;
import android.os.Parcelable;
import com.android.internal.util.BitUtils;
-import com.android.internal.util.Preconditions;
import java.util.Arrays;
import java.util.List;
@@ -646,7 +647,7 @@ public final class ScanFilter implements Parcelable {
public Builder setDeviceAddress(@NonNull String deviceAddress,
@AddressType int addressType,
@NonNull byte[] irk) {
- Preconditions.checkNotNull(irk);
+ requireNonNull(irk);
if (irk.length != LEN_IRK_OCTETS) {
throw new IllegalArgumentException("'irk' is invalid length!");
}
@@ -678,7 +679,7 @@ public final class ScanFilter implements Parcelable {
@Nullable byte[] irk) {
// Make sure our deviceAddress is valid!
- Preconditions.checkNotNull(deviceAddress);
+ requireNonNull(deviceAddress);
if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
throw new IllegalArgumentException("invalid device address " + deviceAddress);
}
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index 63f93bfa24e5..806091e2158d 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -423,7 +423,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
shortLabelResName, longLabel, longLabelResId, longLabelResName, disabledMessage,
disabledMessageResId, disabledMessageResName, categoriesSet, intents, rank, extras,
getCreationTimestampMillis(), flags, iconResId, iconResName, bitmapPath, iconUri,
- disabledReason, persons, locusId, 0);
+ disabledReason, persons, locusId, null);
si.setImplicitRank(implicitRank);
if ((implicitRank & ShortcutInfo.RANK_CHANGED_BIT) != 0) {
si.setRankChanged();
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 32fc74f60d15..b0ce6a55e9ba 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -63,4 +63,5 @@ interface IPackageInstaller {
void bypassNextStagedInstallerCheck(boolean value);
void setAllowUnlimitedSilentUpdates(String installerPackageName);
+ void setSilentUpdatesThrottleTime(long throttleTimeInSeconds);
}
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 76712b5ce2dc..a264bebb5d88 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -449,7 +449,7 @@ public final class ShortcutInfo implements Parcelable {
private int mDisabledReason;
- private int mStartingThemeResId;
+ @Nullable private String mStartingThemeResName;
private ShortcutInfo(Builder b) {
mUserId = b.mContext.getUserId();
@@ -478,8 +478,9 @@ public final class ShortcutInfo implements Parcelable {
mExtras = b.mExtras;
mLocusId = b.mLocusId;
+ mStartingThemeResName = b.mStartingThemeResId != 0
+ ? b.mContext.getResources().getResourceName(b.mStartingThemeResId) : null;
updateTimestamp();
- mStartingThemeResId = b.mStartingThemeResId;
}
/**
@@ -626,7 +627,7 @@ public final class ShortcutInfo implements Parcelable {
// Set this bit.
mFlags |= FLAG_KEY_FIELDS_ONLY;
}
- mStartingThemeResId = source.mStartingThemeResId;
+ mStartingThemeResName = source.mStartingThemeResName;
}
/**
@@ -950,8 +951,8 @@ public final class ShortcutInfo implements Parcelable {
if (source.mLocusId != null) {
mLocusId = source.mLocusId;
}
- if (source.mStartingThemeResId != 0) {
- mStartingThemeResId = source.mStartingThemeResId;
+ if (source.mStartingThemeResName != null && !source.mStartingThemeResName.isEmpty()) {
+ mStartingThemeResName = source.mStartingThemeResName;
}
}
@@ -1454,11 +1455,12 @@ public final class ShortcutInfo implements Parcelable {
}
/**
- * Returns the theme resource id used for the splash screen.
+ * Returns the theme resource name used for the splash screen.
* @hide
*/
- public int getStartingThemeResId() {
- return mStartingThemeResId;
+ @Nullable
+ public String getStartingThemeResName() {
+ return mStartingThemeResName;
}
/** @hide -- old signature, the internal code still uses it. */
@@ -2182,7 +2184,7 @@ public final class ShortcutInfo implements Parcelable {
mPersons = source.readParcelableArray(cl, Person.class);
mLocusId = source.readParcelable(cl);
mIconUri = source.readString8();
- mStartingThemeResId = source.readInt();
+ mStartingThemeResName = source.readString8();
}
@Override
@@ -2234,7 +2236,7 @@ public final class ShortcutInfo implements Parcelable {
dest.writeParcelableArray(mPersons, flags);
dest.writeParcelable(mLocusId, flags);
dest.writeString8(mIconUri);
- dest.writeInt(mStartingThemeResId);
+ dest.writeString8(mStartingThemeResName);
}
public static final @NonNull Creator<ShortcutInfo> CREATOR =
@@ -2391,10 +2393,10 @@ public final class ShortcutInfo implements Parcelable {
sb.append("disabledReason=");
sb.append(getDisabledReasonDebugString(mDisabledReason));
- if (mStartingThemeResId != 0) {
+ if (mStartingThemeResName != null && !mStartingThemeResName.isEmpty()) {
addIndentOrComma(sb, indent);
- sb.append("SplashScreenThemeResId=");
- sb.append(Integer.toHexString(mStartingThemeResId));
+ sb.append("SplashScreenThemeResName=");
+ sb.append(mStartingThemeResName);
}
addIndentOrComma(sb, indent);
@@ -2482,7 +2484,8 @@ public final class ShortcutInfo implements Parcelable {
Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
long lastChangedTimestamp,
int flags, int iconResId, String iconResName, String bitmapPath, String iconUri,
- int disabledReason, Person[] persons, LocusId locusId, int startingThemeResId) {
+ int disabledReason, Person[] persons, LocusId locusId,
+ @Nullable String startingThemeResName) {
mUserId = userId;
mId = id;
mPackageName = packageName;
@@ -2511,6 +2514,6 @@ public final class ShortcutInfo implements Parcelable {
mDisabledReason = disabledReason;
mPersons = persons;
mLocusId = locusId;
- mStartingThemeResId = startingThemeResId;
+ mStartingThemeResName = startingThemeResName;
}
}
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 233abf36131b..3ed5c6457fa5 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -74,7 +74,7 @@ public abstract class ShortcutServiceInternal {
/**
* Get the theme res ID of the starting window, it can be 0 if not specified.
*/
- public abstract int getShortcutStartingThemeResId(int launcherUserId,
+ public abstract @Nullable String getShortcutStartingThemeResName(int launcherUserId,
@NonNull String callingPackage, @NonNull String packageName, @NonNull String shortcutId,
int userId);
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 1e650a807cec..154d9234d00c 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -493,6 +493,7 @@ public class ApkLiteParseUtils {
if (targetResult.isError()) {
return input.error(targetResult);
}
+ targetSdkVersion = targetResult.getResult();
ParseResult<Integer> minResult = ParsingPackageUtils.computeMinSdkVersion(
minVer, minCode, ParsingPackageUtils.SDK_VERSION,
@@ -500,8 +501,6 @@ public class ApkLiteParseUtils {
if (minResult.isError()) {
return input.error(minResult);
}
-
- targetSdkVersion = targetResult.getResult();
minSdkVersion = minResult.getResult();
}
}
diff --git a/core/java/android/hardware/biometrics/BiometricAuthenticator.java b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
index a0027077e1a3..60a365835e2e 100644
--- a/core/java/android/hardware/biometrics/BiometricAuthenticator.java
+++ b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
@@ -63,6 +63,11 @@ public interface BiometricAuthenticator {
*/
int TYPE_FACE = 1 << 3;
+ /**
+ * @hide
+ */
+ int TYPE_ANY_BIOMETRIC = TYPE_FINGERPRINT | TYPE_IRIS | TYPE_FACE;
+
@IntDef(flag = true, value = {
TYPE_NONE,
TYPE_CREDENTIAL,
diff --git a/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java b/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java
new file mode 100644
index 000000000000..4ec6f0d2509e
--- /dev/null
+++ b/core/java/android/hardware/biometrics/ParentalControlsUtilsInternal.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Build;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+/**
+ * "Base" functionality. For settings-specific functionality (which may rely on this base
+ * functionality), see {@link com.android.settings.biometrics.ParentalControlsUtils}
+ * @hide
+ */
+public class ParentalControlsUtilsInternal {
+
+ private static final String TEST_ALWAYS_REQUIRE_CONSENT =
+ "android.hardware.biometrics.ParentalControlsUtilsInternal.always_require_consent";
+
+ public static boolean isTestModeEnabled(@NonNull Context context) {
+ if (Build.IS_USERDEBUG || Build.IS_ENG) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ TEST_ALWAYS_REQUIRE_CONSENT, 0) != 0;
+ }
+ return false;
+ }
+
+ public static boolean parentConsentRequired(@NonNull Context context,
+ @NonNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality,
+ @NonNull UserHandle userHandle) {
+ if (isTestModeEnabled(context)) {
+ return true;
+ }
+
+ return parentConsentRequired(dpm, modality, userHandle);
+ }
+
+ /**
+ * @return true if parental consent is required in order for biometric sensors to be used.
+ */
+ public static boolean parentConsentRequired(@NonNull DevicePolicyManager dpm,
+ @BiometricAuthenticator.Modality int modality, @NonNull UserHandle userHandle) {
+ final ComponentName cn = getSupervisionComponentName(dpm, userHandle);
+ if (cn == null) {
+ return false;
+ }
+
+ final int keyguardDisabledFeatures = dpm.getKeyguardDisabledFeatures(cn);
+ final boolean dpmFpDisabled = containsFlag(keyguardDisabledFeatures,
+ DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
+ final boolean dpmFaceDisabled = containsFlag(keyguardDisabledFeatures,
+ DevicePolicyManager.KEYGUARD_DISABLE_FACE);
+ final boolean dpmIrisDisabled = containsFlag(keyguardDisabledFeatures,
+ DevicePolicyManager.KEYGUARD_DISABLE_IRIS);
+
+ final boolean consentRequired;
+ if (containsFlag(modality, BiometricAuthenticator.TYPE_FINGERPRINT) && dpmFpDisabled) {
+ consentRequired = true;
+ } else if (containsFlag(modality, BiometricAuthenticator.TYPE_FACE) && dpmFaceDisabled) {
+ consentRequired = true;
+ } else if (containsFlag(modality, BiometricAuthenticator.TYPE_IRIS) && dpmIrisDisabled) {
+ consentRequired = true;
+ } else {
+ consentRequired = false;
+ }
+
+ return consentRequired;
+ }
+
+ @Nullable
+ public static ComponentName getSupervisionComponentName(@NonNull DevicePolicyManager dpm,
+ @NonNull UserHandle userHandle) {
+ return dpm.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle);
+ }
+
+ private static boolean containsFlag(int haystack, int needle) {
+ return (haystack & needle) != 0;
+ }
+}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index d4da3b9526c3..9501994fe38a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -17,6 +17,7 @@
package android.hardware.camera2;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.PublicKey;
@@ -2922,10 +2923,10 @@ public abstract class CameraMetadata<TKey> {
* respective color channel provided in
* {@link CaptureRequest#SENSOR_TEST_PATTERN_DATA android.sensor.testPatternData}.</p>
* <p>For example:</p>
- * <pre><code>android.control.testPatternData = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
+ * <pre><code>{@link CaptureRequest#SENSOR_TEST_PATTERN_DATA android.sensor.testPatternData} = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
* </code></pre>
* <p>All green pixels are 100% green. All red/blue pixels are black.</p>
- * <pre><code>android.control.testPatternData = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
+ * <pre><code>{@link CaptureRequest#SENSOR_TEST_PATTERN_DATA android.sensor.testPatternData} = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
* </code></pre>
* <p>All red pixels are 100% red. Only the odd green pixels
* are 100% green. All blue pixels are 100% black.</p>
@@ -3002,6 +3003,20 @@ public abstract class CameraMetadata<TKey> {
public static final int SENSOR_TEST_PATTERN_MODE_PN9 = 4;
/**
+ * <p>All pixel data is replaced by 0% intensity (black) values.</p>
+ * <p>This test pattern is identical to SOLID_COLOR with a value of <code>[0, 0, 0, 0]</code> for
+ * {@link CaptureRequest#SENSOR_TEST_PATTERN_DATA android.sensor.testPatternData}. It is recommended that devices implement full
+ * SOLID_COLOR support instead, but BLACK can be used to provide minimal support for a
+ * test pattern suitable for privacy use cases.</p>
+ *
+ * @see CaptureRequest#SENSOR_TEST_PATTERN_DATA
+ * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+ * @hide
+ */
+ @TestApi
+ public static final int SENSOR_TEST_PATTERN_MODE_BLACK = 5;
+
+ /**
* <p>The first custom test pattern. All custom patterns that are
* available only on this camera device are at least this numeric
* value.</p>
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 8dfb787bb3ab..5bb7201eff65 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -735,8 +735,7 @@ public final class OutputConfiguration implements Parcelable {
source.readTypedList(surfaces, Surface.CREATOR);
String physicalCameraId = source.readString();
boolean isMultiResolutionOutput = source.readInt() == 1;
- ArrayList<Integer> sensorPixelModesUsed = new ArrayList<Integer>();
- source.readList(sensorPixelModesUsed, Integer.class.getClassLoader());
+ int[] sensorPixelModesUsed = source.createIntArray();
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
mSurfaceGroupId = surfaceSetId;
@@ -760,7 +759,7 @@ public final class OutputConfiguration implements Parcelable {
}
mPhysicalCameraId = physicalCameraId;
mIsMultiResolution = isMultiResolutionOutput;
- mSensorPixelModesUsed = sensorPixelModesUsed;
+ mSensorPixelModesUsed = convertIntArrayToIntegerList(sensorPixelModesUsed);
}
/**
@@ -826,13 +825,7 @@ public final class OutputConfiguration implements Parcelable {
new Parcelable.Creator<OutputConfiguration>() {
@Override
public OutputConfiguration createFromParcel(Parcel source) {
- try {
- OutputConfiguration outputConfiguration = new OutputConfiguration(source);
- return outputConfiguration;
- } catch (Exception e) {
- Log.e(TAG, "Exception creating OutputConfiguration from parcel", e);
- return null;
- }
+ return new OutputConfiguration(source);
}
@Override
@@ -854,6 +847,17 @@ public final class OutputConfiguration implements Parcelable {
return integerArray;
}
+ private static ArrayList<Integer> convertIntArrayToIntegerList(int[] intArray) {
+ ArrayList<Integer> integerList = new ArrayList<Integer>();
+ if (intArray == null) {
+ return integerList;
+ }
+ for (int i = 0; i < intArray.length; i++) {
+ integerList.add(intArray[i]);
+ }
+ return integerList;
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
if (dest == null) {
@@ -871,7 +875,6 @@ public final class OutputConfiguration implements Parcelable {
dest.writeInt(mIsMultiResolution ? 1 : 0);
// writeList doesn't seem to work well with Integer list.
dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed));
- //dest.writeArray(mSensorPixelModesUsed.toArray());
}
/**
diff --git a/core/java/android/hardware/camera2/params/SessionConfiguration.java b/core/java/android/hardware/camera2/params/SessionConfiguration.java
index ea6b92d4f33e..cfb6efa9ba3c 100644
--- a/core/java/android/hardware/camera2/params/SessionConfiguration.java
+++ b/core/java/android/hardware/camera2/params/SessionConfiguration.java
@@ -146,13 +146,7 @@ public final class SessionConfiguration implements Parcelable {
new Parcelable.Creator<SessionConfiguration> () {
@Override
public SessionConfiguration createFromParcel(Parcel source) {
- try {
- SessionConfiguration sessionConfiguration = new SessionConfiguration(source);
- return sessionConfiguration;
- } catch (Exception e) {
- Log.e(TAG, "Exception creating SessionConfiguration from parcel", e);
- return null;
- }
+ return new SessionConfiguration(source);
}
@Override
diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptor.java b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
index 4845ec3e3bd8..c62f6da012c1 100644
--- a/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
+++ b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
@@ -36,13 +36,7 @@ public final class VendorTagDescriptor implements Parcelable {
new Parcelable.Creator<VendorTagDescriptor>() {
@Override
public VendorTagDescriptor createFromParcel(Parcel source) {
- try {
- VendorTagDescriptor vendorDescriptor = new VendorTagDescriptor(source);
- return vendorDescriptor;
- } catch (Exception e) {
- Log.e(TAG, "Exception creating VendorTagDescriptor from parcel", e);
- return null;
- }
+ return new VendorTagDescriptor(source);
}
@Override
diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java b/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java
index 450b70bcdcdc..8d7615c98662 100644
--- a/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java
+++ b/core/java/android/hardware/camera2/params/VendorTagDescriptorCache.java
@@ -36,13 +36,7 @@ public final class VendorTagDescriptorCache implements Parcelable {
new Parcelable.Creator<VendorTagDescriptorCache>() {
@Override
public VendorTagDescriptorCache createFromParcel(Parcel source) {
- try {
- VendorTagDescriptorCache vendorDescriptorCache = new VendorTagDescriptorCache(source);
- return vendorDescriptorCache;
- } catch (Exception e) {
- Log.e(TAG, "Exception creating VendorTagDescriptorCache from parcel", e);
- return null;
- }
+ return new VendorTagDescriptorCache(source);
}
@Override
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index 891299760237..a1f7aa12264b 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -53,7 +53,8 @@ public class AmbientDisplayConfiguration {
|| pickupGestureEnabled(user)
|| tapGestureEnabled(user)
|| doubleTapGestureEnabled(user)
- || quickPickupSensorEnabled(user);
+ || quickPickupSensorEnabled(user)
+ || screenOffUdfpsEnabled(user);
}
/** {@hide} */
@@ -106,6 +107,12 @@ public class AmbientDisplayConfiguration {
}
/** {@hide} */
+ public boolean screenOffUdfpsEnabled(int user) {
+ return !TextUtils.isEmpty(udfpsLongPressSensorType())
+ && boolSettingDefaultOff("screen_off_udfps_enabled", user);
+ }
+
+ /** {@hide} */
public boolean wakeScreenGestureAvailable() {
return mContext.getResources()
.getBoolean(R.bool.config_dozeWakeLockScreenSensorAvailable);
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 64f20b839a63..5a25cfc00cd4 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -200,6 +200,9 @@ public final class NsdManager {
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 20;
/** @hide */
+ public static final int DAEMON_CLEANUP = BASE + 21;
+
+ /** @hide */
public static final int ENABLE = BASE + 24;
/** @hide */
public static final int DISABLE = BASE + 25;
diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java
index ee86265e81ad..802387c675b5 100644
--- a/core/java/android/os/AggregateBatteryConsumer.java
+++ b/core/java/android/os/AggregateBatteryConsumer.java
@@ -17,7 +17,13 @@
package android.os;
import android.annotation.NonNull;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.io.PrintWriter;
/**
@@ -72,6 +78,43 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
return mConsumedPowerMah;
}
+ /** Serializes this object to XML */
+ void writeToXml(TypedXmlSerializer serializer,
+ @BatteryUsageStats.AggregateBatteryConsumerScope int scope) throws IOException {
+ serializer.startTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
+ serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE, scope);
+ serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, mConsumedPowerMah);
+ mPowerComponents.writeToXml(serializer);
+ serializer.endTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
+ }
+
+ /** Parses an XML representation and populates the BatteryUsageStats builder */
+ static void parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
+ throws XmlPullParserException, IOException {
+ final int scope = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE);
+ final Builder consumerBuilder = builder.getAggregateBatteryConsumerBuilder(scope);
+
+ int eventType = parser.getEventType();
+ if (eventType != XmlPullParser.START_TAG || !parser.getName().equals(
+ BatteryUsageStats.XML_TAG_AGGREGATE)) {
+ throw new XmlPullParserException("Invalid XML parser state");
+ }
+
+ consumerBuilder.setConsumedPower(
+ parser.getAttributeDouble(null, BatteryUsageStats.XML_ATTR_POWER));
+
+ while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(
+ BatteryUsageStats.XML_TAG_AGGREGATE))
+ && eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
+ PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
+ }
+ }
+ eventType = parser.next();
+ }
+ }
+
/**
* Builder for DeviceBatteryConsumer.
*/
@@ -91,6 +134,14 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
}
/**
+ * Adds power and usage duration from the supplied AggregateBatteryConsumer.
+ */
+ public void add(AggregateBatteryConsumer aggregateBatteryConsumer) {
+ mConsumedPowerMah += aggregateBatteryConsumer.mConsumedPowerMah;
+ mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents);
+ }
+
+ /**
* Creates a read-only object out of the Builder values.
*/
@NonNull
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index f2857ceb59d7..77f8a87cdcd1 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -20,16 +20,23 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.util.Range;
import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
import android.util.proto.ProtoOutputStream;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.internal.os.PowerCalculator;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@@ -75,6 +82,36 @@ public final class BatteryUsageStats implements Parcelable {
public static final int AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT = 2;
+ private static final int STATSD_PULL_ATOM_MAX_BYTES = 45000;
+
+ // XML tags and attributes for BatteryUsageStats persistence
+ static final String XML_TAG_BATTERY_USAGE_STATS = "battery_usage_stats";
+ static final String XML_TAG_AGGREGATE = "aggregate";
+ static final String XML_TAG_UID = "uid";
+ static final String XML_TAG_USER = "user";
+ static final String XML_TAG_POWER_COMPONENTS = "power_components";
+ static final String XML_TAG_COMPONENT = "component";
+ static final String XML_TAG_CUSTOM_COMPONENT = "custom_component";
+ static final String XML_ATTR_ID = "id";
+ static final String XML_ATTR_UID = "uid";
+ static final String XML_ATTR_USER_ID = "user_id";
+ static final String XML_ATTR_SCOPE = "scope";
+ static final String XML_ATTR_PREFIX_CUSTOM_COMPONENT = "custom_component_";
+ static final String XML_ATTR_START_TIMESTAMP = "start_timestamp";
+ static final String XML_ATTR_END_TIMESTAMP = "end_timestamp";
+ static final String XML_ATTR_POWER = "power";
+ static final String XML_ATTR_DURATION = "duration";
+ static final String XML_ATTR_MODEL = "model";
+ static final String XML_ATTR_BATTERY_CAPACITY = "battery_capacity";
+ static final String XML_ATTR_DISCHARGE_PERCENT = "discharge_pct";
+ static final String XML_ATTR_DISCHARGE_LOWER = "discharge_lower";
+ static final String XML_ATTR_DISCHARGE_UPPER = "discharge_upper";
+ static final String XML_ATTR_BATTERY_REMAINING = "battery_remaining";
+ static final String XML_ATTR_CHARGE_REMAINING = "charge_remaining";
+ static final String XML_ATTR_HIGHEST_DRAIN_PACKAGE = "highest_drain_package";
+ static final String XML_ATTR_TIME_IN_FOREGROUND = "time_in_foreground";
+ static final String XML_ATTR_TIME_IN_BACKGROUND = "time_in_background";
+
private final int mDischargePercentage;
private final double mBatteryCapacityMah;
private final long mStatsStartTimestampMs;
@@ -94,11 +131,7 @@ public final class BatteryUsageStats implements Parcelable {
private BatteryUsageStats(@NonNull Builder builder) {
mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
mStatsEndTimestampMs = builder.mStatsEndTimestampMs;
- if (builder.mStatsDurationMs != -1) {
- mStatsDurationMs = builder.mStatsDurationMs;
- } else {
- mStatsDurationMs = mStatsEndTimestampMs - mStatsStartTimestampMs;
- }
+ mStatsDurationMs = builder.getStatsDuration();
mBatteryCapacityMah = builder.mBatteryCapacityMah;
mDischargePercentage = builder.mDischargePercentage;
mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah;
@@ -369,30 +402,60 @@ public final class BatteryUsageStats implements Parcelable {
/** Returns a proto (as used for atoms.proto) corresponding to this BatteryUsageStats. */
public byte[] getStatsProto() {
+ // ProtoOutputStream.getRawSize() returns the buffer size before compaction.
+ // BatteryUsageStats contains a lot of integers, so compaction of integers to
+ // varint reduces the size of the proto buffer by as much as 50%.
+ int maxRawSize = (int) (STATSD_PULL_ATOM_MAX_BYTES * 1.75);
+ // Limit the number of attempts in order to prevent an infinite loop
+ for (int i = 0; i < 3; i++) {
+ final ProtoOutputStream proto = new ProtoOutputStream();
+ writeStatsProto(proto, maxRawSize);
+
+ final int rawSize = proto.getRawSize();
+ final byte[] protoOutput = proto.getBytes();
+
+ if (protoOutput.length <= STATSD_PULL_ATOM_MAX_BYTES) {
+ return protoOutput;
+ }
+
+ // Adjust maxRawSize proportionately and try again.
+ maxRawSize =
+ (int) ((long) STATSD_PULL_ATOM_MAX_BYTES * rawSize / protoOutput.length - 1024);
+ }
+
+ // Fallback: if we have failed to generate a proto smaller than STATSD_PULL_ATOM_MAX_BYTES,
+ // just generate a proto with the _rawSize_ of STATSD_PULL_ATOM_MAX_BYTES, which is
+ // guaranteed to produce a compacted proto (significantly) smaller than
+ // STATSD_PULL_ATOM_MAX_BYTES.
+ final ProtoOutputStream proto = new ProtoOutputStream();
+ writeStatsProto(proto, STATSD_PULL_ATOM_MAX_BYTES);
+ return proto.getBytes();
+ }
+
+ @NonNull
+ private void writeStatsProto(ProtoOutputStream proto, int maxRawSize) {
final BatteryConsumer deviceBatteryConsumer = getAggregateBatteryConsumer(
AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
- final ProtoOutputStream proto = new ProtoOutputStream();
proto.write(BatteryUsageStatsAtomsProto.SESSION_START_MILLIS, getStatsStartTimestamp());
proto.write(BatteryUsageStatsAtomsProto.SESSION_END_MILLIS, getStatsEndTimestamp());
proto.write(BatteryUsageStatsAtomsProto.SESSION_DURATION_MILLIS, getStatsDuration());
- deviceBatteryConsumer.writeStatsProto(proto,
- BatteryUsageStatsAtomsProto.DEVICE_BATTERY_CONSUMER);
- writeUidBatteryConsumersProto(proto);
proto.write(BatteryUsageStatsAtomsProto.SESSION_DISCHARGE_PERCENTAGE,
getDischargePercentage());
- return proto.getBytes();
+ deviceBatteryConsumer.writeStatsProto(proto,
+ BatteryUsageStatsAtomsProto.DEVICE_BATTERY_CONSUMER);
+ writeUidBatteryConsumersProto(proto, maxRawSize);
}
/**
* Writes the UidBatteryConsumers data, held by this BatteryUsageStats, to the proto (as used
* for atoms.proto).
*/
- private void writeUidBatteryConsumersProto(ProtoOutputStream proto) {
+ private void writeUidBatteryConsumersProto(ProtoOutputStream proto, int maxRawSize) {
final List<UidBatteryConsumer> consumers = getUidBatteryConsumers();
+ // Order consumers by descending weight (a combination of consumed power and usage time)
+ consumers.sort(Comparator.comparingDouble(this::getUidBatteryConsumerWeight).reversed());
- // TODO(b/189225426): Sort the list by power consumption. If during the for,
- // proto.getRawSize() > 45kb, truncate the remainder of the list.
final int size = consumers.size();
for (int i = 0; i < size; i++) {
final UidBatteryConsumer consumer = consumers.get(i);
@@ -420,9 +483,35 @@ public final class BatteryUsageStats implements Parcelable {
BatteryUsageStatsAtomsProto.UidBatteryConsumer.TIME_IN_BACKGROUND_MILLIS,
bgMs);
proto.end(token);
+
+ if (proto.getRawSize() >= maxRawSize) {
+ break;
+ }
}
}
+ private static final double WEIGHT_CONSUMED_POWER = 1;
+ // Weight one hour in foreground the same as 100 mAh of power drain
+ private static final double WEIGHT_FOREGROUND_STATE = 100.0 / (1 * 60 * 60 * 1000);
+ // Weight one hour in background the same as 300 mAh of power drain
+ private static final double WEIGHT_BACKGROUND_STATE = 300.0 / (1 * 60 * 60 * 1000);
+
+ /**
+ * Computes the weight associated with a UidBatteryConsumer, which is used for sorting.
+ * We want applications with the largest consumed power as well as applications
+ * with the highest usage time to be included in the statsd atom.
+ */
+ private double getUidBatteryConsumerWeight(UidBatteryConsumer uidBatteryConsumer) {
+ final double consumedPower = uidBatteryConsumer.getConsumedPower();
+ final long timeInForeground =
+ uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND);
+ final long timeInBackground =
+ uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND);
+ return consumedPower * WEIGHT_CONSUMED_POWER
+ + timeInForeground * WEIGHT_FOREGROUND_STATE
+ + timeInBackground * WEIGHT_BACKGROUND_STATE;
+ }
+
/**
* Prints the stats in a human-readable format.
*/
@@ -521,6 +610,109 @@ public final class BatteryUsageStats implements Parcelable {
}
}
+ /** Serializes this object to XML */
+ public void writeXml(TypedXmlSerializer serializer) throws IOException {
+ serializer.startTag(null, XML_TAG_BATTERY_USAGE_STATS);
+
+ for (int i = 0; i < mCustomPowerComponentNames.length; i++) {
+ serializer.attribute(null, XML_ATTR_PREFIX_CUSTOM_COMPONENT + i,
+ mCustomPowerComponentNames[i]);
+ }
+
+ serializer.attributeLong(null, XML_ATTR_START_TIMESTAMP, mStatsStartTimestampMs);
+ serializer.attributeLong(null, XML_ATTR_END_TIMESTAMP, mStatsEndTimestampMs);
+ serializer.attributeLong(null, XML_ATTR_DURATION, mStatsDurationMs);
+ serializer.attributeDouble(null, XML_ATTR_BATTERY_CAPACITY, mBatteryCapacityMah);
+ serializer.attributeInt(null, XML_ATTR_DISCHARGE_PERCENT, mDischargePercentage);
+ serializer.attributeDouble(null, XML_ATTR_DISCHARGE_LOWER, mDischargedPowerLowerBound);
+ serializer.attributeDouble(null, XML_ATTR_DISCHARGE_UPPER, mDischargedPowerUpperBound);
+ serializer.attributeLong(null, XML_ATTR_BATTERY_REMAINING, mBatteryTimeRemainingMs);
+ serializer.attributeLong(null, XML_ATTR_CHARGE_REMAINING, mChargeTimeRemainingMs);
+
+ for (int scope = 0; scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
+ scope++) {
+ mAggregateBatteryConsumers[scope].writeToXml(serializer, scope);
+ }
+ for (UidBatteryConsumer consumer : mUidBatteryConsumers) {
+ consumer.writeToXml(serializer);
+ }
+ for (UserBatteryConsumer consumer : mUserBatteryConsumers) {
+ consumer.writeToXml(serializer);
+ }
+ serializer.endTag(null, XML_TAG_BATTERY_USAGE_STATS);
+ }
+
+ /** Parses an XML representation of BatteryUsageStats */
+ public static BatteryUsageStats createFromXml(TypedXmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ Builder builder = null;
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG
+ && parser.getName().equals(XML_TAG_BATTERY_USAGE_STATS)) {
+ List<String> customComponentNames = new ArrayList<>();
+ int i = 0;
+ while (true) {
+ int index = parser.getAttributeIndex(null,
+ XML_ATTR_PREFIX_CUSTOM_COMPONENT + i);
+ if (index == -1) {
+ break;
+ }
+ customComponentNames.add(parser.getAttributeValue(index));
+ i++;
+ }
+
+ builder = new Builder(
+ customComponentNames.toArray(new String[0]), true);
+
+ builder.setStatsStartTimestamp(
+ parser.getAttributeLong(null, XML_ATTR_START_TIMESTAMP));
+ builder.setStatsEndTimestamp(
+ parser.getAttributeLong(null, XML_ATTR_END_TIMESTAMP));
+ builder.setStatsDuration(
+ parser.getAttributeLong(null, XML_ATTR_DURATION));
+ builder.setBatteryCapacity(
+ parser.getAttributeDouble(null, XML_ATTR_BATTERY_CAPACITY));
+ builder.setDischargePercentage(
+ parser.getAttributeInt(null, XML_ATTR_DISCHARGE_PERCENT));
+ builder.setDischargedPowerRange(
+ parser.getAttributeDouble(null, XML_ATTR_DISCHARGE_LOWER),
+ parser.getAttributeDouble(null, XML_ATTR_DISCHARGE_UPPER));
+ builder.setBatteryTimeRemainingMs(
+ parser.getAttributeLong(null, XML_ATTR_BATTERY_REMAINING));
+ builder.setChargeTimeRemainingMs(
+ parser.getAttributeLong(null, XML_ATTR_CHARGE_REMAINING));
+
+ eventType = parser.next();
+ break;
+ }
+ eventType = parser.next();
+ }
+
+ if (builder == null) {
+ throw new XmlPullParserException("No root element");
+ }
+
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ switch (parser.getName()) {
+ case XML_TAG_AGGREGATE:
+ AggregateBatteryConsumer.parseXml(parser, builder);
+ break;
+ case XML_TAG_UID:
+ UidBatteryConsumer.createFromXml(parser, builder);
+ break;
+ case XML_TAG_USER:
+ UserBatteryConsumer.createFromXml(parser, builder);
+ break;
+ }
+ }
+ eventType = parser.next();
+ }
+
+ return builder.build();
+ }
+
/**
* Builder for BatteryUsageStats.
*/
@@ -600,6 +792,14 @@ public final class BatteryUsageStats implements Parcelable {
return this;
}
+ private long getStatsDuration() {
+ if (mStatsDurationMs != -1) {
+ return mStatsDurationMs;
+ } else {
+ return mStatsEndTimestampMs - mStatsStartTimestampMs;
+ }
+ }
+
/**
* Sets the battery discharge amount since BatteryStats reset as percentage of the full
* charge.
@@ -680,6 +880,22 @@ public final class BatteryUsageStats implements Parcelable {
}
/**
+ * Creates or returns a UidBatteryConsumer, which represents battery attribution
+ * data for an individual UID. This version of the method is not suitable for use
+ * with PowerCalculators.
+ */
+ @NonNull
+ public UidBatteryConsumer.Builder getOrCreateUidBatteryConsumerBuilder(int uid) {
+ UidBatteryConsumer.Builder builder = mUidBatteryConsumerBuilders.get(uid);
+ if (builder == null) {
+ builder = new UidBatteryConsumer.Builder(mCustomPowerComponentNames,
+ mIncludePowerModels, uid);
+ mUidBatteryConsumerBuilders.put(uid, builder);
+ }
+ return builder;
+ }
+
+ /**
* Creates or returns a UserBatteryConsumer, which represents battery attribution
* data for an individual {@link UserHandle}.
*/
@@ -698,5 +914,59 @@ public final class BatteryUsageStats implements Parcelable {
public SparseArray<UidBatteryConsumer.Builder> getUidBatteryConsumerBuilders() {
return mUidBatteryConsumerBuilders;
}
+
+ /**
+ * Adds battery usage stats from another snapshots. The two snapshots are assumed to be
+ * non-overlapping, meaning that the power consumption estimates and session durations
+ * can be simply summed across the two snapshots. This remains true even if the timestamps
+ * seem to indicate that the sessions are in fact overlapping: timestamps may be off as a
+ * result of realtime clock adjustments by the user or the system.
+ */
+ @NonNull
+ public Builder add(BatteryUsageStats stats) {
+ if (!Arrays.equals(mCustomPowerComponentNames, stats.mCustomPowerComponentNames)) {
+ throw new IllegalArgumentException(
+ "BatteryUsageStats have different custom power components");
+ }
+
+ if (mUserBatteryConsumerBuilders.size() != 0
+ || !stats.getUserBatteryConsumers().isEmpty()) {
+ throw new UnsupportedOperationException(
+ "Combining UserBatteryConsumers is not supported");
+ }
+
+ mDischargedPowerLowerBoundMah += stats.mDischargedPowerLowerBound;
+ mDischargedPowerUpperBoundMah += stats.mDischargedPowerUpperBound;
+ mDischargePercentage += stats.mDischargePercentage;
+
+ mStatsDurationMs = getStatsDuration() + stats.getStatsDuration();
+
+ if (mStatsStartTimestampMs == 0
+ || stats.mStatsStartTimestampMs < mStatsStartTimestampMs) {
+ mStatsStartTimestampMs = stats.mStatsStartTimestampMs;
+ }
+
+ final boolean addingLaterSnapshot = stats.mStatsEndTimestampMs > mStatsEndTimestampMs;
+ if (addingLaterSnapshot) {
+ mStatsEndTimestampMs = stats.mStatsEndTimestampMs;
+ }
+
+ for (int scope = 0; scope < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; scope++) {
+ getAggregateBatteryConsumerBuilder(scope)
+ .add(stats.mAggregateBatteryConsumers[scope]);
+ }
+
+ for (UidBatteryConsumer consumer : stats.getUidBatteryConsumers()) {
+ getOrCreateUidBatteryConsumerBuilder(consumer.getUid()).add(consumer);
+ }
+
+ if (addingLaterSnapshot) {
+ mBatteryCapacityMah = stats.mBatteryCapacityMah;
+ mBatteryTimeRemainingMs = stats.mBatteryTimeRemainingMs;
+ mChargeTimeRemainingMs = stats.mChargeTimeRemainingMs;
+ }
+
+ return this;
+ }
}
}
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java
index 50804422e92f..97f24ccecaee 100644
--- a/core/java/android/os/BatteryUsageStatsQuery.java
+++ b/core/java/android/os/BatteryUsageStatsQuery.java
@@ -72,12 +72,16 @@ public final class BatteryUsageStatsQuery implements Parcelable {
@NonNull
private final int[] mUserIds;
private final long mMaxStatsAgeMs;
+ private long mFromTimestamp;
+ private long mToTimestamp;
private BatteryUsageStatsQuery(@NonNull Builder builder) {
mFlags = builder.mFlags;
mUserIds = builder.mUserIds != null ? builder.mUserIds.toArray()
: new int[]{UserHandle.USER_ALL};
mMaxStatsAgeMs = builder.mMaxStatsAgeMs;
+ mFromTimestamp = builder.mFromTimestamp;
+ mToTimestamp = builder.mToTimestamp;
}
@BatteryUsageStatsFlags
@@ -112,11 +116,30 @@ public final class BatteryUsageStatsQuery implements Parcelable {
return mMaxStatsAgeMs;
}
+ /**
+ * Returns the exclusive lower bound of the stored snapshot timestamps that should be included
+ * in the aggregation. Ignored if {@link #getToTimestamp()} is zero.
+ */
+ public long getFromTimestamp() {
+ return mFromTimestamp;
+ }
+
+ /**
+ * Returns the inclusive upper bound of the stored snapshot timestamps that should
+ * be included in the aggregation. The default is to include only the current stats
+ * accumulated since the latest battery reset.
+ */
+ public long getToTimestamp() {
+ return mToTimestamp;
+ }
+
private BatteryUsageStatsQuery(Parcel in) {
mFlags = in.readInt();
mUserIds = new int[in.readInt()];
in.readIntArray(mUserIds);
mMaxStatsAgeMs = in.readLong();
+ mFromTimestamp = in.readLong();
+ mToTimestamp = in.readLong();
}
@Override
@@ -125,6 +148,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
dest.writeInt(mUserIds.length);
dest.writeIntArray(mUserIds);
dest.writeLong(mMaxStatsAgeMs);
+ dest.writeLong(mFromTimestamp);
+ dest.writeLong(mToTimestamp);
}
@Override
@@ -153,6 +178,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
private int mFlags;
private IntArray mUserIds;
private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS;
+ private long mFromTimestamp;
+ private long mToTimestamp;
/**
* Builds a read-only BatteryUsageStatsQuery object.
@@ -204,6 +231,17 @@ public final class BatteryUsageStatsQuery implements Parcelable {
}
/**
+ * Requests to aggregate stored snapshots between the two supplied timestamps
+ * @param fromTimestamp Exclusive starting timestamp, as per System.currentTimeMillis()
+ * @param toTimestamp Inclusive ending timestamp, as per System.currentTimeMillis()
+ */
+ public Builder aggregateSnapshots(long fromTimestamp, long toTimestamp) {
+ mFromTimestamp = fromTimestamp;
+ mToTimestamp = toTimestamp;
+ return this;
+ }
+
+ /**
* Set the client's tolerance for stale battery stats. The data may be up to
* this many milliseconds out-of-date.
*/
diff --git a/core/java/android/os/PackageTagsList.java b/core/java/android/os/PackageTagsList.java
index c94d3de33b6f..4a81dc6f592e 100644
--- a/core/java/android/os/PackageTagsList.java
+++ b/core/java/android/os/PackageTagsList.java
@@ -23,20 +23,26 @@ import android.annotation.TestApi;
import android.util.ArrayMap;
import android.util.ArraySet;
+import com.android.internal.annotations.Immutable;
+
import java.io.PrintWriter;
+import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
- * A list of packages and associated attribution tags that supports easy membership checks.
+ * A list of packages and associated attribution tags that supports easy membership checks. Supports
+ * "wildcard" attribution tags (ie, matching any attribution tag under a package) in additional to
+ * standard checks.
*
* @hide
*/
@TestApi
+@Immutable
public final class PackageTagsList implements Parcelable {
- // an empty set value matches any attribution tag
+ // an empty set value matches any attribution tag (ie, wildcard)
private final ArrayMap<String, ArraySet<String>> mPackageTags;
private PackageTagsList(@NonNull ArrayMap<String, ArraySet<String>> packageTags) {
@@ -51,15 +57,34 @@ public final class PackageTagsList implements Parcelable {
}
/**
- * Returns true if the given package is represented within this instance. If this returns true
- * this does not imply anything about whether any given attribution tag under the given package
- * name is present.
+ * Returns true if the given package is found within this instance. If this returns true this
+ * does not imply anything about whether any given attribution tag under the given package name
+ * is present.
*/
public boolean includes(@NonNull String packageName) {
return mPackageTags.containsKey(packageName);
}
/**
+ * Returns true if the given attribution tag is found within this instance under any package.
+ * Only returns true if the attribution tag literal is found, not if any package contains the
+ * set of all attribution tags.
+ *
+ * @hide
+ */
+ public boolean includesTag(@NonNull String attributionTag) {
+ final int size = mPackageTags.size();
+ for (int i = 0; i < size; i++) {
+ ArraySet<String> tags = mPackageTags.valueAt(i);
+ if (tags.contains(attributionTag)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Returns true if all attribution tags under the given package are contained within this
* instance.
*/
@@ -76,6 +101,7 @@ public final class PackageTagsList implements Parcelable {
if (tags == null) {
return false;
} else if (tags.isEmpty()) {
+ // our tags are the full set, so we contain any attribution tag
return true;
} else {
return tags.contains(attributionTag);
@@ -98,10 +124,12 @@ public final class PackageTagsList implements Parcelable {
return false;
}
if (tags.isEmpty()) {
+ // our tags are the full set, so we contain whatever the other tags are
continue;
}
ArraySet<String> otherTags = packageTagsList.mPackageTags.valueAt(i);
if (otherTags.isEmpty()) {
+ // other tags are the full set, so we can't contain them
return false;
}
if (!tags.containsAll(otherTags)) {
@@ -248,6 +276,31 @@ public final class PackageTagsList implements Parcelable {
}
/**
+ * Adds the specified package and set of attribution tags to the builder.
+ *
+ * @hide
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public @NonNull Builder add(@NonNull String packageName,
+ @NonNull Collection<String> attributionTags) {
+ if (attributionTags.isEmpty()) {
+ // the input is not allowed to specify a full set by passing in an empty collection
+ return this;
+ }
+
+ ArraySet<String> tags = mPackageTags.get(packageName);
+ if (tags == null) {
+ tags = new ArraySet<>(attributionTags);
+ mPackageTags.put(packageName, tags);
+ } else if (!tags.isEmpty()) {
+ // if we contain the full set, already done, otherwise add all the tags
+ tags.addAll(attributionTags);
+ }
+
+ return this;
+ }
+
+ /**
* Adds the specified {@link PackageTagsList} to the builder.
*/
@SuppressLint("MissingGetterMatchingBuilder")
@@ -267,13 +320,92 @@ public final class PackageTagsList implements Parcelable {
if (newTags.isEmpty()) {
add(entry.getKey());
} else {
- ArraySet<String> tags = mPackageTags.get(entry.getKey());
- if (tags == null) {
- tags = new ArraySet<>(newTags);
- mPackageTags.put(entry.getKey(), tags);
- } else if (!tags.isEmpty()) {
- tags.addAll(newTags);
- }
+ add(entry.getKey(), newTags);
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * Removes all attribution tags under the specified package from the builder.
+ *
+ * @hide
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public @NonNull Builder remove(@NonNull String packageName) {
+ mPackageTags.remove(packageName);
+ return this;
+ }
+
+ /**
+ * Removes the specified package and attribution tag from the builder if and only if the
+ * specified attribution tag is listed explicitly under the package. If the package contains
+ * all possible attribution tags, then nothing will be removed.
+ *
+ * @hide
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public @NonNull Builder remove(@NonNull String packageName,
+ @Nullable String attributionTag) {
+ ArraySet<String> tags = mPackageTags.get(packageName);
+ if (tags != null && tags.remove(attributionTag) && tags.isEmpty()) {
+ mPackageTags.remove(packageName);
+ }
+ return this;
+ }
+
+ /**
+ * Removes the specified package and set of attribution tags from the builder if and only if
+ * the specified set of attribution tags are listed explicitly under the package. If the
+ * package contains all possible attribution tags, then nothing will be removed.
+ *
+ * @hide
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public @NonNull Builder remove(@NonNull String packageName,
+ @NonNull Collection<String> attributionTags) {
+ if (attributionTags.isEmpty()) {
+ // the input is not allowed to specify a full set by passing in an empty collection
+ return this;
+ }
+
+ ArraySet<String> tags = mPackageTags.get(packageName);
+ if (tags != null && tags.removeAll(attributionTags) && tags.isEmpty()) {
+ mPackageTags.remove(packageName);
+ }
+ return this;
+ }
+
+ /**
+ * Removes the specified {@link PackageTagsList} from the builder. If a package contains all
+ * possible attribution tags, it will only be removed if the package in the removed
+ * {@link PackageTagsList} also contains all possible attribution tags.
+ *
+ * @hide
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public @NonNull Builder remove(@NonNull PackageTagsList packageTagsList) {
+ return remove(packageTagsList.mPackageTags);
+ }
+
+ /**
+ * Removes the given map of package to attribution tags to the builder. An empty set of
+ * attribution tags is interpreted to imply all attribution tags under that package. If a
+ * package contains all possible attribution tags, it will only be removed if the package in
+ * the removed map also contains all possible attribution tags.
+ *
+ * @hide
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ public @NonNull Builder remove(@NonNull Map<String, ? extends Set<String>> packageTagsMap) {
+ for (Map.Entry<String, ? extends Set<String>> entry : packageTagsMap.entrySet()) {
+ Set<String> removedTags = entry.getValue();
+ if (removedTags.isEmpty()) {
+ // if removing the full set, drop the package completely
+ remove(entry.getKey());
+ } else {
+ remove(entry.getKey(), removedTags);
}
}
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index a90ed20d54fc..db3d13bdb07b 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -19,11 +19,18 @@ import static android.os.BatteryConsumer.convertMahToDeciCoulombs;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
import android.util.proto.ProtoOutputStream;
import com.android.internal.os.PowerCalculator;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Arrays;
/**
* Contains details of battery attribution data broken down to individual power drain types
@@ -36,9 +43,12 @@ class PowerComponents {
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
private final double mConsumedPowerMah;
+ @NonNull
private final double[] mPowerComponentsMah;
+ @NonNull
private final long[] mUsageDurationsMs;
private final int mCustomPowerComponentCount;
+ @Nullable
private final byte[] mPowerModels;
// Not written to Parcel and must be explicitly restored during the parent object's unparceling
private String[] mCustomPowerComponentNames;
@@ -49,7 +59,7 @@ class PowerComponents {
mPowerComponentsMah = builder.mPowerComponentsMah;
mUsageDurationsMs = builder.mUsageDurationsMs;
mConsumedPowerMah = builder.getTotalPower();
- mPowerModels = builder.mPowerModels;
+ mPowerModels = builder.getPowerModels();
}
PowerComponents(@NonNull Parcel source) {
@@ -146,9 +156,13 @@ class PowerComponents {
}
}
+ public boolean hasPowerModels() {
+ return mPowerModels != null;
+ }
+
@BatteryConsumer.PowerModel
int getPowerModel(@BatteryConsumer.PowerComponent int component) {
- if (mPowerModels == null) {
+ if (!hasPowerModels()) {
throw new IllegalStateException(
"Power model IDs were not requested in the BatteryUsageStatsQuery");
}
@@ -294,10 +308,128 @@ class PowerComponents {
return interestingData;
}
+ void writeToXml(TypedXmlSerializer serializer) throws IOException {
+ serializer.startTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS);
+ for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
+ componentId++) {
+ final double powerMah = getConsumedPower(componentId);
+ final long durationMs = getUsageDurationMillis(componentId);
+ if (powerMah == 0 && durationMs == 0) {
+ continue;
+ }
+
+ serializer.startTag(null, BatteryUsageStats.XML_TAG_COMPONENT);
+ serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, componentId);
+ if (powerMah != 0) {
+ serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, powerMah);
+ }
+ if (durationMs != 0) {
+ serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs);
+ }
+ if (mPowerModels != null) {
+ serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_MODEL,
+ mPowerModels[componentId]);
+ }
+ serializer.endTag(null, BatteryUsageStats.XML_TAG_COMPONENT);
+ }
+
+ final int customComponentEnd =
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + mCustomPowerComponentCount;
+ for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+ componentId < customComponentEnd;
+ componentId++) {
+ final double powerMah = getConsumedPowerForCustomComponent(componentId);
+ final long durationMs = getUsageDurationForCustomComponentMillis(componentId);
+ if (powerMah == 0 && durationMs == 0) {
+ continue;
+ }
+
+ serializer.startTag(null, BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT);
+ serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, componentId);
+ if (powerMah != 0) {
+ serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, powerMah);
+ }
+ if (durationMs != 0) {
+ serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs);
+ }
+ serializer.endTag(null, BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT);
+ }
+
+ serializer.endTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS);
+ }
+
+
+ static void parseXml(TypedXmlPullParser parser, PowerComponents.Builder builder)
+ throws XmlPullParserException, IOException {
+ int eventType = parser.getEventType();
+ if (eventType != XmlPullParser.START_TAG || !parser.getName().equals(
+ BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
+ throw new XmlPullParserException("Invalid XML parser state");
+ }
+
+ while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(
+ BatteryUsageStats.XML_TAG_POWER_COMPONENTS))
+ && eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ switch (parser.getName()) {
+ case BatteryUsageStats.XML_TAG_COMPONENT: {
+ int componentId = -1;
+ double powerMah = 0;
+ long durationMs = 0;
+ int model = BatteryConsumer.POWER_MODEL_UNDEFINED;
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ switch (parser.getAttributeName(i)) {
+ case BatteryUsageStats.XML_ATTR_ID:
+ componentId = parser.getAttributeInt(i);
+ break;
+ case BatteryUsageStats.XML_ATTR_POWER:
+ powerMah = parser.getAttributeDouble(i);
+ break;
+ case BatteryUsageStats.XML_ATTR_DURATION:
+ durationMs = parser.getAttributeLong(i);
+ break;
+ case BatteryUsageStats.XML_ATTR_MODEL:
+ model = parser.getAttributeInt(i);
+ break;
+ }
+ }
+ builder.setConsumedPower(componentId, powerMah, model);
+ builder.setUsageDurationMillis(componentId, durationMs);
+ break;
+ }
+ case BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT: {
+ int componentId = -1;
+ double powerMah = 0;
+ long durationMs = 0;
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ switch (parser.getAttributeName(i)) {
+ case BatteryUsageStats.XML_ATTR_ID:
+ componentId = parser.getAttributeInt(i);
+ break;
+ case BatteryUsageStats.XML_ATTR_POWER:
+ powerMah = parser.getAttributeDouble(i);
+ break;
+ case BatteryUsageStats.XML_ATTR_DURATION:
+ durationMs = parser.getAttributeLong(i);
+ break;
+ }
+ }
+ builder.setConsumedPowerForCustomComponent(componentId, powerMah);
+ builder.setUsageDurationForCustomComponentMillis(componentId, durationMs);
+ break;
+ }
+ }
+ }
+ eventType = parser.next();
+ }
+ }
+
/**
* Builder for PowerComponents.
*/
static final class Builder {
+ private static final byte POWER_MODEL_UNINITIALIZED = -1;
+
private final double[] mPowerComponentsMah;
private final String[] mCustomPowerComponentNames;
private final long[] mUsageDurationsMs;
@@ -311,6 +443,7 @@ class PowerComponents {
mUsageDurationsMs = new long[powerComponentCount];
if (includePowerModels) {
mPowerModels = new byte[BatteryConsumer.POWER_COMPONENT_COUNT];
+ Arrays.fill(mPowerModels, POWER_MODEL_UNINITIALIZED);
} else {
mPowerModels = null;
}
@@ -412,12 +545,39 @@ class PowerComponents {
return this;
}
- public void addPowerAndDuration(Builder other) {
+ public void addPowerAndDuration(PowerComponents.Builder other) {
+ addPowerAndDuration(other.mPowerComponentsMah, other.mUsageDurationsMs,
+ other.mPowerModels);
+ }
+
+ public void addPowerAndDuration(PowerComponents other) {
+ addPowerAndDuration(other.mPowerComponentsMah, other.mUsageDurationsMs,
+ other.mPowerModels);
+ }
+
+ private void addPowerAndDuration(double[] powerComponentsMah,
+ long[] usageDurationsMs, byte[] powerModels) {
+ if (mPowerComponentsMah.length != powerComponentsMah.length) {
+ throw new IllegalArgumentException(
+ "Number of power components does not match: " + powerComponentsMah.length
+ + ", expected: " + mPowerComponentsMah.length);
+ }
+
for (int i = mPowerComponentsMah.length - 1; i >= 0; i--) {
- mPowerComponentsMah[i] += other.mPowerComponentsMah[i];
+ mPowerComponentsMah[i] += powerComponentsMah[i];
}
for (int i = mUsageDurationsMs.length - 1; i >= 0; i--) {
- mUsageDurationsMs[i] += other.mUsageDurationsMs[i];
+ mUsageDurationsMs[i] += usageDurationsMs[i];
+ }
+ if (mPowerModels != null && powerModels != null) {
+ for (int i = mPowerModels.length - 1; i >= 0; i--) {
+ if (mPowerModels[i] == POWER_MODEL_UNINITIALIZED) {
+ mPowerModels[i] = powerModels[i];
+ } else if (mPowerModels[i] != powerModels[i]
+ && powerModels[i] != POWER_MODEL_UNINITIALIZED) {
+ mPowerModels[i] = BatteryConsumer.POWER_MODEL_UNDEFINED;
+ }
+ }
}
}
@@ -433,6 +593,19 @@ class PowerComponents {
return totalPowerMah;
}
+ private byte[] getPowerModels() {
+ if (mPowerModels == null) {
+ return null;
+ }
+
+ byte[] powerModels = new byte[mPowerModels.length];
+ for (int i = mPowerModels.length - 1; i >= 0; i--) {
+ powerModels[i] = mPowerModels[i] != POWER_MODEL_UNINITIALIZED ? mPowerModels[i]
+ : BatteryConsumer.POWER_MODEL_UNDEFINED;
+ }
+ return powerModels;
+ }
+
/**
* Creates a read-only object out of the Builder values.
*/
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index c33603d26ded..04165564ce1e 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -146,7 +146,7 @@ public class SystemVibratorManager extends VibratorManager {
@Override
public void cancel() {
- cancelVibration(/* usageFilter= */ -1);
+ cancelVibration(VibrationAttributes.USAGE_FILTER_MATCH_ALL);
}
@Override
diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING
index 97e03e9d0d94..55b1f940c764 100644
--- a/core/java/android/os/TEST_MAPPING
+++ b/core/java/android/os/TEST_MAPPING
@@ -40,7 +40,12 @@
]
},
{
- "file_patterns": ["BatteryStats.java"],
+ "file_patterns": [
+ "BatteryStats[^/]*\\.java",
+ "BatteryUsageStats[^/]*\\.java",
+ "PowerComponents\\.java",
+ "[^/]*BatteryConsumer[^/]*\\.java"
+ ],
"name": "FrameworksCoreTests",
"options": [
{ "include-filter": "com.android.internal.os.BatteryStatsTests" },
@@ -48,13 +53,26 @@
]
},
{
- "file_patterns": ["BatteryStats.java"],
+ "file_patterns": [
+ "BatteryStats[^/]*\\.java",
+ "BatteryUsageStats[^/]*\\.java",
+ "PowerComponents\\.java",
+ "[^/]*BatteryConsumer[^/]*\\.java"
+ ],
"name": "FrameworksServicesTests",
"options": [
{ "include-filter": "com.android.server.am.BatteryStatsServiceTest" },
{ "include-filter": "com.android.server.am.MeasuredEnergySnapshotTest" },
{ "include-filter": "com.android.server.am.BatteryExternalStatsWorkerTest" }
]
+ },
+ {
+ "file_patterns": [
+ "BatteryUsageStats[^/]*\\.java",
+ "PowerComponents\\.java",
+ "[^/]*BatteryConsumer[^/]*\\.java"
+ ],
+ "name": "BatteryUsageStatsProtoTests"
}
],
"postsubmit": [
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index 16a6c767da38..bfc4f73835d9 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -19,9 +19,16 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
import com.android.internal.os.PowerCalculator;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -143,13 +150,65 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
return 0;
}
+ /** Serializes this object to XML */
+ void writeToXml(TypedXmlSerializer serializer) throws IOException {
+ if (getConsumedPower() == 0) {
+ return;
+ }
+
+ serializer.startTag(null, BatteryUsageStats.XML_TAG_UID);
+ serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_UID, getUid());
+ if (!TextUtils.isEmpty(mPackageWithHighestDrain)) {
+ serializer.attribute(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE,
+ mPackageWithHighestDrain);
+ }
+ serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND,
+ mTimeInForegroundMs);
+ serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND,
+ mTimeInBackgroundMs);
+ mPowerComponents.writeToXml(serializer);
+ serializer.endTag(null, BatteryUsageStats.XML_TAG_UID);
+ }
+
+ /** Parses an XML representation and populates the BatteryUsageStats builder */
+ static void createFromXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
+ throws XmlPullParserException, IOException {
+ final int uid = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_UID);
+ final UidBatteryConsumer.Builder consumerBuilder =
+ builder.getOrCreateUidBatteryConsumerBuilder(uid);
+
+ int eventType = parser.getEventType();
+ if (eventType != XmlPullParser.START_TAG
+ || !parser.getName().equals(BatteryUsageStats.XML_TAG_UID)) {
+ throw new XmlPullParserException("Invalid XML parser state");
+ }
+
+ consumerBuilder.setPackageWithHighestDrain(
+ parser.getAttributeValue(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE));
+ consumerBuilder.setTimeInStateMs(STATE_FOREGROUND,
+ parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND));
+ consumerBuilder.setTimeInStateMs(STATE_BACKGROUND,
+ parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND));
+ while (!(eventType == XmlPullParser.END_TAG
+ && parser.getName().equals(BatteryUsageStats.XML_TAG_UID))
+ && eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
+ PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
+ }
+ }
+ eventType = parser.next();
+ }
+ }
+
/**
* Builder for UidBatteryConsumer.
*/
public static final class Builder extends BaseBuilder<Builder> {
+ private static final String PACKAGE_NAME_UNINITIALIZED = "";
private final BatteryStats.Uid mBatteryStatsUid;
private final int mUid;
- private String mPackageWithHighestDrain;
+ private String mPackageWithHighestDrain = PACKAGE_NAME_UNINITIALIZED;
public long mTimeInForegroundMs;
public long mTimeInBackgroundMs;
private boolean mExcludeFromBatteryUsageStats;
@@ -161,8 +220,19 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
mUid = batteryStatsUid.getUid();
}
+ public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels,
+ int uid) {
+ super(customPowerComponentNames, includePowerModels);
+ mBatteryStatsUid = null;
+ mUid = uid;
+ }
+
@NonNull
public BatteryStats.Uid getBatteryStatsUid() {
+ if (mBatteryStatsUid == null) {
+ throw new IllegalStateException(
+ "UidBatteryConsumer.Builder was initialized without a BatteryStats.Uid");
+ }
return mBatteryStatsUid;
}
@@ -176,7 +246,7 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
*/
@NonNull
public Builder setPackageWithHighestDrain(@Nullable String packageName) {
- mPackageWithHighestDrain = packageName;
+ mPackageWithHighestDrain = TextUtils.nullIfEmpty(packageName);
return this;
}
@@ -208,6 +278,30 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
}
/**
+ * Adds power and usage duration from the supplied UidBatteryConsumer.
+ */
+ public Builder add(UidBatteryConsumer consumer) {
+ mPowerComponentsBuilder.addPowerAndDuration(consumer.mPowerComponents);
+ mTimeInBackgroundMs += consumer.mTimeInBackgroundMs;
+ mTimeInForegroundMs += consumer.mTimeInForegroundMs;
+
+ if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) {
+ mPackageWithHighestDrain = consumer.mPackageWithHighestDrain;
+ } else if (!TextUtils.equals(mPackageWithHighestDrain,
+ consumer.mPackageWithHighestDrain)) {
+ // Consider combining two UidBatteryConsumers with this distribution
+ // of power drain between packages:
+ // (package1=100, package2=10) and (package1=100, package2=101).
+ // Since we don't know the actual power distribution between packages at this
+ // point, we have no way to correctly declare package1 as the winner.
+ // The naive logic of picking the consumer with the higher total consumed
+ // power would produce an incorrect result.
+ mPackageWithHighestDrain = null;
+ }
+ return this;
+ }
+
+ /**
* Returns true if this UidBatteryConsumer must be excluded from the
* BatteryUsageStats.
*/
@@ -220,6 +314,9 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
*/
@NonNull
public UidBatteryConsumer build() {
+ if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) {
+ mPackageWithHighestDrain = null;
+ }
return new UidBatteryConsumer(this);
}
}
diff --git a/core/java/android/os/UserBatteryConsumer.java b/core/java/android/os/UserBatteryConsumer.java
index 429d2c53a836..b508a8cd98ae 100644
--- a/core/java/android/os/UserBatteryConsumer.java
+++ b/core/java/android/os/UserBatteryConsumer.java
@@ -17,9 +17,15 @@
package android.os;
import android.annotation.NonNull;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
import com.android.internal.os.PowerCalculator;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -85,6 +91,42 @@ public class UserBatteryConsumer extends BatteryConsumer implements Parcelable {
return 0;
}
+ /** Serializes this object to XML */
+ void writeToXml(TypedXmlSerializer serializer) throws IOException {
+ if (getConsumedPower() == 0) {
+ return;
+ }
+
+ serializer.startTag(null, BatteryUsageStats.XML_TAG_USER);
+ serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_USER_ID, getUserId());
+ mPowerComponents.writeToXml(serializer);
+ serializer.endTag(null, BatteryUsageStats.XML_TAG_USER);
+ }
+
+ /** Parses an XML representation and populates the BatteryUsageStats builder */
+ static void createFromXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
+ throws XmlPullParserException, IOException {
+ final int userId = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_USER_ID);
+ final UserBatteryConsumer.Builder consumerBuilder =
+ builder.getOrCreateUserBatteryConsumerBuilder(userId);
+
+ int eventType = parser.getEventType();
+ if (eventType != XmlPullParser.START_TAG
+ || !parser.getName().equals(BatteryUsageStats.XML_TAG_USER)) {
+ throw new XmlPullParserException("Invalid XML parser state");
+ }
+ while (!(eventType == XmlPullParser.END_TAG
+ && parser.getName().equals(BatteryUsageStats.XML_TAG_USER))
+ && eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
+ PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
+ }
+ }
+ eventType = parser.next();
+ }
+ }
+
/**
* Builder for UserBatteryConsumer.
*/
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c22224dd0da2..7edd6e6597b2 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1322,6 +1322,24 @@ public class UserManager {
"disallow_camera_toggle";
/**
+ * This is really not a user restriction in the normal sense. This can't be set to a user,
+ * via UserManager nor via DevicePolicyManager. This is not even set in UserSettingsUtils.
+ * This is defined here purely for convenience within the settings app.
+ *
+ * TODO(b/191306258): Refactor the Settings app to remove the need for this field, and delete it
+ *
+ * Specifies whether biometrics are available to the user. This is used internally only,
+ * as a means of communications between biometric settings and
+ * {@link com.android.settingslib.enterprise.ActionDisabledByAdminControllerFactory}.
+ *
+ * @see {@link android.hardware.biometrics.ParentalControlsUtilsInternal}
+ * @see {@link com.android.settings.biometrics.ParentalControlsUtils}
+ *
+ * @hide
+ */
+ public static final String DISALLOW_BIOMETRIC = "disallow_biometric";
+
+ /**
* Application restriction key that is used to indicate the pending arrival
* of real restrictions for the app.
*
@@ -1415,6 +1433,7 @@ public class UserManager {
DISALLOW_MICROPHONE_TOGGLE,
DISALLOW_CAMERA_TOGGLE,
KEY_RESTRICTIONS_PENDING,
+ DISALLOW_BIOMETRIC,
})
@Retention(RetentionPolicy.SOURCE)
public @interface UserRestrictionKey {}
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index cec323f8b423..43ea2e7810bc 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -63,6 +63,11 @@ public final class VibrationAttributes implements Parcelable {
public @interface Usage{}
/**
+ * Vibration usage filter value to match all usages.
+ * @hide
+ */
+ public static final int USAGE_FILTER_MATCH_ALL = -1;
+ /**
* Vibration usage class value to use when the vibration usage class is unknown.
*/
public static final int USAGE_CLASS_UNKNOWN = 0x0;
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 12d905588e1e..ff692818863a 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -50,6 +50,7 @@ import android.util.TypedXmlSerializer;
import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
+import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -162,6 +163,7 @@ public class ZenModeConfig implements Parcelable {
private static final String RULE_ATT_ENABLED = "enabled";
private static final String RULE_ATT_SNOOZING = "snoozing";
private static final String RULE_ATT_NAME = "name";
+ private static final String RULE_ATT_PKG = "pkg";
private static final String RULE_ATT_COMPONENT = "component";
private static final String RULE_ATT_CONFIG_ACTIVITY = "configActivity";
private static final String RULE_ATT_ZEN = "zen";
@@ -671,11 +673,11 @@ public class ZenModeConfig implements Parcelable {
rt.conditionId = safeUri(parser, RULE_ATT_CONDITION_ID);
rt.component = safeComponentName(parser, RULE_ATT_COMPONENT);
rt.configurationActivity = safeComponentName(parser, RULE_ATT_CONFIG_ACTIVITY);
- rt.pkg = (rt.component != null)
- ? rt.component.getPackageName()
- : (rt.configurationActivity != null)
- ? rt.configurationActivity.getPackageName()
- : null;
+ rt.pkg = XmlUtils.readStringAttribute(parser, RULE_ATT_PKG);
+ if (rt.pkg == null) {
+ // backfill from component, if present. configActivity is not safe to backfill from
+ rt.pkg = rt.component != null ? rt.component.getPackageName() : null;
+ }
rt.creationTime = safeLong(parser, RULE_ATT_CREATION_TIME, 0);
rt.enabler = parser.getAttributeValue(null, RULE_ATT_ENABLER);
rt.condition = readConditionXml(parser);
@@ -697,6 +699,9 @@ public class ZenModeConfig implements Parcelable {
out.attribute(null, RULE_ATT_NAME, rule.name);
}
out.attributeInt(null, RULE_ATT_ZEN, rule.zenMode);
+ if (rule.pkg != null) {
+ out.attribute(null, RULE_ATT_PKG, rule.pkg);
+ }
if (rule.component != null) {
out.attribute(null, RULE_ATT_COMPONENT, rule.component.flattenToString());
}
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 055e71f0077b..8b4c0d9e21f5 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -229,6 +229,7 @@ public abstract class RecognitionService extends Service {
protected abstract void onStopListening(Callback listener);
@Override
+ @SuppressLint("MissingNullability")
public Context createContext(@NonNull ContextParams contextParams) {
if (contextParams.getNextAttributionSource() != null) {
if (mHandler.getLooper().equals(Looper.myLooper())) {
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 4f1354d7eee6..782a992d28e5 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -444,6 +444,13 @@ public final class InputDevice implements Parcelable {
private static final int VIBRATOR_ID_ALL = -1;
+ /**
+ * The device id of input events generated inside accessibility service.
+ * @hide
+ */
+ @TestApi
+ public static final int ACCESSIBILITY_DEVICE_ID = -2;
+
public static final @android.annotation.NonNull Parcelable.Creator<InputDevice> CREATOR =
new Parcelable.Creator<InputDevice>() {
public InputDevice createFromParcel(Parcel in) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c1e394d7456a..5964f632da1a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2371,6 +2371,14 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
/**
+ * Flag to prevent the window from being magnified by the accessibility magnifier.
+ *
+ * TODO(b/190623172): This is a temporary solution and need to find out another way instead.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_NOT_MAGNIFIABLE = 0x00400000;
+
+ /**
* Flag to indicate that the status bar window is in a state such that it forces showing
* the navigation bar unless the navigation bar window is explicitly set to
* {@link View#GONE}.
@@ -2473,6 +2481,7 @@ public interface WindowManager extends ViewManager {
PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
+ PRIVATE_FLAG_NOT_MAGNIFIABLE,
PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
PRIVATE_FLAG_USE_BLAST,
@@ -2553,6 +2562,10 @@ public interface WindowManager extends ViewManager {
equals = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
name = "IS_ROUNDED_CORNERS_OVERLAY"),
@ViewDebug.FlagToString(
+ mask = PRIVATE_FLAG_NOT_MAGNIFIABLE,
+ equals = PRIVATE_FLAG_NOT_MAGNIFIABLE,
+ name = "NOT_MAGNIFIABLE"),
+ @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
equals = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
name = "STATUS_FORCE_SHOW_NAVIGATION"),
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 7668d80d3cb1..81c934dffa47 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -16,6 +16,9 @@
package android.view;
+import static android.os.IInputConstants.POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY;
+import static android.os.IInputConstants.POLICY_FLAG_INPUTFILTER_TRUSTED;
+
import android.annotation.IntDef;
import android.os.PowerManager;
@@ -27,10 +30,13 @@ import java.lang.annotation.RetentionPolicy;
* @hide
*/
public interface WindowManagerPolicyConstants {
- // Policy flags. These flags are also defined in frameworks/base/include/ui/Input.h.
+ // Policy flags. These flags are also defined in frameworks/base/include/ui/Input.h and
+ // frameworks/native/libs/input/android/os/IInputConstants.aidl
int FLAG_WAKE = 0x00000001;
int FLAG_VIRTUAL = 0x00000002;
+ int FLAG_INPUTFILTER_TRUSTED = POLICY_FLAG_INPUTFILTER_TRUSTED;
+ int FLAG_INJECTED_FROM_ACCESSIBILITY = POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY;
int FLAG_INJECTED = 0x01000000;
int FLAG_TRUSTED = 0x02000000;
int FLAG_FILTERED = 0x04000000;
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index ac4554134a44..10ae69118f54 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -16,6 +16,7 @@
package android.view.contentcapture;
import static android.view.contentcapture.ContentCaptureHelper.getSanitizedString;
+import static android.view.contentcapture.ContentCaptureManager.DEBUG;
import static android.view.contentcapture.ContentCaptureManager.NO_SESSION_ID;
import android.annotation.IntDef;
@@ -25,8 +26,12 @@ import android.annotation.SystemApi;
import android.graphics.Insets;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.SpannableString;
import android.util.Log;
import android.view.autofill.AutofillId;
+import android.view.inputmethod.BaseInputConnection;
import com.android.internal.util.Preconditions;
@@ -132,6 +137,9 @@ public final class ContentCaptureEvent implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface EventType{}
+ /** @hide */
+ public static final int MAX_INVALID_VALUE = -1;
+
private final int mSessionId;
private final int mType;
private final long mEventTime;
@@ -143,6 +151,11 @@ public final class ContentCaptureEvent implements Parcelable {
private @Nullable ContentCaptureContext mClientContext;
private @Nullable Insets mInsets;
+ private int mComposingStart = MAX_INVALID_VALUE;
+ private int mComposingEnd = MAX_INVALID_VALUE;
+ private int mSelectionStartIndex = MAX_INVALID_VALUE;
+ private int mSelectionEndIndex = MAX_INVALID_VALUE;
+
/** Only used in the main Content Capture session, no need to parcel */
private boolean mTextHasComposingSpan;
@@ -246,19 +259,75 @@ public final class ContentCaptureEvent implements Parcelable {
/** @hide */
@NonNull
- public ContentCaptureEvent setText(@Nullable CharSequence text, boolean hasComposingSpan) {
+ public ContentCaptureEvent setText(@Nullable CharSequence text) {
mText = text;
- mTextHasComposingSpan = hasComposingSpan;
return this;
}
- /**
- * The value is not parcelled, become false after parcelled.
- * @hide
- */
+ /** @hide */
+ @NonNull
+ public ContentCaptureEvent setComposingIndex(int start, int end) {
+ mComposingStart = start;
+ mComposingEnd = end;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public boolean hasComposingSpan() {
+ return mComposingStart > MAX_INVALID_VALUE;
+ }
+
+ /** @hide */
@NonNull
- public boolean getTextHasComposingSpan() {
- return mTextHasComposingSpan;
+ public ContentCaptureEvent setSelectionIndex(int start, int end) {
+ mSelectionStartIndex = start;
+ mSelectionEndIndex = end;
+ return this;
+ }
+
+ private int getComposingStart() {
+ return mComposingStart;
+ }
+
+ private int getComposingEnd() {
+ return mComposingEnd;
+ }
+
+ private int getSelectionStart() {
+ return mSelectionStartIndex;
+ }
+
+ private int getSelectionEnd() {
+ return mSelectionEndIndex;
+ }
+
+ private void restoreComposingSpan() {
+ if (mComposingStart <= MAX_INVALID_VALUE
+ || mComposingEnd <= MAX_INVALID_VALUE) {
+ return;
+ }
+ if (mText instanceof Spannable) {
+ BaseInputConnection.setComposingSpans((Spannable) mText, mComposingStart,
+ mComposingEnd);
+ } else {
+ Log.w(TAG, "Text is not a Spannable.");
+ }
+ }
+
+ private void restoreSelectionSpans() {
+ if (mSelectionStartIndex <= MAX_INVALID_VALUE
+ || mSelectionEndIndex <= MAX_INVALID_VALUE) {
+ return;
+ }
+
+ if (mText instanceof SpannableString) {
+ SpannableString ss = (SpannableString) mText;
+ ss.setSpan(Selection.SELECTION_START, mSelectionStartIndex, mSelectionStartIndex, 0);
+ ss.setSpan(Selection.SELECTION_END, mSelectionEndIndex, mSelectionEndIndex, 0);
+ } else {
+ Log.w(TAG, "Text is not a SpannableString.");
+ }
}
/** @hide */
@@ -374,7 +443,9 @@ public final class ContentCaptureEvent implements Parcelable {
throw new IllegalArgumentException("mergeEvent(): got "
+ "TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
} else if (eventType == TYPE_VIEW_TEXT_CHANGED) {
- setText(event.getText(), event.getTextHasComposingSpan());
+ setText(event.getText());
+ setComposingIndex(event.getComposingStart(), event.getComposingEnd());
+ setSelectionIndex(event.getSelectionStart(), event.getSelectionEnd());
} else {
Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType)
+ ") does not support this event type.");
@@ -409,6 +480,14 @@ public final class ContentCaptureEvent implements Parcelable {
if (mInsets != null) {
pw.print(", insets="); pw.println(mInsets);
}
+ if (mComposingStart > MAX_INVALID_VALUE) {
+ pw.print(", composing("); pw.print(mComposingStart);
+ pw.print(", "); pw.print(mComposingEnd); pw.print(")");
+ }
+ if (mSelectionStartIndex > MAX_INVALID_VALUE) {
+ pw.print(", selection("); pw.print(mSelectionStartIndex);
+ pw.print(", "); pw.print(mSelectionEndIndex); pw.print(")");
+ }
}
@NonNull
@@ -431,11 +510,13 @@ public final class ContentCaptureEvent implements Parcelable {
string.append(", class=").append(className);
string.append(", id=").append(mNode.getAutofillId());
if (mNode.getText() != null) {
- string.append(", text=").append(getSanitizedString(mNode.getText()));
+ string.append(", text=")
+ .append(DEBUG ? mNode.getText() : getSanitizedString(mNode.getText()));
}
}
if (mText != null) {
- string.append(", text=").append(getSanitizedString(mText));
+ string.append(", text=")
+ .append(DEBUG ? mText : getSanitizedString(mText));
}
if (mClientContext != null) {
string.append(", context=").append(mClientContext);
@@ -443,6 +524,15 @@ public final class ContentCaptureEvent implements Parcelable {
if (mInsets != null) {
string.append(", insets=").append(mInsets);
}
+ if (mComposingStart > MAX_INVALID_VALUE) {
+ string.append(", composing=[")
+ .append(mComposingStart).append(",").append(mComposingEnd).append("]");
+ }
+ if (mSelectionStartIndex > MAX_INVALID_VALUE) {
+ string.append(", selection=[")
+ .append(mSelectionStartIndex).append(",")
+ .append(mSelectionEndIndex).append("]");
+ }
return string.append(']').toString();
}
@@ -469,6 +559,12 @@ public final class ContentCaptureEvent implements Parcelable {
if (mType == TYPE_VIEW_INSETS_CHANGED) {
parcel.writeParcelable(mInsets, flags);
}
+ if (mType == TYPE_VIEW_TEXT_CHANGED) {
+ parcel.writeInt(mComposingStart);
+ parcel.writeInt(mComposingEnd);
+ parcel.writeInt(mSelectionStartIndex);
+ parcel.writeInt(mSelectionEndIndex);
+ }
}
public static final @android.annotation.NonNull Parcelable.Creator<ContentCaptureEvent> CREATOR =
@@ -493,7 +589,7 @@ public final class ContentCaptureEvent implements Parcelable {
if (node != null) {
event.setViewNode(node);
}
- event.setText(parcel.readCharSequence(), false);
+ event.setText(parcel.readCharSequence());
if (type == TYPE_SESSION_STARTED || type == TYPE_SESSION_FINISHED) {
event.setParentSessionId(parcel.readInt());
}
@@ -503,6 +599,12 @@ public final class ContentCaptureEvent implements Parcelable {
if (type == TYPE_VIEW_INSETS_CHANGED) {
event.setInsets(parcel.readParcelable(null));
}
+ if (type == TYPE_VIEW_TEXT_CHANGED) {
+ event.setComposingIndex(parcel.readInt(), parcel.readInt());
+ event.restoreComposingSpan();
+ event.setSelectionIndex(parcel.readInt(), parcel.readInt());
+ event.restoreSelectionSpans();
+ }
return event;
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index ed840ce3061b..9241c3074ddd 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -212,6 +212,9 @@ public final class ContentCaptureManager {
private static final String TAG = ContentCaptureManager.class.getSimpleName();
+ /** @hide */
+ public static final boolean DEBUG = false;
+
/** Error happened during the data sharing session. */
public static final int DATA_SHARE_ERROR_UNKNOWN = 1;
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index aee540f466bf..d8ac779ddc27 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -43,6 +43,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
+import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -347,8 +348,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
// 2.2 last event doesn't have composing span: add.
// Otherwise, merge.
final CharSequence text = event.getText();
- final boolean textHasComposingSpan = event.getTextHasComposingSpan();
- if (textHasComposingSpan) {
+ final boolean hasComposingSpan = event.hasComposingSpan();
+ if (hasComposingSpan) {
ContentCaptureEvent lastEvent = null;
for (int index = mEvents.size() - 1; index >= 0; index--) {
final ContentCaptureEvent tmpEvent = mEvents.get(index);
@@ -357,7 +358,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
break;
}
}
- if (lastEvent != null && lastEvent.getTextHasComposingSpan()) {
+ if (lastEvent != null && lastEvent.hasComposingSpan()) {
final CharSequence lastText = lastEvent.getText();
final boolean bothNonEmpty = !TextUtils.isEmpty(lastText)
&& !TextUtils.isEmpty(text);
@@ -705,12 +706,24 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
// a copy of its content so that its value will not be changed by subsequent updates
// in the TextView.
final CharSequence eventText = stringOrSpannedStringWithoutNoCopySpans(text);
- final boolean textHasComposingSpan =
- text instanceof Spannable && BaseInputConnection.getComposingSpanStart(
- (Spannable) text) >= 0;
+
+ final int composingStart;
+ final int composingEnd;
+ if (text instanceof Spannable) {
+ composingStart = BaseInputConnection.getComposingSpanStart((Spannable) text);
+ composingEnd = BaseInputConnection.getComposingSpanEnd((Spannable) text);
+ } else {
+ composingStart = ContentCaptureEvent.MAX_INVALID_VALUE;
+ composingEnd = ContentCaptureEvent.MAX_INVALID_VALUE;
+ }
+
+ final int startIndex = Selection.getSelectionStart(text);
+ final int endIndex = Selection.getSelectionEnd(text);
mHandler.post(() -> sendEvent(
new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED)
- .setAutofillId(id).setText(eventText, textHasComposingSpan)));
+ .setAutofillId(id).setText(eventText)
+ .setComposingIndex(composingStart, composingEnd)
+ .setSelectionIndex(startIndex, endIndex)));
}
private CharSequence stringOrSpannedStringWithoutNoCopySpans(CharSequence source) {
diff --git a/core/java/android/window/ITaskOrganizer.aidl b/core/java/android/window/ITaskOrganizer.aidl
index 3eb35c2c5e8a..8b8dba89ea67 100644
--- a/core/java/android/window/ITaskOrganizer.aidl
+++ b/core/java/android/window/ITaskOrganizer.aidl
@@ -52,6 +52,11 @@ oneway interface ITaskOrganizer {
void copySplashScreenView(int taskId);
/**
+ * Called when the Task removed the splash screen.
+ */
+ void onAppSplashScreenViewRemoved(int taskId);
+
+ /**
* A callback when the Task is available for the registered organizer. The client is responsible
* for releasing the SurfaceControl in the callback. For non-root tasks, the leash may initially
* be hidden so it is up to the organizer to show this task.
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 6772afeb0270..4a3bf91645f2 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -34,8 +34,10 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.RemoteCallback;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.Log;
@@ -76,7 +78,7 @@ import java.time.Instant;
*/
public final class SplashScreenView extends FrameLayout {
private static final String TAG = SplashScreenView.class.getSimpleName();
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Build.IS_DEBUGGABLE;
private static final int LIGHT_BARS_MASK =
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
@@ -85,6 +87,7 @@ public final class SplashScreenView extends FrameLayout {
| FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS;
private boolean mNotCopyable;
+ private boolean mIsCopied;
private int mInitBackgroundColor;
private int mInitIconBackgroundColor;
private View mIconView;
@@ -103,6 +106,10 @@ public final class SplashScreenView extends FrameLayout {
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
@Nullable
private SurfaceView mSurfaceView;
+ @Nullable
+ private SurfaceControlViewHost mSurfaceHost;
+ @Nullable
+ private RemoteCallback mClientCallback;
// cache original window and status
private Window mWindow;
@@ -127,6 +134,7 @@ public final class SplashScreenView extends FrameLayout {
private Bitmap mParceledIconBitmap;
private Drawable mIconDrawable;
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
+ private RemoteCallback mClientCallback;
private int mBrandingImageWidth;
private int mBrandingImageHeight;
private Drawable mBrandingDrawable;
@@ -161,6 +169,7 @@ public final class SplashScreenView extends FrameLayout {
}
mIconAnimationStart = Instant.ofEpochMilli(parcelable.mIconAnimationStartMillis);
mIconAnimationDuration = Duration.ofMillis(parcelable.mIconAnimationDurationMillis);
+ mClientCallback = parcelable.mClientCallback;
if (DEBUG) {
Log.d(TAG, String.format("Building from parcel drawable: %s", mIconDrawable));
}
@@ -228,6 +237,7 @@ public final class SplashScreenView extends FrameLayout {
view.mInitBackgroundColor = mBackgroundColor;
view.mInitIconBackgroundColor = mIconBackground;
view.setBackgroundColor(mBackgroundColor);
+ view.mClientCallback = mClientCallback;
view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
@@ -285,7 +295,8 @@ public final class SplashScreenView extends FrameLayout {
if (mSurfacePackage == null) {
if (DEBUG) {
Log.d(TAG,
- "Creating Original SurfacePackage. SurfaceView: " + surfaceView);
+ "SurfaceControlViewHost created on thread "
+ + Thread.currentThread().getId());
}
SurfaceControlViewHost viewHost = new SurfaceControlViewHost(mContext,
@@ -297,6 +308,7 @@ public final class SplashScreenView extends FrameLayout {
SurfaceControlViewHost.SurfacePackage surfacePackage = viewHost.getSurfacePackage();
surfaceView.setChildSurfacePackage(surfacePackage);
view.mSurfacePackage = surfacePackage;
+ view.mSurfaceHost = viewHost;
view.mSurfacePackageCopy = new SurfaceControlViewHost.SurfacePackage(
surfacePackage);
} else {
@@ -357,6 +369,7 @@ public final class SplashScreenView extends FrameLayout {
* @hide
*/
public void onCopied() {
+ mIsCopied = true;
if (mSurfaceView == null) {
return;
}
@@ -369,6 +382,12 @@ public final class SplashScreenView extends FrameLayout {
mSurfacePackage = null;
}
+ /** @hide **/
+ @Nullable
+ public SurfaceControlViewHost getSurfaceHost() {
+ return mSurfaceHost;
+ }
+
@Override
public void setAlpha(float alpha) {
super.setAlpha(alpha);
@@ -407,8 +426,7 @@ public final class SplashScreenView extends FrameLayout {
if (DEBUG) {
mSurfacePackage.getSurfaceControl().addOnReparentListener(
(transaction, parent) -> Log.e(TAG,
- String.format("SurfacePackage'surface reparented.\n Parent: %s",
- parent), new Throwable()));
+ String.format("SurfacePackage'surface reparented to %s", parent)));
Log.d(TAG, "Transferring surface " + mSurfaceView.toString());
}
mSurfaceView.setChildSurfacePackage(mSurfacePackage);
@@ -466,9 +484,36 @@ public final class SplashScreenView extends FrameLayout {
mHasRemoved = true;
}
+ /** @hide **/
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ releaseAnimationSurfaceHost();
+ }
+
+ private void releaseAnimationSurfaceHost() {
+ if (mSurfaceHost != null && !mIsCopied) {
+ final SurfaceControlViewHost finalSurfaceHost = mSurfaceHost;
+ mSurfaceHost = null;
+ finalSurfaceHost.getView().post(() -> {
+ if (DEBUG) {
+ Log.d(TAG,
+ "Shell removed splash screen."
+ + " Releasing SurfaceControlViewHost on thread #"
+ + Thread.currentThread().getId());
+ }
+ finalSurfaceHost.release();
+ });
+ } else if (mSurfacePackage != null && mSurfaceHost == null) {
+ mSurfacePackage = null;
+ mClientCallback.sendResult(null);
+ }
+ }
+
/**
* Called when this view is attached to an activity. This also makes SystemUI colors
* transparent so the content of splash screen view can draw fully.
+ *
* @hide
*/
public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) {
@@ -585,6 +630,7 @@ public final class SplashScreenView extends FrameLayout {
private long mIconAnimationDurationMillis;
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
+ private RemoteCallback mClientCallback;
public SplashScreenViewParcelable(SplashScreenView view) {
mIconSize = view.mIconView.getWidth();
@@ -641,6 +687,7 @@ public final class SplashScreenView extends FrameLayout {
mIconAnimationDurationMillis = source.readLong();
mIconBackground = source.readInt();
mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
+ mClientCallback = source.readTypedObject(RemoteCallback.CREATOR);
}
@Override
@@ -660,6 +707,7 @@ public final class SplashScreenView extends FrameLayout {
dest.writeLong(mIconAnimationDurationMillis);
dest.writeInt(mIconBackground);
dest.writeTypedObject(mSurfacePackage, flags);
+ dest.writeTypedObject(mClientCallback, flags);
}
public static final @NonNull Parcelable.Creator<SplashScreenViewParcelable> CREATOR =
@@ -697,5 +745,13 @@ public final class SplashScreenView extends FrameLayout {
int getIconBackground() {
return mIconBackground;
}
+
+ /**
+ * Sets the {@link RemoteCallback} that will be called by the client to notify the shell
+ * of the removal of the {@link SplashScreenView}.
+ */
+ public void setClientCallback(@NonNull RemoteCallback clientCallback) {
+ mClientCallback = clientCallback;
+ }
}
}
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index 3340cf4fb707..73995491668a 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -117,6 +117,16 @@ public class TaskOrganizer extends WindowOrganizer {
public void copySplashScreenView(int taskId) {}
/**
+ * Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
+ * removed the splash screen view.
+ * @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
+ * @see SplashScreenView#remove()
+ */
+ @BinderThread
+ public void onAppSplashScreenViewRemoved(int taskId) {
+ }
+
+ /**
* Called when a task with the registered windowing mode can be controlled by this task
* organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
* to show this task.
@@ -236,11 +246,16 @@ public class TaskOrganizer extends WindowOrganizer {
}
@Override
- public void copySplashScreenView(int taskId) {
+ public void copySplashScreenView(int taskId) {
mExecutor.execute(() -> TaskOrganizer.this.copySplashScreenView(taskId));
}
@Override
+ public void onAppSplashScreenViewRemoved(int taskId) {
+ mExecutor.execute(() -> TaskOrganizer.this.onAppSplashScreenViewRemoved(taskId));
+ }
+
+ @Override
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
mExecutor.execute(() -> TaskOrganizer.this.onTaskAppeared(taskInfo, leash));
}
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index bd908900fccc..19183b8eb9e7 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -31,9 +31,6 @@ import android.provider.Settings;
import android.util.MathUtils;
import android.view.Display;
-import java.util.LinkedList;
-import java.util.Queue;
-
/**
* BrightnessSynchronizer helps convert between the int (old) system and float
* (new) system for storing the brightness. It has methods to convert between the two and also
@@ -43,12 +40,11 @@ public class BrightnessSynchronizer {
private static final int MSG_UPDATE_FLOAT = 1;
private static final int MSG_UPDATE_INT = 2;
+ private static final int MSG_UPDATE_BOTH = 3;
private static final String TAG = "BrightnessSynchronizer";
private static final Uri BRIGHTNESS_URI =
Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
- private static final Uri BRIGHTNESS_FLOAT_URI =
- Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FLOAT);
// The tolerance within which we consider brightness values approximately equal to eachother.
// This value is approximately 1/3 of the smallest possible brightness value.
@@ -57,8 +53,6 @@ public class BrightnessSynchronizer {
private DisplayManager mDisplayManager;
private final Context mContext;
- private final Queue<Object> mWriteHistory = new LinkedList<>();
-
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
@@ -69,6 +63,9 @@ public class BrightnessSynchronizer {
case MSG_UPDATE_INT:
updateBrightnessIntFromFloat(Float.intBitsToFloat(msg.arg1));
break;
+ case MSG_UPDATE_BOTH:
+ updateBoth(Float.intBitsToFloat(msg.arg1));
+ break;
default:
super.handleMessage(msg);
}
@@ -139,7 +136,7 @@ public class BrightnessSynchronizer {
/**
* Translates specified value from the float brightness system to the int brightness system,
- * given the min/max of each range. Accounts for special values such as OFF and invalid values.
+ * given the min/max of each range. Accounts for special values such as OFF and invalid values.
* Value returned as a float primitive (to preserve precision), but is a value within the
* int-system range.
*/
@@ -168,49 +165,63 @@ public class BrightnessSynchronizer {
}
/**
- * Updates the float setting based on a passed in int value. This is called whenever the int
- * setting changes. mWriteHistory keeps a record of the values that been written to the settings
- * from either this method or updateBrightnessIntFromFloat. This is to ensure that the value
- * being set is due to an external value being set, rather than the updateBrightness* methods.
- * The intention of this is to avoid race conditions when the setting is being changed
- * frequently and to ensure we are not reacting to settings changes from this file.
+ * Updates the settings based on a passed in int value. This is called whenever the int
+ * setting changes. mPreferredSettingValue holds the most recently updated brightness value
+ * as a float that we would like the display to be set to.
+ *
+ * We then schedule an update to both the int and float settings, but, remove all the other
+ * messages to update all, to prevent us getting stuck in a loop.
+ *
* @param value Brightness value as int to store in the float setting.
*/
private void updateBrightnessFloatFromInt(int value) {
- Object topOfQueue = mWriteHistory.peek();
- if (topOfQueue != null && topOfQueue.equals(value)) {
- mWriteHistory.poll();
- } else {
- if (brightnessFloatToInt(mPreferredSettingValue) == value) {
- return;
- }
- float newBrightnessFloat = brightnessIntToFloat(value);
- mWriteHistory.offer(newBrightnessFloat);
- mPreferredSettingValue = newBrightnessFloat;
- mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, newBrightnessFloat);
+ if (brightnessFloatToInt(mPreferredSettingValue) == value) {
+ return;
}
+
+ mPreferredSettingValue = brightnessIntToFloat(value);
+ final int newBrightnessAsIntBits = Float.floatToIntBits(mPreferredSettingValue);
+ mHandler.removeMessages(MSG_UPDATE_BOTH);
+ mHandler.obtainMessage(MSG_UPDATE_BOTH, newBrightnessAsIntBits, 0).sendToTarget();
}
/**
- * Updates the int setting based on a passed in float value. This is called whenever the float
- * setting changes. mWriteHistory keeps a record of the values that been written to the settings
- * from either this method or updateBrightnessFloatFromInt. This is to ensure that the value
- * being set is due to an external value being set, rather than the updateBrightness* methods.
- * The intention of this is to avoid race conditions when the setting is being changed
- * frequently and to ensure we are not reacting to settings changes from this file.
+ * Updates the settings based on a passed in float value. This is called whenever the float
+ * setting changes. mPreferredSettingValue holds the most recently updated brightness value
+ * as a float that we would like the display to be set to.
+ *
+ * We then schedule an update to both the int and float settings, but, remove all the other
+ * messages to update all, to prevent us getting stuck in a loop.
+ *
* @param value Brightness setting as float to store in int setting.
*/
private void updateBrightnessIntFromFloat(float value) {
- int newBrightnessInt = brightnessFloatToInt(value);
- Object topOfQueue = mWriteHistory.peek();
- if (topOfQueue != null && topOfQueue.equals(value)) {
- mWriteHistory.poll();
- } else {
- mWriteHistory.offer(newBrightnessInt);
- mPreferredSettingValue = value;
+ if (floatEquals(mPreferredSettingValue, value)) {
+ return;
+ }
+
+ mPreferredSettingValue = value;
+ final int newBrightnessAsIntBits = Float.floatToIntBits(mPreferredSettingValue);
+ mHandler.removeMessages(MSG_UPDATE_BOTH);
+ mHandler.obtainMessage(MSG_UPDATE_BOTH, newBrightnessAsIntBits, 0).sendToTarget();
+ }
+
+
+ /**
+ * Updates both setting values if they have changed
+ * mDisplayManager.setBrightness automatically checks for changes
+ * Settings.System.putIntForUser needs to be checked, to prevent an extra callback to this class
+ *
+ * @param newBrightnessFloat Brightness setting as float to store in both settings
+ */
+ private void updateBoth(float newBrightnessFloat) {
+ int newBrightnessInt = brightnessFloatToInt(newBrightnessFloat);
+ mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, newBrightnessFloat);
+ if (getScreenBrightnessInt(mContext) != newBrightnessInt) {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, newBrightnessInt, UserHandle.USER_CURRENT);
}
+
}
/**
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 26d6a0c74b08..aabcd7f82ac7 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -43,6 +43,10 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_PAGE_SCROLL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_COLLAPSE_LOCK;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
@@ -53,6 +57,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_EXPAND;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_SWIPE;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_SCROLL_FLING;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -153,6 +158,11 @@ public class InteractionJankMonitor {
public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET = 27;
public static final int CUJ_SETTINGS_PAGE_SCROLL = 28;
public static final int CUJ_LOCKSCREEN_UNLOCK_ANIMATION = 29;
+ public static final int CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON = 30;
+ public static final int CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER = 31;
+ public static final int CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE = 32;
+ public static final int CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON = 33;
+ public static final int CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP = 34;
private static final int NO_STATSD_LOGGING = -1;
@@ -191,6 +201,11 @@ public class InteractionJankMonitor {
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_WIDGET,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_PAGE_SCROLL,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_UNLOCK_ANIMATION,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
};
private static volatile InteractionJankMonitor sInstance;
@@ -240,6 +255,11 @@ public class InteractionJankMonitor {
CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET,
CUJ_SETTINGS_PAGE_SCROLL,
CUJ_LOCKSCREEN_UNLOCK_ANIMATION,
+ CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON,
+ CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER,
+ CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE,
+ CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON,
+ CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -578,6 +598,16 @@ public class InteractionJankMonitor {
return "SETTINGS_PAGE_SCROLL";
case CUJ_LOCKSCREEN_UNLOCK_ANIMATION:
return "LOCKSCREEN_UNLOCK_ANIMATION";
+ case CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON:
+ return "SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON";
+ case CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER:
+ return "SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER";
+ case CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE:
+ return "SHADE_APP_LAUNCH_FROM_QS_TILE";
+ case CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON:
+ return "SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON";
+ case CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP:
+ return "STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5dfc5faead43..945a6ab11856 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -341,6 +341,19 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
+ /**
+ * Listener for the battery stats reset.
+ */
+ public interface BatteryResetListener {
+
+ /**
+ * Callback invoked immediately prior to resetting battery stats.
+ */
+ void prepareForBatteryStatsReset();
+ }
+
+ private BatteryResetListener mBatteryResetListener;
+
public interface BatteryCallback {
public void batteryNeedsCpuUpdate();
public void batteryPowerChanged(boolean onBattery);
@@ -10736,6 +10749,10 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
+ PowerProfile getPowerProfile() {
+ return mPowerProfile;
+ }
+
/**
* Starts tracking CPU time-in-state for threads of the system server process,
* keeping a separate account of threads receiving incoming binder calls.
@@ -11184,6 +11201,10 @@ public class BatteryStatsImpl extends BatteryStats {
mDischargeCounter.reset(false, elapsedRealtimeUs);
}
+ public void setBatteryResetListener(BatteryResetListener batteryResetListener) {
+ mBatteryResetListener = batteryResetListener;
+ }
+
public void resetAllStatsCmdLocked() {
final long mSecUptime = mClocks.uptimeMillis();
long uptimeUs = mSecUptime * 1000;
@@ -11219,6 +11240,10 @@ public class BatteryStatsImpl extends BatteryStats {
}
private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis) {
+ if (mBatteryResetListener != null) {
+ mBatteryResetListener.prepareForBatteryStatsReset();
+ }
+
final long uptimeUs = uptimeMillis * 1000;
final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000;
mStartCount = 0;
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index 3aaccdd71844..8943db6c8a1e 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -38,14 +38,24 @@ import java.util.Map;
public class BatteryUsageStatsProvider {
private final Context mContext;
private final BatteryStats mStats;
+ private final BatteryUsageStatsStore mBatteryUsageStatsStore;
private final PowerProfile mPowerProfile;
private final Object mLock = new Object();
private List<PowerCalculator> mPowerCalculators;
public BatteryUsageStatsProvider(Context context, BatteryStats stats) {
+ this(context, stats, null);
+ }
+
+ @VisibleForTesting
+ public BatteryUsageStatsProvider(Context context, BatteryStats stats,
+ BatteryUsageStatsStore batteryUsageStatsStore) {
mContext = context;
mStats = stats;
- mPowerProfile = new PowerProfile(mContext);
+ mBatteryUsageStatsStore = batteryUsageStatsStore;
+ mPowerProfile = stats instanceof BatteryStatsImpl
+ ? ((BatteryStatsImpl) stats).getPowerProfile()
+ : new PowerProfile(context);
}
private List<PowerCalculator> getPowerCalculators() {
@@ -126,6 +136,15 @@ public class BatteryUsageStatsProvider {
private BatteryUsageStats getBatteryUsageStats(BatteryUsageStatsQuery query,
long currentTimeMs) {
+ if (query.getToTimestamp() == 0) {
+ return getCurrentBatteryUsageStats(query, currentTimeMs);
+ } else {
+ return getAggregatedBatteryUsageStats(query);
+ }
+ }
+
+ private BatteryUsageStats getCurrentBatteryUsageStats(BatteryUsageStatsQuery query,
+ long currentTimeMs) {
final long realtimeUs = elapsedRealtime() * 1000;
final long uptimeUs = uptimeMillis() * 1000;
@@ -209,6 +228,25 @@ public class BatteryUsageStatsProvider {
BatteryStats.STATS_SINCE_CHARGED) / 1000;
}
+ private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryUsageStatsQuery query) {
+ final boolean includePowerModels = (query.getFlags()
+ & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
+
+ final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
+ mStats.getCustomEnergyConsumerNames(), includePowerModels);
+ final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps();
+ for (long timestamp : timestamps) {
+ if (timestamp > query.getFromTimestamp() && timestamp <= query.getToTimestamp()) {
+ final BatteryUsageStats snapshot =
+ mBatteryUsageStatsStore.loadBatteryUsageStats(timestamp);
+ if (snapshot != null) {
+ builder.add(snapshot);
+ }
+ }
+ }
+ return builder.build();
+ }
+
private long elapsedRealtime() {
if (mStats instanceof BatteryStatsImpl) {
return ((BatteryStatsImpl) mStats).mClocks.elapsedRealtime();
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsStore.java b/core/java/com/android/internal/os/BatteryUsageStatsStore.java
new file mode 100644
index 000000000000..5c976025d39d
--- /dev/null
+++ b/core/java/com/android/internal/os/BatteryUsageStatsStore.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
+import android.os.Handler;
+import android.util.AtomicFile;
+import android.util.LongArray;
+import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.StandardOpenOption;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+/**
+ * A storage mechanism for BatteryUsageStats snapshots.
+ */
+public class BatteryUsageStatsStore {
+ private static final String TAG = "BatteryUsageStatsStore";
+
+ private static final List<BatteryUsageStatsQuery> BATTERY_USAGE_STATS_QUERY = List.of(
+ new BatteryUsageStatsQuery.Builder()
+ .setMaxStatsAgeMs(0)
+ .includePowerModels()
+ .build());
+ private static final String BATTERY_USAGE_STATS_DIR = "battery-usage-stats";
+ private static final String SNAPSHOT_FILE_EXTENSION = ".bus";
+ private static final String DIR_LOCK_FILENAME = ".lock";
+ private static final String CONFIG_FILENAME = "config";
+ private static final String BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY =
+ "BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP";
+ private static final long MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES = 100 * 1024;
+
+ private final Context mContext;
+ private final BatteryStatsImpl mBatteryStats;
+ private final File mStoreDir;
+ private final File mLockFile;
+ private final AtomicFile mConfigFile;
+ private final long mMaxStorageBytes;
+ private final Handler mHandler;
+ private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
+
+ public BatteryUsageStatsStore(Context context, BatteryStatsImpl stats, File systemDir,
+ Handler handler) {
+ this(context, stats, systemDir, handler, MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES);
+ }
+
+ @VisibleForTesting
+ public BatteryUsageStatsStore(Context context, BatteryStatsImpl batteryStats, File systemDir,
+ Handler handler, long maxStorageBytes) {
+ mContext = context;
+ mBatteryStats = batteryStats;
+ mStoreDir = new File(systemDir, BATTERY_USAGE_STATS_DIR);
+ mLockFile = new File(mStoreDir, DIR_LOCK_FILENAME);
+ mConfigFile = new AtomicFile(new File(mStoreDir, CONFIG_FILENAME));
+ mHandler = handler;
+ mMaxStorageBytes = maxStorageBytes;
+ mBatteryStats.setBatteryResetListener(this::prepareForBatteryStatsReset);
+ mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(mContext, mBatteryStats);
+ }
+
+ private void prepareForBatteryStatsReset() {
+ final List<BatteryUsageStats> stats =
+ mBatteryUsageStatsProvider.getBatteryUsageStats(BATTERY_USAGE_STATS_QUERY);
+ if (stats.isEmpty()) {
+ Slog.wtf(TAG, "No battery usage stats generated");
+ return;
+ }
+
+ mHandler.post(() -> storeBatteryUsageStats(stats.get(0)));
+ }
+
+ private void storeBatteryUsageStats(BatteryUsageStats stats) {
+ try (FileLock lock = lockSnapshotDirectory()) {
+ if (!mStoreDir.exists()) {
+ if (!mStoreDir.mkdirs()) {
+ Slog.e(TAG,
+ "Could not create a directory for battery usage stats snapshots");
+ return;
+ }
+ }
+ File file = makeSnapshotFilename(stats.getStatsEndTimestamp());
+ try {
+ writeXmlFileLocked(stats, file);
+ } catch (Exception e) {
+ Slog.e(TAG, "Cannot save battery usage stats", e);
+ }
+
+ removeOldSnapshotsLocked();
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ }
+ }
+
+ /**
+ * Returns the timestamps of the stored BatteryUsageStats snapshots. The timestamp corresponds
+ * to the time the snapshot was taken {@link BatteryUsageStats#getStatsEndTimestamp()}.
+ */
+ public long[] listBatteryUsageStatsTimestamps() {
+ LongArray timestamps = new LongArray(100);
+ try (FileLock lock = lockSnapshotDirectory()) {
+ for (File file : mStoreDir.listFiles()) {
+ String fileName = file.getName();
+ if (fileName.endsWith(SNAPSHOT_FILE_EXTENSION)) {
+ try {
+ String fileNameWithoutExtension = fileName.substring(0,
+ fileName.length() - SNAPSHOT_FILE_EXTENSION.length());
+ timestamps.add(Long.parseLong(fileNameWithoutExtension));
+ } catch (NumberFormatException e) {
+ Slog.wtf(TAG, "Invalid format of BatteryUsageStats snapshot file name: "
+ + fileName);
+ }
+ }
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ }
+ return timestamps.toArray();
+ }
+
+ /**
+ * Reads the specified snapshot of BatteryUsageStats. Returns null if the snapshot
+ * does not exist.
+ */
+ @Nullable
+ public BatteryUsageStats loadBatteryUsageStats(long timestamp) {
+ try (FileLock lock = lockSnapshotDirectory()) {
+ File file = makeSnapshotFilename(timestamp);
+ try {
+ return readXmlFileLocked(file);
+ } catch (Exception e) {
+ Slog.e(TAG, "Cannot read battery usage stats", e);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ }
+ return null;
+ }
+
+ /**
+ * Saves the supplied timestamp of the BATTERY_USAGE_STATS_BEFORE_RESET statsd atom pull
+ * in persistent file.
+ */
+ public void setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(long timestamp) {
+ Properties props = new Properties();
+ try (FileLock lock = lockSnapshotDirectory()) {
+ try (InputStream in = mConfigFile.openRead()) {
+ props.load(in);
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot load config file " + mConfigFile, e);
+ }
+ props.put(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY,
+ String.valueOf(timestamp));
+ FileOutputStream out = null;
+ try {
+ out = mConfigFile.startWrite();
+ props.store(out, "Statsd atom pull timestamps");
+ mConfigFile.finishWrite(out);
+ } catch (IOException e) {
+ mConfigFile.failWrite(out);
+ Slog.e(TAG, "Cannot save config file " + mConfigFile, e);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ }
+ }
+
+ /**
+ * Retrieves the previously saved timestamp of the last BATTERY_USAGE_STATS_BEFORE_RESET
+ * statsd atom pull.
+ */
+ public long getLastBatteryUsageStatsBeforeResetAtomPullTimestamp() {
+ Properties props = new Properties();
+ try (FileLock lock = lockSnapshotDirectory()) {
+ try (InputStream in = mConfigFile.openRead()) {
+ props.load(in);
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot load config file " + mConfigFile, e);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ }
+ return Long.parseLong(
+ props.getProperty(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY, "0"));
+ }
+
+ private FileLock lockSnapshotDirectory() throws IOException {
+ mLockFile.getParentFile().mkdirs();
+ mLockFile.createNewFile();
+ return FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock();
+ }
+
+ /**
+ * Creates a file name by formatting the timestamp as 19-digit zero-padded number.
+ * This ensures that sorted directory list follows the chronological order.
+ */
+ private File makeSnapshotFilename(long statsEndTimestamp) {
+ return new File(mStoreDir, String.format(Locale.ENGLISH, "%019d", statsEndTimestamp)
+ + SNAPSHOT_FILE_EXTENSION);
+ }
+
+ private void writeXmlFileLocked(BatteryUsageStats stats, File file) throws IOException {
+ try (OutputStream out = new FileOutputStream(file)) {
+ TypedXmlSerializer serializer = Xml.newBinarySerializer();
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ stats.writeXml(serializer);
+ serializer.endDocument();
+ }
+ }
+
+ private BatteryUsageStats readXmlFileLocked(File file)
+ throws IOException, XmlPullParserException {
+ try (InputStream in = new FileInputStream(file)) {
+ TypedXmlPullParser parser = Xml.newBinaryPullParser();
+ parser.setInput(in, StandardCharsets.UTF_8.name());
+ return BatteryUsageStats.createFromXml(parser);
+ }
+ }
+
+ private void removeOldSnapshotsLocked() {
+ // Read the directory list into a _sorted_ map. The alphanumeric ordering
+ // corresponds to the historical order of snapshots because the file names
+ // are timestamps zero-padded to the same length.
+ long totalSize = 0;
+ TreeMap<File, Long> mFileSizes = new TreeMap<>();
+ for (File file : mStoreDir.listFiles()) {
+ final long fileSize = file.length();
+ totalSize += fileSize;
+ if (file.getName().endsWith(SNAPSHOT_FILE_EXTENSION)) {
+ mFileSizes.put(file, fileSize);
+ }
+ }
+
+ while (totalSize > mMaxStorageBytes) {
+ final Map.Entry<File, Long> entry = mFileSizes.firstEntry();
+ if (entry == null) {
+ break;
+ }
+
+ File file = entry.getKey();
+ if (!file.delete()) {
+ Slog.e(TAG, "Cannot delete battery usage stats " + file);
+ }
+ totalSize -= entry.getValue();
+ mFileSizes.remove(file);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index 2b22f08652e7..5a5165ddd7e2 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -14,6 +14,14 @@
},
{
"file_patterns": [
+ "Battery[^/]*\\.java",
+ "Kernel[^/]*\\.java",
+ "[^/]*Power[^/]*\\.java"
+ ],
+ "name": "BatteryUsageStatsProtoTests"
+ },
+ {
+ "file_patterns": [
"BinderDeathDispatcher\\.java"
],
"name": "FrameworksCoreTests",
@@ -23,7 +31,11 @@
]
},
{
- "file_patterns": ["Battery[^/]*\\.java"],
+ "file_patterns": [
+ "Battery[^/]*\\.java",
+ "Kernel[^/]*\\.java",
+ "[^/]*Power[^/]*\\.java"
+ ],
"name": "FrameworksServicesTests",
"options": [
{ "include-filter": "com.android.server.am.BatteryStatsServiceTest" },
diff --git a/core/java/com/android/internal/view/inline/InlineTooltipUi.java b/core/java/com/android/internal/view/inline/InlineTooltipUi.java
index 5ec8b30d6a7b..25fa678d0507 100644
--- a/core/java/com/android/internal/view/inline/InlineTooltipUi.java
+++ b/core/java/com/android/internal/view/inline/InlineTooltipUi.java
@@ -213,6 +213,8 @@ public final class InlineTooltipUi extends PopupWindow implements AutoCloseable
if (!mShowing) {
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ params.privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_NOT_MAGNIFIABLE;
mContentContainer.addOnLayoutChangeListener(mAnchoredOnLayoutChangeListener);
mWm.addView(mContentContainer, params);
mShowing = true;
diff --git a/core/java/com/android/internal/widget/EmphasizedNotificationButton.java b/core/java/com/android/internal/widget/EmphasizedNotificationButton.java
index 4460e4a0ea78..ce6af49eef0b 100644
--- a/core/java/com/android/internal/widget/EmphasizedNotificationButton.java
+++ b/core/java/com/android/internal/widget/EmphasizedNotificationButton.java
@@ -40,6 +40,7 @@ import com.android.internal.R;
@RemoteViews.RemoteView
public class EmphasizedNotificationButton extends Button {
private final RippleDrawable mRipple;
+ private final GradientDrawable mBackground;
private boolean mPriority;
public EmphasizedNotificationButton(Context context) {
@@ -57,9 +58,10 @@ public class EmphasizedNotificationButton extends Button {
public EmphasizedNotificationButton(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- DrawableWrapper background = (DrawableWrapper) getBackground().mutate();
- mRipple = (RippleDrawable) background.getDrawable();
+ mRipple = (RippleDrawable) getBackground();
mRipple.mutate();
+ DrawableWrapper inset = (DrawableWrapper) mRipple.getDrawable(0);
+ mBackground = (GradientDrawable) inset.getDrawable();
}
@RemotableViewMethod
@@ -70,8 +72,7 @@ public class EmphasizedNotificationButton extends Button {
@RemotableViewMethod
public void setButtonBackground(ColorStateList color) {
- GradientDrawable inner = (GradientDrawable) mRipple.getDrawable(0);
- inner.setColor(color);
+ mBackground.setColor(color);
invalidate();
}
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 73e7d86e8279..e93b00d7b148 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1282,6 +1282,8 @@ static void NativeThemeRebase(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong th
if (style_id_args == nullptr) {
return;
}
+ } else {
+ CHECK(style_count == 0) << "style_ids is null while style_count is non-zero";
}
jboolean* force_args = nullptr;
@@ -1292,12 +1294,18 @@ static void NativeThemeRebase(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong th
env->ReleasePrimitiveArrayCritical(style_ids, style_id_args, JNI_ABORT);
return;
}
+ } else {
+ CHECK(style_count == 0) << "force is null while style_count is non-zero";
}
auto theme = reinterpret_cast<Theme*>(theme_ptr);
theme->Rebase(&(*assetmanager), style_id_args, force_args, static_cast<size_t>(style_count));
- env->ReleasePrimitiveArrayCritical(style_ids, style_id_args, JNI_ABORT);
- env->ReleasePrimitiveArrayCritical(force, force_args, JNI_ABORT);
+ if (style_ids != nullptr) {
+ env->ReleasePrimitiveArrayCritical(style_ids, style_id_args, JNI_ABORT);
+ }
+ if (force != nullptr) {
+ env->ReleasePrimitiveArrayCritical(force, force_args, JNI_ABORT);
+ }
}
static void NativeThemeCopy(JNIEnv* env, jclass /*clazz*/, jlong dst_asset_manager_ptr,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6533fc51accf..64b8a1a81e69 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4053,8 +4053,13 @@
<permission android:name="android.permission.SCHEDULE_PRIORITIZED_ALARM"
android:protectionLevel="signature|privileged"/>
- <!-- Allows an app to use exact alarm scheduling APIs to perform timing
- sensitive background work.
+ <!-- Allows applications to use exact alarm APIs.
+ <p>Exact alarms should only be used for user-facing features.
+ For more details, see <a
+ href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
+ Exact alarm permission</a>.
+ Applications targeting API level 30 or below do not need this permission to use
+ exact alarm APIs.
-->
<permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
android:protectionLevel="normal|appop"/>
diff --git a/core/res/res/drawable/btn_notification_emphasized.xml b/core/res/res/drawable/btn_notification_emphasized.xml
index 63707ab7f5d6..29c51f2a33c9 100644
--- a/core/res/res/drawable/btn_notification_emphasized.xml
+++ b/core/res/res/drawable/btn_notification_emphasized.xml
@@ -15,13 +15,13 @@
~ limitations under the License
-->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="@dimen/button_inset_horizontal_material"
- android:insetTop="@dimen/button_inset_vertical_material"
- android:insetRight="@dimen/button_inset_horizontal_material"
- android:insetBottom="@dimen/button_inset_vertical_material">
- <ripple android:color="?attr/colorControlHighlight">
- <item>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?attr/colorControlHighlight">
+ <item>
+ <inset
+ android:insetLeft="@dimen/button_inset_horizontal_material"
+ android:insetTop="@dimen/button_inset_vertical_material"
+ android:insetRight="@dimen/button_inset_horizontal_material"
+ android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/notification_action_button_radius" />
<padding android:left="12dp"
@@ -30,6 +30,6 @@
android:bottom="@dimen/button_padding_vertical_material" />
<solid android:color="@color/white" />
</shape>
- </item>
- </ripple>
-</inset>
+ </inset>
+ </item>
+</ripple>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index c419e46349f4..e4c2a34b1af8 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -51,7 +51,7 @@
android:gravity="center"
android:singleLine="true"
android:ellipsize="end"
- android:fontFamily="sans-serif-medium"
+ android:fontFamily="@*android:string/config_bodyFontFamily"
android:textSize="@dimen/floating_toolbar_text_size"
android:textColor="?attr/floatingToolbarForegroundColor"
android:background="@null"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index ece2dc777575..85de02e4be95 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Laat \'n program toe om te versoek dat pakkette uitgevee word."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"vra om batteryoptimerings te ignoreer"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Laat \'n program toe om toestemming te vra om batteryoptimerings vir daardie program ignoreer."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Klop twee keer vir zoembeheer"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Kon nie legstuk byvoeg nie."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Gaan"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5bfd8d591dd4..18cc4c67f22f 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"አንድ መተግበሪያ የጥቅሎች ስረዛን እንዲጠይቅ ይፈቅዳል።"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"የባትሪ ማትባቶችን ችላ ለማለት መጠየቅ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"አንድ መተግበሪያ ለዚያ መተግበሪያ የባትሪ ማትባቶችን ችላ ለማለት እንዲጠይቅ ይፈቅድለታል።"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ለአጉላ መቆጣጠሪያ ሁለት ጊዜ ነካ አድርግ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ምግብር ማከል አልተቻለም።"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ሂድ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 09d6266e42b2..1d7ce153d4e5 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1538,6 +1538,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"للسماح لتطبيق ما بطلب حذف الحِزم."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"طلب تجاهل تحسينات البطارية"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"للسماح للتطبيق بطلب الإذن لتجاهل تحسينات البطارية في هذا التطبيق."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"اضغط مرتين للتحكم في التكبير أو التصغير"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"تعذرت إضافة أداة."</string>
<string name="ime_action_go" msgid="5536744546326495436">"تنفيذ"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 5802c4135af1..b1bf980fcbb4 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"এপটোক পেকেজবোৰ মচাৰ অনুৰোধ কৰিবলৈ দিয়ে।"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"বেটাৰি অপ্টিমাইজেশ্বন উপেক্ষা কৰিবলৈ বিচাৰক"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"কোনো এপক সেই এপটোৰ বাবে বেটাৰি অপ্টিমাইজেশ্বন উপেক্ষা কৰিবলৈ অনুমতি বিচাৰিবলৈ দিয়ে।"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্ৰণ কৰিবলৈ দুবাৰ টিপক"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ৱিজেট যোগ কৰিব পৰা নগ\'ল।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যাওক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 8301144fb9d3..af66b0bebfe2 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Tətbiqə paketlərin silinməsi sorğusunu göndərməyə icazə verir."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"batareya optimallaşdırmasını iqnor etmək üçün soruşun"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Tatareya optimallaşdırılmasını o tətbiq üçün iqnor edilməsinə icazə vermək məqsədilə soruşmağa tətbiqə icazə verilir."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Zoom kontrolu üçün iki dəfə toxunun"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget əlavə edilə bilmədi."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Get"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 31c0bdc84015..4cc46d9b4176 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1478,6 +1478,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Omogućava da aplikacija zahteva brisanje paketa."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"traženje dozvole za ignorisanje optimizacija baterije"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Dozvoljava aplikaciji da traži dozvolu za ignorisanje optimizacija baterije za tu aplikaciju."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dodirnite dvaput za kontrolu zumiranja"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nije moguće dodati vidžet."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Idi"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index fcfbc7324c11..142373747c8d 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Дазваляе праграме запытваць выдаленне пакетаў."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"запытваць дазвол на ігнараванне аптымізацыі акумулятара"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Дазваляе праграме запытваць дазвол на ігнараванне аптымізацыі акумулятара для гэтай праграмы."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Націсніце двойчы, каб кіраваць маштабаваннем"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Немагчыма дадаць віджэт."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Пачаць"</string>
@@ -2215,8 +2219,8 @@
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Размова"</string>
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групавая размова"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
- <string name="resolver_personal_tab" msgid="2051260504014442073">"Асабістыя"</string>
- <string name="resolver_work_tab" msgid="2690019516263167035">"Працоўныя"</string>
+ <string name="resolver_personal_tab" msgid="2051260504014442073">"Асабісты"</string>
+ <string name="resolver_work_tab" msgid="2690019516263167035">"Працоўны"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Прагляд асабістага змесціва"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Прагляд працоўнага змесціва"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Заблакіравана вашым ІТ-адміністратарам"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 8c7c9509b1d6..92e1a86198cc 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1355,7 +1355,7 @@
<string name="no_permissions" msgid="5729199278862516390">"Не се изискват разрешения"</string>
<string name="perm_costs_money" msgid="749054595022779685">"това може да ви струва пари"</string>
<string name="dlg_ok" msgid="5103447663504839312">"OK"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"Това устройство се зарежда през USB"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"Устройството се зарежда през USB"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"Свързаното устройство се зарежда през USB"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Прехвърлянето на файлове през USB е включено"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режимът PTP през USB е включен"</string>
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Разрешава на приложението да заявява изтриване на пакети."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"искане за пренебрегване на оптимизациите на батерията"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Разрешава на дадено приложение да иска разрешение за пренебрегване на свързаните с него оптимизации на батерията."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Докоснете двукратно за управление на промяната на мащаба"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Приспособлението не можа да бъде добавено."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Старт"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 3a9d5cb96cf3..2a9ecf66d4e9 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"একটি অ্যাপ্লিকেশানকে প্যাকেজগুলি মুছে দেওয়ার অনুরোধ জানাতে দেয়৷"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ব্যাটারি অপ্টিমাইজেশন উপেক্ষা করার জন্য অনুমতি চাওয়া"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"কোনো অ্যাপের জন্য ব্যাটারি অপ্টিমাইজেশন উপেক্ষা করতে সেটিকে অনুমতির চাওয়ার মঞ্জুরি দেয়৷"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"উইজেট যোগ করা যায়নি৷"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যান"</string>
@@ -2158,7 +2162,7 @@
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ব্যক্তিগত অ্যাপে এই কন্টেন্ট খোলা যাবে না"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"অফিস প্রোফাইল বন্ধ করা আছে"</string>
<string name="resolver_switch_on_work" msgid="463709043650610420">"চালু করতে ট্যাপ করুন"</string>
- <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"অফিসের অ্যাপ ব্যবহার করা যাবে না"</string>
+ <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"এর জন্য কোনও অফিস অ্যাপ নেই"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ব্যক্তিগত অ্যাপে দেখা যাবে না"</string>
<string name="miniresolver_open_in_personal" msgid="2937599899213467617">"ব্যক্তিগত প্রোফাইলে <xliff:g id="APP">%s</xliff:g> অ্যাপ খুলতে চান?"</string>
<string name="miniresolver_open_in_work" msgid="152208044699347924">"অফিস প্রোফাইলে <xliff:g id="APP">%s</xliff:g> অ্যাপ খুলতে চান?"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 74ba9da3c36b..f811ac2f4b95 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1478,6 +1478,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Omogućava aplikaciji da zatraži brisanje paketa."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"traži zanemarivanje optimizacije baterije"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Omogućava aplikaciji da traži odobrenje za zanemarivanje optimizacije baterije za tu aplikaciju."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dodirnite dvaput za kontrolu uvećanja"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Dodavanje vidžeta nije uspjelo."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Započni"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 1dadb14a145b..19762bfc0de3 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet que una aplicació sol·liciti la supressió de paquets."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Demanar permís per ignorar les optimitzacions de bateria"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet que una aplicació demani permís per ignorar les optimitzacions de bateria per a l\'aplicació."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Piqueu dos cops per controlar el zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"No s\'ha pogut afegir el widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ves"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 718fe0f385db..95b2b551d78c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Umožňuje aplikaci požádat o smazání balíčků."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"požádat o ignorování optimalizace využití baterie"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Povoluje aplikaci požádat o oprávnění ignorovat optimalizaci využití baterie, která pro ni je nastavena."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Poklepáním můžete ovládat přiblížení"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget nelze přidat."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Přejít"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c93a26ba07e2..79379f10f2c8 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Tillader, at en app anmoder om sletning af pakker."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"bede om at ignorere batterioptimeringer"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Gør det muligt for en app at bede om tilladelse til at ignorere batterioptimeringer for den pågældende app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tryk to gange for zoomkontrol"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget kunne ikke tilføjes."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Gå"</string>
@@ -2125,7 +2129,7 @@
<item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fil</item>
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> filer</item>
</plurals>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Der er ingen anbefalede brugere at dele med"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Der er ingen anbefalede personer at dele med"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste over apps"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Denne app har ikke fået tilladelse til at optage, men optager muligvis lyd via denne USB-enhed."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Hjem"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 392973c5cfc9..b8727e879f83 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Ermöglicht der App, das Löschen von Paketen anzufordern."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"fragen, ob Akku-Leistungsoptimierungen ignoriert werden können"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Erlaubt einer App, nach der Berechtigung zum Ignorieren der Akku-Leistungsoptimierungen zu fragen."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Für Zoomeinstellung zweimal berühren"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget konnte nicht hinzugefügt werden."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Los"</string>
@@ -1868,7 +1872,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Der Energiesparmodus aktiviert das dunkle Design und schränkt Hintergrundaktivitäten, einige Funktionen und optische Effekte sowie manche Netzwerkverbindungen ein oder deaktiviert sie."</string>
<string name="battery_saver_description" msgid="8518809702138617167">"Der Energiesparmodus aktiviert das dunkle Design und schränkt Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen ein oder deaktiviert sie."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Der Datensparmodus verhindert zum einen, dass manche Apps im Hintergrund Daten senden oder empfangen, sodass weniger Daten verbraucht werden. Zum anderen werden die Datenzugriffe der gerade aktiven App eingeschränkt, was z. B. dazu führen kann, dass Bilder erst angetippt werden müssen, bevor sie sichtbar werden."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Der Datensparmodus verhindert, dass manche Apps im Hintergrund Daten senden oder empfangen, sodass weniger Daten verbraucht werden. Auch werden die Datenzugriffe der gerade aktiven App eingeschränkt, was z. B. dazu führen kann, dass Bilder erst angetippt werden müssen, bevor sie sichtbar werden."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Datensparmodus aktivieren?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivieren"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2069,7 +2073,7 @@
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Schädliche App erkannt"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> möchte Teile von <xliff:g id="APP_2">%2$s</xliff:g> anzeigen"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Bearbeiten"</string>
- <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Anrufe und Benachrichtigungen per Vibrationsalarm"</string>
+ <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Gerät vibriert bei Anrufen und Benachrichtigungen"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Anrufe und Benachrichtigungen stummgeschaltet"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"Systemänderungen"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Bitte nicht stören"</string>
@@ -2130,7 +2134,7 @@
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Diese App hat noch keine Berechtigung zum Aufnehmen erhalten, könnte aber Audioaufnahmen über dieses USB-Gerät machen."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Startseite"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Zurück"</string>
- <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Letzte Apps"</string>
+ <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Kürzlich geöffnete Apps"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Benachrichtigungen"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Schnelleinstellungen"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Kleines Fenster für Akkustand"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index a2624a13ef1f..2aa10e597c08 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Επιτρέπει σε μια εφαρμογή να ζητά διαγραφή πακέτων."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"αίτημα αγνόησης βελτιστοποιήσεων μπαταρίας"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Επιτρέπει σε μια εφαρμογή να ζητήσει άδεια για την αγνόηση βελτιστοποιήσεων της μπαταρίας για τη συγκεκριμένη εφαρμογή."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Πατήστε δύο φορές για έλεγχο εστίασης"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Δεν ήταν δυνατή η προσθήκη του γραφικού στοιχείου."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Μετάβαση"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f16e2e4ce25f..0817cb5d4316 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Allows an application to request deletion of packages."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ask to ignore battery optimisations"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 2a67834b0cc1..6e3b041f1c2c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Allows an application to request deletion of packages."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ask to ignore battery optimisations"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bb1e6f3dea1a..74973c4e57f1 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Allows an application to request deletion of packages."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ask to ignore battery optimisations"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a06053f5c80e..8fe3f42e1672 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Allows an application to request deletion of packages."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ask to ignore battery optimisations"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 022f06051c55..2d921235a55e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎Allows an application to request deletion of packages.‎‏‎‎‏‎"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎ask to ignore battery optimizations‎‏‎‎‏‎"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎Allows an app to ask for permission to ignore battery optimizations for that app.‎‏‎‎‏‎"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎Tap twice for zoom control‎‏‎‎‏‎"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎Couldn\'t add widget.‎‏‎‎‏‎"</string>
<string name="ime_action_go" msgid="5536744546326495436">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎‎‎Go‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a164ffe23f8e..9102b8981869 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite que una aplicación solicite que se borren paquetes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"solicitar permiso para ignorar las optimizaciones de la batería"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que una app solicite permiso para ignorar las optimizaciones de la batería."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Presiona dos veces para obtener el control del zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"No se pudo agregar el widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0c5de09f514f..07f805be51af 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite a una aplicación solicitar la eliminación de paquetes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"solicitar permiso para ignorar las optimizaciones de la batería"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que una aplicación solicite permiso para ignorar las optimizaciones de la batería."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Da dos toques para acceder al control de zoom."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"No se ha podido añadir el widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index b2b0226159c9..937161b88dfd 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Võimaldab rakendusel taotleda pakettide kustutamist."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"küsida luba aku optimeerimise eiramiseks"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Lubab rakendusel küsida luba rakenduse aku optimeerimise eiramiseks."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Suumi kasutamiseks koputage kaks korda"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Vidinat ei saanud lisada."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Mine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index d0bdd6fe1bc2..316013434506 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Paketeak ezabatzeko eskatzea baimentzen die aplikazioei."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"eskatu bateria-optimizazioei ez ikusi egitea"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Bateriaren optimizazioei ez ikusi egiteko baimena eskatzea baimentzen die aplikazioei."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Sakatu birritan zooma kontrolatzeko"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Ezin izan da widgeta gehitu."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Joan"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index f303be0c25bc..3787d4c9db5f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"به برنامه اجازه می‌دهد حذف بسته‌ها را درخواست کند."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"درخواست نادیده‌گرفتن بهینه‌سازی باتری"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"به یک برنامه اجازه می‌دهد جهت نادیده گرفتن بهینه‌سازی باتری برای خود مجوز درخواست کند."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"برای کنترل بزرگ‌نمایی، دو بار ضربه بزنید"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"افزودن ابزارک انجام نشد."</string>
<string name="ime_action_go" msgid="5536744546326495436">"برو"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index ac6cca83a330..965970cc9e54 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Antaa sovelluksen pyytää pakettien poistamista."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Lupa ohittaa akun optimoinnit"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Sallii sovelluksen pyytää lupaa ohittaa tietyn sovelluksen akun optimoinnit."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Hallitse zoomausta napauttamalla kahdesti"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widgetin lisääminen epäonnistui."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Siirry"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 8abf13370f07..44754d7a9bbf 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -280,8 +280,8 @@
<string name="notification_channel_security" msgid="8516754650348238057">"Sécurité"</string>
<string name="notification_channel_car_mode" msgid="2123919247040988436">"Mode Voiture"</string>
<string name="notification_channel_account" msgid="6436294521740148173">"État du compte"</string>
- <string name="notification_channel_developer" msgid="1691059964407549150">"Messages des concepteurs"</string>
- <string name="notification_channel_developer_important" msgid="7197281908918789589">"Messages importants à l\'intention des concepteurs"</string>
+ <string name="notification_channel_developer" msgid="1691059964407549150">"Messages des développeurs"</string>
+ <string name="notification_channel_developer_important" msgid="7197281908918789589">"Messages importants à l\'intention des développeurs"</string>
<string name="notification_channel_updates" msgid="7907863984825495278">"Mises à jour"</string>
<string name="notification_channel_network_status" msgid="2127687368725272809">"État du réseau"</string>
<string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertes réseau"</string>
@@ -1271,7 +1271,7 @@
<string name="dump_heap_ready_notification" msgid="2302452262927390268">"L\'empreinte de mémoire <xliff:g id="PROC">%1$s</xliff:g> est prête"</string>
<string name="dump_heap_notification_detail" msgid="8431586843001054050">"L\'empreinte de mémoire a été recueillie. Touchez ici pour la partager."</string>
<string name="dump_heap_title" msgid="4367128917229233901">"Partager l\'empreinte de mémoire?"</string>
- <string name="dump_heap_text" msgid="1692649033835719336">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son concepteur. Attention : Cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'application a accès."</string>
+ <string name="dump_heap_text" msgid="1692649033835719336">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : Cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'application a accès."</string>
<string name="dump_heap_system_text" msgid="6805155514925350849">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
<string name="dump_heap_ready_text" msgid="5849618132123045516">"Une empreinte de mémoire du processus lié à l\'application <xliff:g id="PROC">%1$s</xliff:g> peut être partagée. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
<string name="sendText" msgid="493003724401350724">"Sélectionner une action pour le texte"</string>
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet à une application de demander la suppression de paquets."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"demander d\'ignorer les optimisations de la pile"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet à une application de demander la permission d\'ignorer les optimisations de la pile."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Appuyer deux fois pour régler le zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Impossible d\'ajouter le widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Aller"</string>
@@ -1975,7 +1979,7 @@
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activer"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string>
- <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Cette application a été conçue pour une ancienne version d\'Android et pourrait ne pas fonctionner correctement. Essayez de vérifier les mises à jour ou communiquez avec son concepteur."</string>
+ <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Cette application a été conçue pour une ancienne version d\'Android et pourrait ne pas fonctionner correctement. Essayez de vérifier les mises à jour ou communiquez avec son développeur."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f04e71e3e1aa..cc22d83eb367 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet à une application de demander la suppression de packages."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"demander à ignorer les optimisations de batterie"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Autorise une application à demander l\'autorisation d\'ignorer les optimisations de batterie pour cette application."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Appuyer deux fois pour régler le zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Impossible d\'ajouter le widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"OK"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 025bc1d53af3..ba41c75c514a 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite a unha aplicación solicitar a eliminación dos paquetes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"pedir que se ignore a optimización da batería"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Fai que unha aplicación poida solicitar permiso para ignorar as optimizacións da batería."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Toca dúas veces para controlar o zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Non se puido engadir o widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 0e9d5d5679b5..4157e1fd32eb 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ઍપ્લિકેશનને પૅકેજો કાઢી નાખવાની વિનંતી કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"બૅટરી ઓપ્ટિમાઇઝેશન્સને અવગણવા માટે પૂછો"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ઍપ્લિકેશનને તે ઍપ્લિકેશન માટે બૅટરી ઓપ્ટિમાઇઝેશન્સને અવગણવાની પરવાનગી આપવા માટે પૂછવાની મંજૂરી આપે છે."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ઝૂમ નિયંત્રણ માટે બેવાર ટૅપ કરો"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"વિજેટ ઉમેરી શકાયું નથી."</string>
<string name="ime_action_go" msgid="5536744546326495436">"જાઓ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index fd45cce3e5ec..6e8bd94f3f1d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"किसी ऐप्लिकेशन को पैकेज हटाने का अनुरोध करने देती है."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"बैटरी ऑप्टिमाइज़ेशन पर ध्यान ना देने के लिए पूछें"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"किसी ऐप्लिकेशन को उस ऐप्लिकेशन के लिए बैटरी ऑप्टिमाइज़ेशन पर ध्यान ना देने की अनुमति के लिए पूछने देता है."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ज़ूम नियंत्रण के लिए दो बार टैप करें"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट नहीं जोड़ा जा सका."</string>
<string name="ime_action_go" msgid="5536744546326495436">"जाएं"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 9e0fb1edc610..98acb8993dbe 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1478,6 +1478,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Aplikaciji omogućuje zahtijevanje brisanja paketa."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"tražiti zanemarivanje optimizacija baterije"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Aplikaciji omogućuje da traži dopuštenje za zanemarivanje optimizacija baterije za tu aplikaciju."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dvaput dotaknite za upravljanje zumiranjem"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget nije moguće dodati."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Idi"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3d15380196f3..58c38755cf6e 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Lehetővé teszi az alkalmazás számára, hogy csomagok törlését kérje."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Akkumulátoroptimalizálási beállítások mellőzésének kérése"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Az alkalmazás engedélyt kérhet az akkumulátoroptimalizálási beállítások mellőzésére."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Érintse meg kétszer a nagyítás beállításához"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nem sikerült hozzáadni a modult."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ugrás"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 9b4bb13cc972..860dcf98cc8b 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Թույլ է տալիս հավելվածին պահանջել փաթեթների ջնջում:"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"հայցել մարտկոցի օպտիմալացումն անտեսելու թույլտվություն"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Հավելվածին հնարավորություն է տալիս հայցելու թույլտվություն՝ տվյալ հավելվածի համար մարտկոցի օպտիմալացումն անտեսելու համար:"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Հպեք երկու անգամ` խոշորացման վերահսկման համար"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Չհաջողվեց վիջեթ ավելացնել:"</string>
<string name="ime_action_go" msgid="5536744546326495436">"Առաջ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 7dbf5664f59d..b8649c11466c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Mengizinkan aplikasi meminta penghapusan paket."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"meminta mengabaikan pengoptimalan baterai"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Mengizinkan aplikasi meminta izin untuk mengabaikan pengoptimalan baterai bagi aplikasi tersebut."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ketuk dua kali untuk kontrol perbesar/perkecil"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Buka"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index a15275bc737b..0cf1effb535f 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Leyfir forriti að biðja um eyðingu pakka."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"biðja um að hunsa rafhlöðusparnað"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Gerir forriti kleift að biðja um heimild til að hunsa rafhlöðusparnað fyrir forritið."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ýttu tvisvar til að opna aðdráttarstýringar"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Ekki tókst að bæta græju við."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Áfram"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3191bd635f83..29dbd76514bc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Consente a un\'applicazione di richiedere l\'eliminazione di pacchetti."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"richiesta di ignorare le ottimizzazioni della batteria"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Consente a un\'app di chiedere l\'autorizzazione a ignorare le ottimizzazioni della batteria per quell\'app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tocca due volte per il comando dello zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Aggiunta del widget non riuscita."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Vai"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index b84778fbdcd0..dc43bde6c1c7 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"מאפשרת לאפליקציה לבקש מחיקה של חבילות."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"בקשה להתעלם מאופטימיזציות של הסוללה"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"מאפשרת לאפליקציה לבקש רשות להתעלם מאופטימיזציות של הסוללה לאפליקציה הזו."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"יש להקיש פעמיים לשינוי המרחק מהתצוגה"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"‏לא ניתן להוסיף widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"התחלה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index d98974fcc7c9..b282b44197bf 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"パッケージの削除をリクエストすることをアプリに許可します。"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"電池の最適化を無視するかどうかの確認"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"電池の最適化の無視についてアプリが確認することを許可します。"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ダブルタップでズームします"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ウィジェットを追加できませんでした。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"移動"</string>
@@ -2070,7 +2074,7 @@
<string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」が「<xliff:g id="APP_2">%2$s</xliff:g>」のスライスの表示をリクエストしています"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"編集"</string>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"着信や通知をバイブレーションで知らせます"</string>
- <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"着信音と通知音をミュートします"</string>
+ <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"着信音と通知音が鳴りません"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"システムの変更"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"サイレント モード"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"新機能: サイレント モードでは通知が非表示になります"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 1d5661b6fe95..dbc92da44549 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"აპლიკაციას შეეძლება პაკეტების წაშლის მოთხოვნა."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ბატარეის ოპტიმიზაციის იგნორირების მოთხოვნა"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"საშუალებას მისცემს აპს, მოითხოვოს მასთან დაკავშირებული ბატარეის ოპტიმიზაციის იგნორირების ნებართვა."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"მასშტაბის ცვლილებისთვის შეეხეთ ორჯერ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ვერ დაემატა ვიჯეტი."</string>
<string name="ime_action_go" msgid="5536744546326495436">"გადასვლა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index ff5edfebc131..6d3429e8b770 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Қолданбаның пакеттерді жоюға рұқсат сұрауына мүмкіндік береді."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"батареяны оңтайландыру әрекетін елемеуді сұрау"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Қолданба батареяны оңтайландыру әрекетін елемеуді сұрай алады."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Масштабтау параметрін басқару үшін екі рет түртіңіз"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Виджетті қосу."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Өту"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 1389104abe3a..19aa889245d3 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ស្នើសុំលុប​កញ្ចប់។"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ស្នើឲ្យមិនអើពើចំពោះការបង្កើនប្រសិទ្ធភាពថ្ម"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"អនុញ្ញាតឲ្យកម្មវិធីស្នើសុំការអនុញ្ញាត ដើម្បីមិនអើពើចំពោះការបង្កើនប្រសិទ្ធភាពថ្ម។"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ប៉ះ ពីរ​ដង​ដើម្បី​ពិនិត្យ​ការ​ពង្រីក"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"មិន​អាច​បន្ថែម​ធាតុ​ក្រាហ្វិក។"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ទៅ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index a297d535dac1..a3e0ca57ee0d 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ಪ್ಯಾಕೇಜ್‌ಗಳನ್ನು ಅಳಿಸುವುದಕ್ಕಾಗಿ ವಿನಂತಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ಬ್ಯಾಟರಿ ಆಪ್ಟಿಮೈಸೇಶನ್‌ಗಳನ್ನು ಕಡೆಗಣಿಸಲು ಕೇಳಿ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಬ್ಯಾಟರಿ ಆಪ್ಟಿಮೈಸೇಶನ್‌ಗಳನ್ನು ಕಡೆಗಣಿಸುವುದಕ್ಕೆ ಅನುಮತಿಯನ್ನು ಕೇಳಲು ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ಝೂಮ್‌ ನಿಯಂತ್ರಿಸಲು ಎರಡು ಬಾರಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
<string name="ime_action_go" msgid="5536744546326495436">"ಹೋಗು"</string>
@@ -1988,7 +1992,7 @@
<string name="pin_specific_target" msgid="7824671240625957415">"<xliff:g id="LABEL">%1$s</xliff:g> ಗೆ ಪಿನ್ ಮಾಡಿ"</string>
<string name="unpin_target" msgid="3963318576590204447">"ಅನ್‌ಪಿನ್"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"<xliff:g id="LABEL">%1$s</xliff:g> ಅನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಿ"</string>
- <string name="app_info" msgid="6113278084877079851">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
+ <string name="app_info" msgid="6113278084877079851">"ಆ್ಯಪ್ ಮಾಹಿತಿ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ಡೆಮೋ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"ಸಾಧನ ಮರುಹೊಂದಿಸಲಾಗುತ್ತಿದೆ..."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 44d751e60e41..4c1691b6ac5f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"애플리케이션이 패키지 삭제를 요청하도록 허용합니다."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"배터리 최적화를 무시하도록 요청"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"앱에서 배터리 최적화를 무시할 수 있는 권한을 요청할 수 있도록 허용합니다."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"확대/축소하려면 두 번 탭하세요."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"위젯을 추가할 수 없습니다."</string>
<string name="ime_action_go" msgid="5536744546326495436">"이동"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index c8f94fbbc5bd..66ec9aa5d42b 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Колдонмо топтомдорду жок кылууга уруксат сурай алат."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"батареянын кубатын көп керектей берсин"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Колдонмо батареянын кубатын керектегенден мурун уруксат суралсын."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Масштабдын параметрлерин өзгөртүү үчүн бул жерди эки жолу басыңыз."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Виджетти кошуу мүмкүн болбоду."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Өтүү"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 5de05faffdf3..fd83eda7b736 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຮ້ອງຂໍການລຶບແພັກເກດ."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ຖາມເພື່ອໃຫ້ເພີກເສີຍການປັບແຕ່ງແບັດເຕີຣີ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ອະນຸຍາດໃຫ້ແອັບຖາມສິດອະນຸຍາດເພື່ອເພີກເສີຍຕໍ່ການປັບແຕ່ງແບັດເຕີຣີສຳລັບແອັບນັ້ນ."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ແຕະສອງເທື່ອເພື່ອຄວບຄຸມການຊູມ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ບໍ່ສາມາດເພີ່ມວິດເຈັດໄດ້."</string>
<string name="ime_action_go" msgid="5536744546326495436">"ໄປ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 9a97d9cc9310..ca43ce7ac97d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Programai leidžiama pateikti užklausą dėl paketų ištrynimo."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"prašyti nepaisyti akumuliatoriaus optimizavimo nustatymų"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Programai leidžiama prašyti leidimo nepaisyti tai programai skirto akumuliatoriaus optimizavimo nustatymų."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Bakstelėkite du kartus, kad valdytumėte mastelio keitimą"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nepavyko pridėti."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pradėti"</string>
@@ -2215,7 +2219,7 @@
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Pokalbis"</string>
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupės pokalbis"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
- <string name="resolver_personal_tab" msgid="2051260504014442073">"Asmeninė"</string>
+ <string name="resolver_personal_tab" msgid="2051260504014442073">"Asmeninis"</string>
<string name="resolver_work_tab" msgid="2690019516263167035">"Darbo"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Asmeninė peržiūra"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Darbo peržiūra"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b7d4e0883897..47094a4e2317 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1478,6 +1478,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Atļauj lietojumprogrammai pieprasīt pakotņu dzēšanu."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Lūgt akumulatora optimizācijas ignorēšanu"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Ļauj lietotnei lūgt atļauju ignorēt akumulatora optimizāciju šai lietotnei."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Pieskarieties divreiz, lai kontrolētu tālummaiņu."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nevarēja pievienot logrīku."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Doties uz"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6c9f99d029f6..5a9486e0dc28 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Дозволува апликацијата да бара бришење на пакетите."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"прашај дали да се игнорираат оптимизациите на батеријата"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Овозможува апликацијата да побара дозвола за игнорирање на оптимизациите на батеријата за таа апликација."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Допрете двапати за контрола на зумот"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не може да се додаде виџет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Оди"</string>
@@ -2148,7 +2152,7 @@
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групен разговор"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
<string name="resolver_personal_tab" msgid="2051260504014442073">"Лични"</string>
- <string name="resolver_work_tab" msgid="2690019516263167035">"Службени"</string>
+ <string name="resolver_work_tab" msgid="2690019516263167035">"За работа"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Личен приказ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Работен приказ"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Блокирано од вашиот IT-администратор"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f468ab008ae2..9ca392a06ace 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"പാക്കേജുകളെ ഇല്ലാതാക്കാനുള്ള അഭ്യർത്ഥന നടത്താൻ ആപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ബാറ്ററി ഒപ്റ്റിമൈസേഷനുകൾ അവഗണിക്കാൻ ആവശ്യപ്പെടുക"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ആപ്പിന് വേണ്ടിയുള്ള ബാറ്ററി ഒപ്റ്റിമൈസേഷനുകളെ അവഗണിക്കാനുള്ള അനുമതി ചോദിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"സൂം നിയന്ത്രണം ലഭിക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"വിജറ്റ് ചേർക്കാനായില്ല."</string>
<string name="ime_action_go" msgid="5536744546326495436">"പോവുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 36165362a2d4..4c01871de148 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Апп-д багц устгах хүсэлт тавихыг зөвшөөрнө."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"батерейны оновчлол алгасахыг асуух"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Тухайн аппaaс батерейны оновчлол алгасах зөвшөөрөл асуухыг зөвшөөрдөг."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Өсгөх контрол дээр хоёр удаа товшино уу"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Виджет нэмж чадсангүй."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Очих"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 9d14a8d3834c..1dfa5de9d25a 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"अनुप्रयोगास पॅकेज हटवण्यासाठी विनंती करण्याची अनुमती देते."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"बॅटरी ऑप्टिमायझेशन दुर्लक्षित करण्‍यास सांगा"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"त्या ॲपसाठी बॅटरी ऑप्टिमायझेशन दुर्लक्षित करण्‍यासाठी ॲपला परवानगी मागण्याची अनुमती देते."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"झूम नियंत्रणासाठी दोनदा टॅप करा"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट जोडू शकलो नाही."</string>
<string name="ime_action_go" msgid="5536744546326495436">"जा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1bab0b216623..2960ca2c0eed 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Membenarkan aplikasi meminta pemadaman pakej."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"minta kebenaran untuk mengabaikan pengoptimuman bateri"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Membenarkan apl meminta kebenaran untuk mengabaikan pengoptimuman bateri untuk apl itu."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ketik dua kali untuk mendapatkan kawalan zum"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pergi"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 23fc7bbb4c9d..2c0ed7ba01df 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"အပလီကေးရှင်းတစ်ခုအား ပက်ကေ့ဂျ်များကို ဖျက်ရန် တောင်းဆိုခွင့်ပေးပါ။"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ဘက်ထရီ ပိုမိုကောင်းမွန်အောင် ပြုလုပ်ခြင်းကို လျစ်လျူရှုရန် တောင်းဆိုပါ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ဘက်ထရီ ပိုမိုကောင်းမွန်အောင် ပြုလုပ်ခြင်းကို လျစ်လျူရှုရန်အတွက် ခွင့်ပြုချက်တောင်းရန် အက်ပ်ကို ခွင့်ပြုပါ။"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ဇူးမ်အသုံးပြုရန် နှစ်ချက်တို့ပါ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ဝဒ်ဂျက်ထည့်လို့ မရပါ"</string>
<string name="ime_action_go" msgid="5536744546326495436">"သွားပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d24c87933ec4..0ceebf1bab93 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Lar apper be om sletting av pakker."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"be om å ignorere batterioptimaliseringer"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Gjør det mulig for apper å be om tillatelse til å ignorere batterioptimaliseringer for disse appene."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Trykk to ganger for zoomkontroll"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Kunne ikke legge til modulen."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Utfør"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index d565c28faaf8..8e7ca7137477 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"एपलाई प्याकेजहरू मेटाउने अनुरोध गर्न अनुमति दिन्छ।"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ब्याट्री सम्बन्धी अनुकूलनहरूलाई बेवास्ता गर्न सोध्नुहोस्"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"कुनै एपलाई त्यसका ब्याट्री सम्बन्धी अनुकूलनहरूलाई बेवास्ता गर्नाका लागि अनुमति माग्न दिन्छ।"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"जुम नियन्त्रणको लागि दुई चोटि ट्याप गर्नुहोस्"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट थप गर्न सकिँदैन।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"जानुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 531612423a83..97009396cfaf 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Hiermee kan een app verwijdering van pakketten aanvragen."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"vragen om batterijoptimalisatie te negeren"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Hiermee kan een app rechten vragen om batterijoptimalisatie voor die app te negeren."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tik twee keer voor zoomregeling"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Kan widget niet toevoegen."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ga"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index d2165cbab44a..d6b1e1ee66e8 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ପ୍ୟାକେଜ୍‌ଗୁଡ଼ିକ ଡିଲିଟ୍‍ କରିବା ପାଇଁ ଅନୁରୋଧ କରିବାକୁ ଏକ ଆପ୍ଲିକେଶନକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ବ୍ୟାଟେରୀ ଅନୁକୂଳନ ଏଡ଼ାଇବା ପାଇଁ ପଚାରନ୍ତୁ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ଆପ୍‍ ପାଇଁ ବ୍ୟାଟେରୀ ଅନୁକୂଳନ ଏଡ଼ାଇବାର ଅନୁମତି ମାଗିବା ନିମନ୍ତେ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍‌ କରନ୍ତୁ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ୱିଜେଟ୍‍ ଯୋଡ଼ିପାରିବ ନାହିଁ।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ଯାଆନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 91dd2fc5219a..9a73f9b85245 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ਕਿਸੇ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਪੈਕੇਜਾਂ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ਬੈਟਰੀ ਸੁਯੋਗਤਾਵਾਂ ਨੂੰ ਅਣਡਿੱਠ ਕਰਨ ਲਈ ਪੁੱਛੋ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ਕਿਸੇ ਐਪ ਨੂੰ ਉਸ ਵਾਸਤੇ ਬੈਟਰੀ ਸੁਯੋਗਤਾਵਾਂ ਨੂੰ ਅਣਡਿੱਠ ਕਰਨ ਲਈ ਇਜਾਜ਼ਤ ਵਾਸਤੇ ਪੁੱਛਣ ਲਈ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ਜ਼ੂਮ ਕੰਟਰੋਲ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਨਹੀਂ ਹੋ ਸਕਿਆ।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ਜਾਓ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index c3c5d0a93623..2781df76ea5b 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Zezwala aplikacji na żądanie usunięcia pakietów."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Prośba o ignorowanie optymalizacji wykorzystania baterii"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Zezwala aplikacji na proszenie o uprawnienia do ignorowania optymalizacji wykorzystania baterii w przypadku danej aplikacji."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dotknij dwukrotnie, aby sterować powiększeniem"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nie można dodać widżetu."</string>
<string name="ime_action_go" msgid="5536744546326495436">"OK"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 42e3b5bb1cbb..a60cb23b7324 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite que um app solicite a exclusão de pacotes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"solicitar que as otimizações de bateria sejam ignoradas"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que um app peça permissão para ignorar as otimizações de bateria para esse app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Toque duas vezes para ter controle do zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 378d3b45ce6a..5f1046267317 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite que uma app solicite a eliminação de pacotes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"pedir para ignorar as otimizações da bateria"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que uma app solicite autorização para ignorar as otimizações da bateria para a mesma."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tocar duas vezes para controlar o zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 42e3b5bb1cbb..a60cb23b7324 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite que um app solicite a exclusão de pacotes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"solicitar que as otimizações de bateria sejam ignoradas"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que um app peça permissão para ignorar as otimizações de bateria para esse app."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Toque duas vezes para ter controle do zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 953eb72e9c76..dc351a23156a 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1478,6 +1478,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permite unei aplicații să solicite ștergerea pachetelor."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"să solicite ignorarea optimizărilor bateriei"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite unei aplicații să solicite permisiunea de a ignora optimizările bateriei pentru aplicația respectivă."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Apăsați de două ori pentru a controla mărirea/micșorarea"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nu s-a putut adăuga widgetul."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Accesați"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 4adc5a95ff8b..ea9e292fd9fc 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Приложение сможет запрашивать разрешения на удаление пакетов."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Без ограничения расхода батареи"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Разрешает приложению игнорировать ограничение на расход заряда батареи."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Нажмите дважды для изменения масштаба"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не удалось добавить виджет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Выбрать"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 1bad219e9cd5..60641032538d 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ස්ථාපන පැකේජ මැකීමට යෙදුමකට ඉඩ දීම."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"බැටරි ප්‍රශස්තකරණ නොසලකා හැරීමට ඉල්ලන්න"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"යෙදුමකට එම යෙදුම සඳහා බැටරි ප්‍රශස්තකරණ නොසලකා හැරීමට අවසර ඉල්ලීමට ඉඩ දෙයි."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"විශාලන පාලක සඳහා දෙවතාවක් තට්ටු කරන්න"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"විජටය එකතු කිරීමට නොහැකි විය."</string>
<string name="ime_action_go" msgid="5536744546326495436">"යන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ff114cd3e17f..e42cc0116ccf 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Umožňuje aplikácii vyžiadať odstránenie balíkov."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"požiadať o ignorovanie optimalizácií výdrže batérie"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Umožňuje aplikácii požiadať o povolenie ignorovať optimalizácie výdrže batérie pre danú aplikáciu."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dvojitým klepnutím môžete ovládať priblíženie"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Miniaplikáciu sa nepodarilo pridať."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Hľadať"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ebdde2378db2..506c066571ac 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Omogoča aplikaciji, da zahteva brisanje paketov."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"Dovoljenje za prezrtje optimizacij baterije"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Aplikaciji dovoljuje, da vpraša za dovoljenje, ali naj prezre optimizacije baterije."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tapnite dvakrat za nadzor povečave/pomanjšave"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Pripomočka ni bilo mogoče dodati."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pojdi"</string>
@@ -1914,7 +1918,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"V redu"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Funkcija varčevanja z energijo baterije vklopi temno temo ter omeji ali izklopi dejavnost v ozadju, nekatere vizualne učinke, določene funkcije in nekatere omrežne povezave."</string>
<string name="battery_saver_description" msgid="8518809702138617167">"Funkcija varčevanja z energijo baterije vklopi temno temo ter omeji ali izklopi dejavnost v ozadju, nekatere vizualne učinke, določene funkcije in nekatere omrežne povezave."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Zaradi zmanjševanja prenesene količine podatkov funkcija varčevanja s podatki nekaterim aplikacijam preprečuje, da bi v ozadju pošiljale ali prejemale podatke. Aplikacija, ki jo trenutno uporabljate, lahko prenaša podatke, vendar to morda počne manj pogosto. To na primer pomeni, da se slike ne prikažejo, dokler se jih ne dotaknete."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Zaradi zmanjševanja prenesene količine podatkov funkcija varčevanja s podatki nekaterim aplikacijam preprečuje, da bi v ozadju pošiljale ali prejemale podatke. Aplikacija, ki jo trenutno uporabljate, lahko dostopa do podatkov, vendar to morda počne manj pogosto. To na primer pomeni, da se slike ne prikažejo, dokler se jih ne dotaknete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vklop varčevanja s podatki?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Vklopi"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2193,7 +2197,7 @@
<item quantity="few"><xliff:g id="FILE_NAME_2">%s</xliff:g> in še <xliff:g id="COUNT_3">%d</xliff:g> datoteke</item>
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> in še <xliff:g id="COUNT_3">%d</xliff:g> datotek</item>
</plurals>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Ni priporočenih oseb za deljenje vsebine"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Ni priporočenih oseb za deljenje vsebine."</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Seznam aplikacij"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ta aplikacija sicer nima dovoljenja za snemanje, vendar bi lahko zajemala zvok prek te naprave USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Začetni zaslon"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index ad07eb6cb20a..ed6a6168a841 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Lejon që një aplikacion të kërkojë fshirjen e paketave."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"kërko të shpërfillësh optimizimet e baterisë"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Lejon që një aplikacion të kërkojë leje për të shpërfillur optimizimet e baterisë për atë aplikacion."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Trokit dy herë për të kontrolluar zmadhimin"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nuk mundi të shtonte miniaplikacion."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Shko"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 4d9dbd6b085c..14f5673c1232 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1478,6 +1478,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Омогућава да апликација захтева брисање пакета."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"тражење дозволе за игнорисање оптимизација батерије"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Дозвољава апликацији да тражи дозволу за игнорисање оптимизација батерије за ту апликацију."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Додирните двапут за контролу зумирања"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Није могуће додати виџет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Иди"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 256c8ac955bc..f5e1f81bdb05 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Tillåter att en app begär paketborttagning."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"får be om tillstånd att ignorera batterioptimering"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Appen får be om tillstånd att ignorera batterioptimering."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Peka två gånger för zoomkontroll"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Det gick inte att lägga till widgeten."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Kör"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 7780c779372b..c05f866b9d70 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Huruhusu programu kuomba idhini ya kufuta vifurushi."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"omba kupuuza uimarishji wa betri"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Huruhusu programu kuomba ruhusa ya kupuuza uimarishaji wa betri katika programu yako."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Gusa mara mbili kwa udhibiti wa kuza"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Haikuweza kuongeza wijeti."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Nenda"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index f2ada5d4b2d8..9be38c9292a4 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"தொகுப்புகளை நீக்க கோர, ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"பேட்டரி மேம்படுத்தல்களைப் புறக்கணிப்பதற்கான அனுமதியைக் கோரு"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"பயன்பாட்டிற்கான பேட்டரி மேம்படுத்தல்களைப் புறக்கணிப்பதற்கான அனுமதியைக் கோர, ஆப்ஸை அனுமதிக்கும்."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"அளவை மாற்றுவதற்கான கட்டுப்பாட்டிற்கு, இருமுறை தட்டவும்"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"விட்ஜெட்டைச் சேர்க்க முடியவில்லை."</string>
<string name="ime_action_go" msgid="5536744546326495436">"செல்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index f9fbe65230f2..d910224af035 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ప్యాకేజీల తొలగింపును అభ్యర్థించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"బ్యాటరీ అనుకూలీకరణలను విస్మరించడానికి అడగాలి"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ఆ యాప్ కోసం బ్యాటరీ అనుకూలీకరణలు విస్మరించేలా అనుమతి కోరడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"విడ్జెట్‌ను జోడించడం సాధ్యపడలేదు."</string>
<string name="ime_action_go" msgid="5536744546326495436">"వెళ్లు"</string>
@@ -2156,7 +2160,7 @@
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ఈ కంటెంట్ వర్క్ యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో షేర్ చేయడం సాధ్యం కాదు"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
- <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"కార్యాలయ ప్రొఫైల్ పాజ్ చేయబడింది"</string>
+ <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"వర్క్ ప్రొఫైల్ పాజ్ చేయబడింది"</string>
<string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయి"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"వర్క్ యాప్‌లు లేవు"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్‌లు లేవు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 9f3f9c374691..b6c6ed5c296a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"อนุญาตให้แอปพลิเคชันขอการลบแพ็กเกจ"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"ขอเพิกเฉยต่อการเพิ่มประสิทธิภาพแบตเตอรี่"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"อนุญาตให้แอปขอสิทธิ์เพิกเฉยต่อการเพิ่มประสิทธิภาพแบตเตอรี่สำหรับแอปนั้น"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"แตะสองครั้งเพื่อควบคุมการซูม"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ไม่สามารถเพิ่มวิดเจ็ต"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ไป"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4ab94db6281a..4ea1da96a07b 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Pinapayagan ang isang application na humiling ng pag-delete ng mga package."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"hilingin na balewalain ang mga pag-optimize ng baterya"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Pinapayagang humingi ng pahintulot ang isang app na balewalain ang mga pag-optimize ng baterya para sa app na iyon."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tapikin ng dalawang beses para sa pagkontrol ng zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Hindi maidagdag ang widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pumunta"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6702ce436fa3..306fc8240231 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Uygulamaya, paketleri silme isteğinde bulunma izni verir."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"pil optimizasyonlarını göz ardı etme izni iste"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Bir uygulamanın, kendisi için pil optimizasyonlarını göz ardı etme izni istemesine olanak sağlar."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Zum denetimi için iki kez dokun"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget eklenemedi."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Git"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 96c80fd08e0c..baf4a44a3997 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1407,7 +1407,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Виявлено аналоговий аксесуар для аудіо"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Під’єднаний пристрій несумісний із цим телефоном. Торкніться, щоб дізнатися більше."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Налагодження USB підключено"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Торкніться, щоб вимкнути налагодження через USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Торкніться, щоб вимкнути його"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Виберіть, щоб вимкнути налагодження за USB"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Активне налагодження через Wi-Fi"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Натисніть, щоб вимкнути налагодження через Wi-Fi"</string>
@@ -1498,6 +1498,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Додаток зможе надсилати запити на видалення пакетів."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"запитувати дозвіл ігнорувати оптимізацію використання заряду акумулятора"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Додаток зможе запитувати дозвіл ігнорувати оптимізацію використання заряду акумулятора."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Двічі натис. для кер. масшт."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не вдалося додати віджет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Йти"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 3c41e39ca202..83180218325e 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ایپلیکیشن کو پیکجز حذف کرنے کیلئے درخواست کرنے کی اجازت ہے۔"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"بیٹری کی بہتریاں نظر انداز کرنے کا پوچھیں"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"اس ایپ کیلئے ایک ایپ کو بیٹری کی کارکردگی بہتر بنانے کو نظر انداز کرنے کی اجازت دیں۔"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"زوم کنٹرول کیلئے دوبار تھپتھپائیں"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ویجٹس کو شامل نہیں کرسکا۔"</string>
<string name="ime_action_go" msgid="5536744546326495436">"جائیں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 0bbaa7898bc2..4c30b54b9c02 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Ilovaga paketlarni o‘chirib tashlash so‘rovini yuborish imkonini beradi."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"batareya quvvatidan xohlagancha foydalanishni so‘rash"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Ilovaga batareya quvvatidan xohlagancha foydalanish uchun ruxsat so‘rashga imkon beradi."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ko‘lamini o‘zgartirish uchun ikki marta bosing"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Vidjet qo‘shilmadi."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Tanlash"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7e9c54be5c1d..61aba14d354e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Cho phép ứng dụng yêu cầu xóa gói."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"hỏi để bỏ qua tối ưu hóa pin"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Cho phép ứng dụng hỏi quyền để bỏ qua tối ưu hóa pin cho ứng dụng đó."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Nhấn hai lần để kiểm soát thu phóng"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Không thể thêm tiện ích."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Đến"</string>
@@ -1575,7 +1579,7 @@
<string name="storage_usb" msgid="2391213347883616886">"Bộ lưu trữ USB"</string>
<string name="extract_edit_menu_button" msgid="63954536535863040">"Chỉnh sửa"</string>
<string name="data_usage_warning_title" msgid="9034893717078325845">"Cảnh báo dữ liệu"</string>
- <string name="data_usage_warning_body" msgid="1669325367188029454">"Bạn đã sử dụng <xliff:g id="APP">%s</xliff:g> dữ liệu"</string>
+ <string name="data_usage_warning_body" msgid="1669325367188029454">"Bạn đã dùng <xliff:g id="APP">%s</xliff:g> dữ liệu"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Đã đạt đến giới hạn dữ liệu di động"</string>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Đã đạt tới g.hạn dữ liệu Wi-Fi"</string>
<string name="data_usage_limit_body" msgid="3567699582000085710">"Đã tạm dừng dữ liệu đối với chu kỳ còn lại của bạn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1fca2e90dfae..7fefe747094d 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"允许应用请求删除文件包。"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"请求忽略电池优化"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"允许应用请求相应的权限,以便忽略针对该应用的电池优化。"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"双击可以进行缩放控制"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"无法添加微件。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"开始"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 762607064c7e..457f0d518f73 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"允許應用程式要求刪除套件。"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"要求忽略電池優化"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"允許應用程式要求就該應用程式忽略電池優化。"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"輕觸兩下控制縮放"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"開始"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 52ffc605ec63..82be3183f879 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -250,7 +250,7 @@
<string name="global_action_emergency" msgid="1387617624177105088">"緊急電話"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"錯誤報告"</string>
<string name="global_action_logout" msgid="6093581310002476511">"結束"</string>
- <string name="global_action_screenshot" msgid="2610053466156478564">"擷取螢幕畫面"</string>
+ <string name="global_action_screenshot" msgid="2610053466156478564">"螢幕截圖"</string>
<string name="bugreport_title" msgid="8549990811777373050">"錯誤報告"</string>
<string name="bugreport_message" msgid="5212529146119624326">"這會收集你目前裝置狀態的相關資訊,以便透過電子郵件傳送。從錯誤報告開始建立到準備傳送的這段過程可能需要一點時間,敬請耐心等候。"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"互動式報告"</string>
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"允許應用程式要求刪除套件。"</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"要求忽略電池效能最佳化設定"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"允許應用程式要求權限,以便忽略針對該應用程式的電池效能最佳化設定。"</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"點兩下以進行縮放控制"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"開始"</string>
@@ -2135,7 +2139,7 @@
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"快速設定"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"開啟電源對話方塊"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"螢幕鎖定"</string>
- <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"擷取螢幕畫面"</string>
+ <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"螢幕截圖"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"螢幕上的無障礙捷徑"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕上的無障礙捷徑選擇器"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙捷徑"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 899cdd7c42d4..85cf88cfb624 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1458,6 +1458,10 @@
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Ivumela uhlelo lokusebenza ukuthi lucele ukususwa kwamaphakheji."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"cela ukuziba ukulungiselelwa kwebhethri"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Ivumela uhlelo lokusebenza ukuthi licele imvume yokuziba ukulungiselela ibhethri yalolo hlelo lokusebenza."</string>
+ <!-- no translation found for permlab_queryAllPackages (2928450604653281650) -->
+ <skip />
+ <!-- no translation found for permdesc_queryAllPackages (5339069855520996010) -->
+ <skip />
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Thepha kabili ukuthola ukulawula ukusondeza"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Yehlulekile ukwengeza i-widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Iya"</string>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index d94bcfb04926..55ed83b32262 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -140,7 +140,7 @@
<color name="notification_secondary_text_color_light">@color/primary_text_default_material_light</color>
<item name="notification_secondary_text_disabled_alpha" format="float" type="dimen">0.38</item>
<color name="notification_secondary_text_color_dark">@color/primary_text_default_material_dark</color>
- <color name="notification_default_color_dark">@color/primary_text_default_material_light</color>
+ <color name="notification_default_color_dark">#ddffffff</color>
<color name="notification_default_color_light">#a3202124</color>
<color name="notification_primary_text_color_current">@color/notification_primary_text_color_light</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5ac23365eaee..ee33d48768c5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3354,6 +3354,15 @@
(e.g. accessibility, alarms). This is mainly for Wear devices that don't have speakers. -->
<bool name="config_allowPriorityVibrationsInLowPowerMode">false</bool>
+ <!-- The duration (in milliseconds) that should be used to convert vibration ramps to a sequence
+ of fixed amplitude steps on devices without PWLE support. -->
+ <integer name="config_vibrationWaveformRampStepDuration">5</integer>
+
+ <!-- The duration (in milliseconds) that should be applied to waveform vibrations that ends in
+ non-zero amplitudes, . The waveform will
+ be played as a PWLE instead of on/off calls if this value is set. -->
+ <integer name="config_vibrationWaveformRampDownDuration">0</integer>
+
<!-- Number of retries Cell Data should attempt for a given error code before
restarting the modem.
Error codes not listed will not lead to modem restarts.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b574415c0a08..7d685a202538 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2012,6 +2012,8 @@
<java-symbol type="integer" name="config_notificationServiceArchiveSize" />
<java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
<java-symbol type="integer" name="config_defaultVibrationAmplitude" />
+ <java-symbol type="integer" name="config_vibrationWaveformRampStepDuration" />
+ <java-symbol type="integer" name="config_vibrationWaveformRampDownDuration" />
<java-symbol type="integer" name="config_radioScanningTimeout" />
<java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
<java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
index 36cb55407d8d..52608351775c 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
@@ -14,9 +14,11 @@ android_test {
static_libs: [
"androidx.test.rules",
"junit",
+ "mockito-target-minus-junit4",
"platform-test-annotations",
"platformprotosnano",
"statsdprotolite",
+ "truth-prebuilt",
],
libs: ["android.test.runner"],
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
index 333eebb86d4c..7f9d618fc631 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
@@ -17,10 +17,14 @@ package com.android.internal.os;
import static android.os.BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
@@ -37,7 +41,6 @@ import java.util.Arrays;
import java.util.List;
-
@SmallTest
public class BatteryUsageStatsPulledTest {
@@ -225,4 +228,75 @@ public class BatteryUsageStatsPulledTest {
return builder.build();
}
+
+ @Test
+ public void testLargeAtomTruncated() {
+ final BatteryUsageStats.Builder builder =
+ new BatteryUsageStats.Builder(new String[0]);
+ // If not truncated, this BatteryUsageStats object would generate a proto buffer
+ // larger than 70 Kb
+ for (int i = 0; i < 20000; i++) {
+ BatteryStatsImpl.Uid mockUid = mock(BatteryStatsImpl.Uid.class);
+ when(mockUid.getUid()).thenReturn(i);
+ builder.getOrCreateUidBatteryConsumerBuilder(mockUid)
+ .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1 * 60 * 1000)
+ .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 2 * 60 * 1000)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 30)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 40);
+ }
+
+ // Add a UID with much larger battery footprint
+ final int largeConsumerUid = 20001;
+ BatteryStatsImpl.Uid largeConsumerMockUid = mock(BatteryStatsImpl.Uid.class);
+ when(largeConsumerMockUid.getUid()).thenReturn(largeConsumerUid);
+ builder.getOrCreateUidBatteryConsumerBuilder(largeConsumerMockUid)
+ .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 10 * 60 * 1000)
+ .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 20 * 60 * 1000)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 400);
+
+ // Add a UID with much larger usage duration
+ final int highUsageUid = 20002;
+ BatteryStatsImpl.Uid highUsageMockUid = mock(BatteryStatsImpl.Uid.class);
+ when(highUsageMockUid.getUid()).thenReturn(highUsageUid);
+ builder.getOrCreateUidBatteryConsumerBuilder(highUsageMockUid)
+ .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 60 * 60 * 1000)
+ .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 120 * 60 * 1000)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 3)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 4);
+
+ BatteryUsageStats batteryUsageStats = builder.build();
+ final byte[] bytes = batteryUsageStats.getStatsProto();
+ assertThat(bytes.length).isGreaterThan(40000);
+ assertThat(bytes.length).isLessThan(50000);
+
+ BatteryUsageStatsAtomsProto proto;
+ try {
+ proto = BatteryUsageStatsAtomsProto.parseFrom(bytes);
+ } catch (InvalidProtocolBufferNanoException e) {
+ fail("Invalid proto: " + e);
+ return;
+ }
+
+ boolean largeConsumerIncluded = false;
+ boolean highUsageAppIncluded = false;
+ for (int i = 0; i < proto.uidBatteryConsumers.length; i++) {
+ if (proto.uidBatteryConsumers[i].uid == largeConsumerUid) {
+ largeConsumerIncluded = true;
+ BatteryUsageStatsAtomsProto.BatteryConsumerData consumerData =
+ proto.uidBatteryConsumers[i].batteryConsumerData;
+ assertThat(consumerData.totalConsumedPowerDeciCoulombs / 36)
+ .isEqualTo(300 + 400);
+ } else if (proto.uidBatteryConsumers[i].uid == highUsageUid) {
+ highUsageAppIncluded = true;
+ BatteryUsageStatsAtomsProto.BatteryConsumerData consumerData =
+ proto.uidBatteryConsumers[i].batteryConsumerData;
+ assertThat(consumerData.totalConsumedPowerDeciCoulombs / 36)
+ .isEqualTo(3 + 4);
+ }
+ }
+
+ assertThat(largeConsumerIncluded).isTrue();
+ assertThat(highUsageAppIncluded).isTrue();
+ }
}
diff --git a/core/tests/coretests/src/android/os/PackageTagsListTest.java b/core/tests/coretests/src/android/os/PackageTagsListTest.java
index 518e02e44b06..9034a5ccdd7f 100644
--- a/core/tests/coretests/src/android/os/PackageTagsListTest.java
+++ b/core/tests/coretests/src/android/os/PackageTagsListTest.java
@@ -30,6 +30,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
+import java.util.Collections;
@Presubmit
@RunWith(AndroidJUnit4.class)
@@ -40,7 +41,8 @@ public class PackageTagsListTest {
PackageTagsList.Builder builder = new PackageTagsList.Builder()
.add("package1", "attr1")
.add("package1", "attr2")
- .add("package2");
+ .add("package2")
+ .add("package4", Arrays.asList("attr1", "attr2"));
PackageTagsList list = builder.build();
assertTrue(list.contains(builder.build()));
@@ -49,10 +51,13 @@ public class PackageTagsListTest {
assertTrue(list.contains("package2", "attr1"));
assertTrue(list.contains("package2", "attr2"));
assertTrue(list.contains("package2", "attr3"));
+ assertTrue(list.contains("package4", "attr1"));
+ assertTrue(list.contains("package4", "attr2"));
assertTrue(list.containsAll("package2"));
assertTrue(list.includes("package1"));
assertTrue(list.includes("package2"));
assertFalse(list.contains("package1", "attr3"));
+ assertFalse(list.contains("package4", "attr3"));
assertFalse(list.containsAll("package1"));
assertFalse(list.includes("package3"));
@@ -92,6 +97,51 @@ public class PackageTagsListTest {
}
@Test
+ public void testPackageTagsList_Remove() {
+ PackageTagsList.Builder builder = new PackageTagsList.Builder()
+ .add("package1", "attr1")
+ .add("package1", "attr2")
+ .add("package2")
+ .add("package4", Arrays.asList("attr1", "attr2", "attr3"))
+ .add("package3", "attr1")
+ .remove("package1", "attr1")
+ .remove("package1", "attr2")
+ .remove("package2", "attr1")
+ .remove("package4", Arrays.asList("attr1", "attr2"))
+ .remove("package3");
+ PackageTagsList list = builder.build();
+
+ assertTrue(list.contains(builder.build()));
+ assertFalse(list.contains("package1", "attr1"));
+ assertFalse(list.contains("package1", "attr2"));
+ assertTrue(list.contains("package2", "attr1"));
+ assertTrue(list.contains("package2", "attr2"));
+ assertTrue(list.contains("package2", "attr3"));
+ assertFalse(list.contains("package3", "attr1"));
+ assertFalse(list.contains("package4", "attr1"));
+ assertFalse(list.contains("package4", "attr2"));
+ assertTrue(list.contains("package4", "attr3"));
+ assertTrue(list.containsAll("package2"));
+ assertFalse(list.includes("package1"));
+ assertTrue(list.includes("package2"));
+ assertFalse(list.includes("package3"));
+ assertTrue(list.includes("package4"));
+ }
+
+ @Test
+ public void testPackageTagsList_EmptyCollections() {
+ PackageTagsList.Builder builder = new PackageTagsList.Builder()
+ .add("package1", Collections.emptyList())
+ .add("package2")
+ .remove("package2", Collections.emptyList());
+ PackageTagsList list = builder.build();
+
+ assertTrue(list.contains(builder.build()));
+ assertFalse(list.contains("package1", "attr1"));
+ assertTrue(list.contains("package2", "attr2"));
+ }
+
+ @Test
public void testWriteToParcel() {
PackageTagsList list = new PackageTagsList.Builder()
.add("package1", "attr1")
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
index e6a25d00ff10..f28ee46fdf75 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -236,13 +236,13 @@ public class ContentCaptureEventTest {
@Test
public void testMergeEvent_typeViewTextChanged() {
final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_TEXT_CHANGED)
- .setText("test", false);
+ .setText("test");
final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_TEXT_CHANGED)
- .setText("empty", true);
+ .setText("composing").setComposingIndex(0, 1);
event.mergeEvent(event2);
assertThat(event.getText()).isEqualTo(event2.getText());
- assertThat(event.getTextHasComposingSpan()).isEqualTo(event2.getTextHasComposingSpan());
+ assertThat(event.hasComposingSpan()).isEqualTo(event2.hasComposingSpan());
}
@Test
@@ -283,18 +283,18 @@ public class ContentCaptureEventTest {
@Test
public void testMergeEvent_differentEventTypes() {
final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED)
- .setText("test", false).setAutofillId(new AutofillId(1));
+ .setText("test").setAutofillId(new AutofillId(1));
final ContentCaptureEvent event2 = new ContentCaptureEvent(17, TYPE_VIEW_TEXT_CHANGED)
- .setText("empty", true).setAutofillId(new AutofillId(2));
+ .setText("composing").setAutofillId(new AutofillId(2)).setComposingIndex(0, 1);
event.mergeEvent(event2);
assertThat(event.getText()).isEqualTo("test");
- assertThat(event.getTextHasComposingSpan()).isFalse();
+ assertThat(event.hasComposingSpan()).isFalse();
assertThat(event.getId()).isEqualTo(new AutofillId(1));
event2.mergeEvent(event);
- assertThat(event2.getText()).isEqualTo("empty");
- assertThat(event2.getTextHasComposingSpan()).isTrue();
+ assertThat(event2.getText()).isEqualTo("composing");
+ assertThat(event2.hasComposingSpan()).isTrue();
assertThat(event2.getId()).isEqualTo(new AutofillId(2));
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 46e2772b30ca..90a9572b5560 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -44,6 +44,7 @@ import org.junit.runners.Suite;
BatteryStatsUidTest.class,
BatteryUsageStatsProviderTest.class,
BatteryUsageStatsTest.class,
+ BatteryUsageStatsStoreTest.class,
BatteryStatsUserLifecycleTests.class,
BluetoothPowerCalculatorTest.class,
BstatsCpuTimesValidationTest.class,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index d83645d6e0a5..cbd67c8324f4 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -20,10 +20,14 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.ActivityManager;
import android.content.Context;
+import android.os.BatteryConsumer;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.Parcel;
import android.os.Process;
import android.os.UidBatteryConsumer;
@@ -36,6 +40,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.File;
import java.util.List;
@SmallTest
@@ -45,7 +50,8 @@ public class BatteryUsageStatsProviderTest {
private static final long MINUTE_IN_MS = 60 * 1000;
@Rule
- public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345);
+ public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345)
+ .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0);
@Test
public void test_getBatteryUsageStats() {
@@ -187,4 +193,84 @@ public class BatteryUsageStatsProviderTest {
mStatsRule.setTime(11500, 0);
assertThat(provider.shouldUpdateStats(queries, 10000)).isTrue();
}
+
+ @Test
+ public void testAggregateBatteryStats() {
+ Context context = InstrumentationRegistry.getContext();
+ BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
+ mStatsRule.setCurrentTime(5 * MINUTE_IN_MS);
+ batteryStats.resetAllStatsCmdLocked();
+
+ BatteryUsageStatsStore batteryUsageStatsStore = new BatteryUsageStatsStore(context,
+ batteryStats, new File(context.getCacheDir(), "BatteryUsageStatsProviderTest"),
+ new TestHandler(), Integer.MAX_VALUE);
+
+ BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context,
+ batteryStats, batteryUsageStatsStore);
+
+ batteryStats.noteFlashlightOnLocked(APP_UID,
+ 10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
+ batteryStats.noteFlashlightOffLocked(APP_UID,
+ 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
+ mStatsRule.setCurrentTime(25 * MINUTE_IN_MS);
+ batteryStats.resetAllStatsCmdLocked();
+
+ batteryStats.noteFlashlightOnLocked(APP_UID,
+ 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
+ batteryStats.noteFlashlightOffLocked(APP_UID,
+ 50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
+ mStatsRule.setCurrentTime(55 * MINUTE_IN_MS);
+ batteryStats.resetAllStatsCmdLocked();
+
+ // This section should be ignored because the timestamp is out or range
+ batteryStats.noteFlashlightOnLocked(APP_UID,
+ 60 * MINUTE_IN_MS, 60 * MINUTE_IN_MS);
+ batteryStats.noteFlashlightOffLocked(APP_UID,
+ 70 * MINUTE_IN_MS, 70 * MINUTE_IN_MS);
+ mStatsRule.setCurrentTime(75 * MINUTE_IN_MS);
+ batteryStats.resetAllStatsCmdLocked();
+
+ // This section should be ignored because it represents the current stats session
+ batteryStats.noteFlashlightOnLocked(APP_UID,
+ 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
+ batteryStats.noteFlashlightOffLocked(APP_UID,
+ 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS);
+ mStatsRule.setCurrentTime(95 * MINUTE_IN_MS);
+
+ // Include the first and the second snapshot, but not the third or current
+ BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
+ .aggregateSnapshots(20 * MINUTE_IN_MS, 60 * MINUTE_IN_MS)
+ .build();
+ final BatteryUsageStats stats = provider.getBatteryUsageStats(query);
+
+ assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
+ assertThat(stats.getStatsEndTimestamp()).isEqualTo(55 * MINUTE_IN_MS);
+ assertThat(stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+ .isWithin(0.0001)
+ .of(180.0); // 360 mA * 0.5 hours
+ assertThat(stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+ .isEqualTo((10 + 20) * MINUTE_IN_MS);
+ final UidBatteryConsumer uidBatteryConsumer = stats.getUidBatteryConsumers().stream()
+ .filter(uid -> uid.getUid() == APP_UID).findFirst().get();
+ assertThat(uidBatteryConsumer
+ .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+ .isWithin(0.1)
+ .of(180.0);
+ }
+
+ private static class TestHandler extends Handler {
+ TestHandler() {
+ super(Looper.getMainLooper());
+ }
+
+ @Override
+ public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+ msg.getCallback().run();
+ return true;
+ }
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
new file mode 100644
index 000000000000..141a9fa30c85
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.os.BatteryManager;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class BatteryUsageStatsStoreTest {
+ private static final long MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES = 2 * 1024;
+
+ private final MockClocks mMockClocks = new MockClocks();
+ private MockBatteryStatsImpl mBatteryStats;
+ private BatteryUsageStatsStore mBatteryUsageStatsStore;
+ private BatteryUsageStatsProvider mBatteryUsageStatsProvider;
+ private File mStoreDirectory;
+
+ @Before
+ public void setup() {
+ mMockClocks.currentTime = 123;
+ mBatteryStats = new MockBatteryStatsImpl(mMockClocks);
+ mBatteryStats.setNoAutoReset(true);
+ mBatteryStats.setPowerProfile(mock(PowerProfile.class));
+
+ Context context = InstrumentationRegistry.getContext();
+
+ mStoreDirectory = new File(context.getCacheDir(), "BatteryUsageStatsStoreTest");
+ clearDirectory(mStoreDirectory);
+
+ mBatteryUsageStatsStore = new BatteryUsageStatsStore(context, mBatteryStats,
+ mStoreDirectory, new TestHandler(), MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES);
+
+ mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mBatteryStats);
+ }
+
+ @Test
+ public void testStoreSnapshot() {
+ mMockClocks.currentTime = 1_600_000;
+
+ prepareBatteryStats();
+ mBatteryStats.resetAllStatsCmdLocked();
+
+ final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps();
+ assertThat(timestamps).hasLength(1);
+ assertThat(timestamps[0]).isEqualTo(1_600_000);
+
+ final BatteryUsageStats batteryUsageStats = mBatteryUsageStatsStore.loadBatteryUsageStats(
+ 1_600_000);
+ assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(123);
+ assertThat(batteryUsageStats.getStatsEndTimestamp()).isEqualTo(1_600_000);
+ assertThat(batteryUsageStats.getBatteryCapacity()).isEqualTo(4000);
+ assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(5);
+ assertThat(batteryUsageStats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE).getConsumedPower())
+ .isEqualTo(600); // (3_600_000 - 3_000_000) / 1000
+ }
+
+ @Test
+ public void testGarbageCollectOldSnapshots() throws Exception {
+ prepareBatteryStats();
+
+ mMockClocks.realtime = 10_000_000;
+ mMockClocks.uptime = 10_000_000;
+ mMockClocks.currentTime = 10_000_000;
+
+ final int snapshotFileSize = getSnapshotFileSize();
+ final int numberOfSnapshots =
+ (int) (MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES / snapshotFileSize);
+ for (int i = 0; i < numberOfSnapshots + 2; i++) {
+ mBatteryStats.resetAllStatsCmdLocked();
+
+ mMockClocks.realtime += 10_000_000;
+ mMockClocks.uptime += 10_000_000;
+ mMockClocks.currentTime += 10_000_000;
+ prepareBatteryStats();
+ }
+
+ final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps();
+ Arrays.sort(timestamps);
+ assertThat(timestamps).hasLength(numberOfSnapshots);
+ // Two snapshots (10_000_000 and 20_000_000) should have been discarded
+ assertThat(timestamps[0]).isEqualTo(30_000_000);
+ assertThat(getDirectorySize(mStoreDirectory))
+ .isAtMost(MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES);
+ }
+
+ @Test
+ public void testSavingStatsdAtomPullTimestamp() {
+ mBatteryUsageStatsStore.setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(1234);
+ assertThat(mBatteryUsageStatsStore.getLastBatteryUsageStatsBeforeResetAtomPullTimestamp())
+ .isEqualTo(1234);
+ mBatteryUsageStatsStore.setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(5478);
+ assertThat(mBatteryUsageStatsStore.getLastBatteryUsageStatsBeforeResetAtomPullTimestamp())
+ .isEqualTo(5478);
+ }
+
+ private void prepareBatteryStats() {
+ mBatteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100,
+ /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0,
+ mMockClocks.realtime, mMockClocks.uptime, mMockClocks.currentTime);
+ mBatteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100,
+ /* plugType */ 0, 85, 72, 3700, 3_000_000, 4_000_000, 0,
+ mMockClocks.realtime + 500_000, mMockClocks.uptime + 500_000,
+ mMockClocks.currentTime + 500_000);
+ }
+
+ private void clearDirectory(File dir) {
+ if (dir.exists()) {
+ for (File child : dir.listFiles()) {
+ if (child.isDirectory()) {
+ clearDirectory(child);
+ }
+ child.delete();
+ }
+ }
+ }
+
+ private long getDirectorySize(File dir) {
+ long size = 0;
+ if (dir.exists()) {
+ for (File child : dir.listFiles()) {
+ if (child.isDirectory()) {
+ size += getDirectorySize(child);
+ } else {
+ size += child.length();
+ }
+ }
+ }
+ return size;
+ }
+
+ private int getSnapshotFileSize() throws IOException {
+ BatteryUsageStats stats = mBatteryUsageStatsProvider.getBatteryUsageStats(
+ new BatteryUsageStatsQuery.Builder()
+ .setMaxStatsAgeMs(0)
+ .includePowerModels()
+ .build());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ TypedXmlSerializer serializer = Xml.newBinarySerializer();
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ stats.writeXml(serializer);
+ serializer.endDocument();
+ return out.toByteArray().length;
+ }
+
+ private static class TestHandler extends Handler {
+ TestHandler() {
+ super(Looper.getMainLooper());
+ }
+
+ @Override
+ public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+ msg.getCallback().run();
+ return true;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
index 380b4ae7e748..3e620c2bbec6 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -16,8 +16,13 @@
package com.android.internal.os;
+import static android.os.BatteryConsumer.POWER_MODEL_MEASURED_ENERGY;
+import static android.os.BatteryConsumer.POWER_MODEL_POWER_PROFILE;
+import static android.os.BatteryConsumer.POWER_MODEL_UNDEFINED;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
import android.os.BatteryConsumer;
@@ -25,6 +30,9 @@ import android.os.BatteryUsageStats;
import android.os.Parcel;
import android.os.UidBatteryConsumer;
import android.os.UserBatteryConsumer;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -32,8 +40,11 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -42,15 +53,19 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
public class BatteryUsageStatsTest {
+ private static final int USER_ID = 42;
+ private static final int APP_UID1 = 271;
+ private static final int APP_UID2 = 314;
+
@Test
public void testBuilder() {
- BatteryUsageStats batteryUsageStats = buildBatteryUsageStats().build();
- validateBatteryUsageStats(batteryUsageStats);
+ BatteryUsageStats batteryUsageStats = buildBatteryUsageStats1(true).build();
+ assertBatteryUsageStats1(batteryUsageStats, true);
}
@Test
public void testParcelability() {
- final BatteryUsageStats outBatteryUsageStats = buildBatteryUsageStats().build();
+ final BatteryUsageStats outBatteryUsageStats = buildBatteryUsageStats1(true).build();
final Parcel outParcel = Parcel.obtain();
outParcel.writeParcelable(outBatteryUsageStats, 0);
final byte[] bytes = outParcel.marshall();
@@ -62,20 +77,20 @@ public class BatteryUsageStatsTest {
final BatteryUsageStats inBatteryUsageStats =
inParcel.readParcelable(getClass().getClassLoader());
assertThat(inBatteryUsageStats).isNotNull();
- validateBatteryUsageStats(inBatteryUsageStats);
+ assertBatteryUsageStats1(inBatteryUsageStats, true);
}
@Test
public void testDefaultSessionDuration() {
final BatteryUsageStats stats =
- buildBatteryUsageStats().setStatsDuration(10000).build();
+ buildBatteryUsageStats1(true).setStatsDuration(10000).build();
assertThat(stats.getStatsDuration()).isEqualTo(10000);
}
@Test
public void testDump() {
- final BatteryUsageStats stats = buildBatteryUsageStats().build();
+ final BatteryUsageStats stats = buildBatteryUsageStats1(true).build();
final StringWriter out = new StringWriter();
try (PrintWriter pw = new PrintWriter(out)) {
stats.dump(pw, " ");
@@ -87,7 +102,7 @@ public class BatteryUsageStatsTest {
assertThat(dump).contains("actual drain: 1000-2000");
assertThat(dump).contains("cpu: 20100 apps: 10100 duration: 20s 300ms");
assertThat(dump).contains("FOO: 20200 apps: 10200 duration: 20s 400ms");
- assertThat(dump).contains("UID 2000: 1200 ( screen=300 cpu=400 FOO=500 )");
+ assertThat(dump).contains("UID 271: 1200 ( screen=300 cpu=400 FOO=500 )");
assertThat(dump).contains("User 42: 30.0 ( cpu=10.0 FOO=20.0 )");
}
@@ -101,154 +116,297 @@ public class BatteryUsageStatsTest {
assertThat(allNames).hasSize(BatteryConsumer.POWER_COMPONENT_COUNT);
}
- private BatteryUsageStats.Builder buildBatteryUsageStats() {
+ @Test
+ public void testAdd() {
+ final BatteryUsageStats stats1 = buildBatteryUsageStats1(false).build();
+ final BatteryUsageStats stats2 = buildBatteryUsageStats2(new String[] {"FOO"}).build();
+
+ final BatteryUsageStats sum =
+ new BatteryUsageStats.Builder(new String[] {"FOO"}, true)
+ .add(stats1)
+ .add(stats2)
+ .build();
+
+ assertBatteryUsageStats(sum, 42345, 50, 2234, 4345, 1000, 5000, 5000);
+
+ final List<UidBatteryConsumer> uidBatteryConsumers =
+ sum.getUidBatteryConsumers();
+ for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
+ if (uidBatteryConsumer.getUid() == APP_UID1) {
+ assertUidBatteryConsumer(uidBatteryConsumer, 2124, null,
+ 5321, 7432, 423, POWER_MODEL_POWER_PROFILE, 745, POWER_MODEL_UNDEFINED,
+ 956, 1167, 1478);
+ } else if (uidBatteryConsumer.getUid() == APP_UID2) {
+ assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar",
+ 1111, 2222, 333, POWER_MODEL_POWER_PROFILE, 444, POWER_MODEL_POWER_PROFILE,
+ 555, 666, 777);
+ } else {
+ fail("Unexpected UID " + uidBatteryConsumer.getUid());
+ }
+ }
+
+ assertAggregateBatteryConsumer(sum,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
+ 20223, 20434, 20645, 20856);
+
+ assertAggregateBatteryConsumer(sum,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
+ 40211, 40422, 40633, 40844);
+ }
+
+ @Test
+ public void testAdd_customComponentMismatch() {
+ final BatteryUsageStats.Builder builder =
+ new BatteryUsageStats.Builder(new String[] {"FOO"}, true);
+ final BatteryUsageStats stats = buildBatteryUsageStats2(new String[] {"BAR"}).build();
+
+ assertThrows(IllegalArgumentException.class, () -> builder.add(stats));
+ }
+
+ @Test
+ public void testXml() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ TypedXmlSerializer serializer = Xml.newBinarySerializer();
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ final BatteryUsageStats stats = buildBatteryUsageStats1(true).build();
+ stats.writeXml(serializer);
+ serializer.endDocument();
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ TypedXmlPullParser parser = Xml.newBinaryPullParser();
+ parser.setInput(in, StandardCharsets.UTF_8.name());
+ final BatteryUsageStats fromXml = BatteryUsageStats.createFromXml(parser);
+
+ assertBatteryUsageStats1(fromXml, true);
+ }
+
+ private BatteryUsageStats.Builder buildBatteryUsageStats1(boolean includeUserBatteryConsumer) {
final MockClocks clocks = new MockClocks();
final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
- final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(2000);
final BatteryUsageStats.Builder builder =
- new BatteryUsageStats.Builder(new String[]{"FOO"}, true)
+ new BatteryUsageStats.Builder(new String[] {"FOO"}, true)
.setBatteryCapacity(4000)
.setDischargePercentage(20)
.setDischargedPowerRange(1000, 2000)
.setStatsStartTimestamp(1000)
.setStatsEndTimestamp(3000);
- builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid)
- .setPackageWithHighestDrain("foo")
- .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, 1000)
- .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, 2000)
- .setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
- .setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU, 400)
- .setConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 500)
- .setUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU, 600)
- .setUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 800);
- builder.getAggregateBatteryConsumerBuilder(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU, 10100)
- .setConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200)
- .setUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU, 10300)
- .setUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400);
+ addUidBatteryConsumer(builder, batteryStats, APP_UID1, "foo",
+ 1000, 2000,
+ 300, POWER_MODEL_POWER_PROFILE, 400, POWER_MODEL_POWER_PROFILE, 500, 600, 800);
+
+ addAggregateBatteryConsumer(builder,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, 0,
+ 10100, 10200, 10300, 10400);
+
+ addAggregateBatteryConsumer(builder,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, 30000,
+ 20100, 20200, 20300, 20400);
+
+
+ if (includeUserBatteryConsumer) {
+ builder.getOrCreateUserBatteryConsumerBuilder(USER_ID)
+ .setConsumedPower(
+ BatteryConsumer.POWER_COMPONENT_CPU, 10)
+ .setConsumedPowerForCustomComponent(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20)
+ .setUsageDurationMillis(
+ BatteryConsumer.POWER_COMPONENT_CPU, 30)
+ .setUsageDurationForCustomComponentMillis(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40);
+ }
+ return builder;
+ }
+
+ private BatteryUsageStats.Builder buildBatteryUsageStats2(String[] customPowerComponentNames) {
+ final MockClocks clocks = new MockClocks();
+ final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
+
+ final BatteryUsageStats.Builder builder =
+ new BatteryUsageStats.Builder(customPowerComponentNames, true)
+ .setDischargePercentage(30)
+ .setDischargedPowerRange(1234, 2345)
+ .setStatsStartTimestamp(2000)
+ .setStatsEndTimestamp(5000);
- builder.getAggregateBatteryConsumerBuilder(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
- .setConsumedPower(30000)
+ addUidBatteryConsumer(builder, batteryStats, APP_UID1, null,
+ 4321, 5432,
+ 123, POWER_MODEL_POWER_PROFILE, 345, POWER_MODEL_MEASURED_ENERGY, 456, 567, 678);
+
+ addUidBatteryConsumer(builder, batteryStats, APP_UID2, "bar",
+ 1111, 2222,
+ 333, POWER_MODEL_POWER_PROFILE, 444, POWER_MODEL_POWER_PROFILE, 555, 666, 777);
+
+ addAggregateBatteryConsumer(builder,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, 0,
+ 10123, 10234, 10345, 10456);
+
+ addAggregateBatteryConsumer(builder,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, 12345,
+ 20111, 20222, 20333, 20444);
+
+ return builder;
+ }
+
+ private void addUidBatteryConsumer(BatteryUsageStats.Builder builder,
+ MockBatteryStatsImpl batteryStats, int uid, String packageWithHighestDrain,
+ int timeInStateForeground, int timeInStateBackground, int screenPower,
+ int screenPowerModel, int cpuPower, int cpuPowerModel, int customComponentPower,
+ int cpuDuration, int customComponentDuration) {
+ final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(uid);
+ builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid)
+ .setPackageWithHighestDrain(packageWithHighestDrain)
+ .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, timeInStateForeground)
+ .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, timeInStateBackground)
.setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU, 20100)
+ BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel)
+ .setConsumedPower(
+ BatteryConsumer.POWER_COMPONENT_CPU, cpuPower, cpuPowerModel)
.setConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200)
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower)
.setUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU, 20300)
+ BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration)
.setUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20400);
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentDuration);
+ }
- builder.getOrCreateUserBatteryConsumerBuilder(42)
+ private void addAggregateBatteryConsumer(BatteryUsageStats.Builder builder, int scope,
+ double consumedPower, int cpuPower, int customComponentPower, int cpuDuration,
+ int customComponentDuration) {
+ builder.getAggregateBatteryConsumerBuilder(scope)
+ .setConsumedPower(consumedPower)
.setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU, 10)
+ BatteryConsumer.POWER_COMPONENT_CPU, cpuPower)
.setConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20)
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower)
.setUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU, 30)
+ BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration)
.setUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40);
-
- return builder;
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentDuration);
}
- public void validateBatteryUsageStats(BatteryUsageStats batteryUsageStats) {
- assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(30000);
- assertThat(batteryUsageStats.getBatteryCapacity()).isEqualTo(4000);
- assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(20);
- assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(1000);
- assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(2000);
- assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(1000);
- assertThat(batteryUsageStats.getStatsEndTimestamp()).isEqualTo(3000);
- assertThat(batteryUsageStats.getStatsDuration()).isEqualTo(2000);
+ public void assertBatteryUsageStats1(BatteryUsageStats batteryUsageStats,
+ boolean includesUserBatteryConsumers) {
+ assertBatteryUsageStats(batteryUsageStats, 30000, 20, 1000, 2000, 1000, 3000, 2000);
final List<UidBatteryConsumer> uidBatteryConsumers =
batteryUsageStats.getUidBatteryConsumers();
+ assertThat(uidBatteryConsumers).hasSize(1);
for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
- if (uidBatteryConsumer.getUid() == 2000) {
- assertThat(uidBatteryConsumer.getPackageWithHighestDrain()).isEqualTo("foo");
- assertThat(uidBatteryConsumer.getTimeInStateMs(
- UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(1000);
- assertThat(uidBatteryConsumer.getTimeInStateMs(
- UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(2000);
- assertThat(uidBatteryConsumer.getConsumedPower(
- BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(300);
- assertThat(uidBatteryConsumer.getConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(400);
- assertThat(uidBatteryConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(500);
- assertThat(uidBatteryConsumer.getUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(600);
- assertThat(uidBatteryConsumer.getUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(800);
- assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(1200);
- assertThat(uidBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
- assertThat(uidBatteryConsumer.getCustomPowerComponentName(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
+ if (uidBatteryConsumer.getUid() == APP_UID1) {
+ assertUidBatteryConsumer(uidBatteryConsumer, 1200, "foo",
+ 1000, 2000, 300, POWER_MODEL_POWER_PROFILE, 400, POWER_MODEL_POWER_PROFILE,
+ 500, 600, 800);
} else {
fail("Unexpected UID " + uidBatteryConsumer.getUid());
}
}
+ final List<UserBatteryConsumer> userBatteryConsumers =
+ batteryUsageStats.getUserBatteryConsumers();
+ if (includesUserBatteryConsumers) {
+ assertThat(userBatteryConsumers).hasSize(1);
+ for (UserBatteryConsumer userBatteryConsumer : userBatteryConsumers) {
+ if (userBatteryConsumer.getUserId() == USER_ID) {
+ assertUserBatteryConsumer(userBatteryConsumer, 42, 10, 20, 30, 40);
+ } else {
+ fail("Unexpected User ID " + userBatteryConsumer.getUserId());
+ }
+ }
+ } else {
+ assertThat(userBatteryConsumers).isEmpty();
+ }
+
+ assertAggregateBatteryConsumer(batteryUsageStats,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
+ 10100, 10200, 10300, 10400);
+
+ assertAggregateBatteryConsumer(batteryUsageStats,
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
+ 20100, 20200, 20300, 20400);
+ }
+
+ private void assertBatteryUsageStats(BatteryUsageStats batteryUsageStats, int consumedPower,
+ int dischargePercentage, int dischagePowerLower, int dischargePowerUpper,
+ int statsStartTimestamp, int statsEndTimestamp, int statsDuration) {
+ assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(consumedPower);
+ assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(dischargePercentage);
+ assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(
+ dischagePowerLower);
+ assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(
+ dischargePowerUpper);
+ assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(statsStartTimestamp);
+ assertThat(batteryUsageStats.getStatsEndTimestamp()).isEqualTo(statsEndTimestamp);
+ assertThat(batteryUsageStats.getStatsDuration()).isEqualTo(statsDuration);
+ }
+
+ private void assertUidBatteryConsumer(UidBatteryConsumer uidBatteryConsumer,
+ int consumedPower, String packageWithHighestDrain, int timeInStateForeground,
+ int timeInStateBackground, int screenPower, int screenPowerModel, int cpuPower,
+ int cpuPowerModel, int customComponentPower, int cpuDuration,
+ int customComponentDuration) {
+ assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(consumedPower);
+ assertThat(uidBatteryConsumer.getPackageWithHighestDrain()).isEqualTo(
+ packageWithHighestDrain);
+ assertThat(uidBatteryConsumer.getTimeInStateMs(
+ UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(timeInStateForeground);
+ assertThat(uidBatteryConsumer.getTimeInStateMs(
+ UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(timeInStateBackground);
+ assertThat(uidBatteryConsumer.getConsumedPower(
+ BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPower);
+ assertThat(uidBatteryConsumer.getPowerModel(
+ BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPowerModel);
+ assertThat(uidBatteryConsumer.getConsumedPower(
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
+ assertThat(uidBatteryConsumer.getPowerModel(
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPowerModel);
+ assertThat(uidBatteryConsumer.getConsumedPowerForCustomComponent(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
+ assertThat(uidBatteryConsumer.getUsageDurationMillis(
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration);
+ assertThat(uidBatteryConsumer.getUsageDurationForCustomComponentMillis(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(
+ customComponentDuration);
+ assertThat(uidBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
+ assertThat(uidBatteryConsumer.getCustomPowerComponentName(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
+ }
+
+ private void assertUserBatteryConsumer(UserBatteryConsumer userBatteryConsumer,
+ int userId, int cpuPower, int customComponentPower,
+ int cpuDuration, int customComponentDuration) {
+ assertThat(userBatteryConsumer.getConsumedPower(
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
+ assertThat(userBatteryConsumer.getConsumedPowerForCustomComponent(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
+ assertThat(userBatteryConsumer.getUsageDurationMillis(
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration);
+ assertThat(userBatteryConsumer.getUsageDurationForCustomComponentMillis(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(
+ customComponentDuration);
+ assertThat(userBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
+ assertThat(userBatteryConsumer.getCustomPowerComponentName(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
+ }
+
+ private void assertAggregateBatteryConsumer(BatteryUsageStats batteryUsageStats,
+ int aggregateBatteryConsumerScopeAllApps, int cpuPower, int customComponentPower,
+ int cpuDuration, int customComponentDuration) {
final BatteryConsumer appsBatteryConsumer = batteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
+ aggregateBatteryConsumerScopeAllApps);
assertThat(appsBatteryConsumer.getConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10100);
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(10200);
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
assertThat(appsBatteryConsumer.getUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10300);
+ BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration);
assertThat(appsBatteryConsumer.getUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(10400);
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(
+ customComponentDuration);
assertThat(appsBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
assertThat(appsBatteryConsumer.getCustomPowerComponentName(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
-
- final BatteryConsumer deviceBatteryConsumer = batteryUsageStats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
- assertThat(deviceBatteryConsumer.getConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(20100);
- assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20200);
- assertThat(deviceBatteryConsumer.getUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(20300);
- assertThat(deviceBatteryConsumer.getUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20400);
- assertThat(deviceBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
- assertThat(deviceBatteryConsumer.getCustomPowerComponentName(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
-
- final List<UserBatteryConsumer> userBatteryConsumers =
- batteryUsageStats.getUserBatteryConsumers();
- for (UserBatteryConsumer userBatteryConsumer : userBatteryConsumers) {
- if (userBatteryConsumer.getUserId() == 42) {
- assertThat(userBatteryConsumer.getConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10);
- assertThat(userBatteryConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20);
- assertThat(userBatteryConsumer.getUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(30);
- assertThat(userBatteryConsumer.getUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(40);
- assertThat(userBatteryConsumer.getConsumedPower()).isEqualTo(30);
- assertThat(userBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
- assertThat(userBatteryConsumer.getCustomPowerComponentName(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
- } else {
- fail("Unexpected user ID " + userBatteryConsumer.getUserId());
- }
- }
}
}
diff --git a/data/etc/car/com.android.car.cluster.home.xml b/data/etc/car/com.android.car.cluster.home.xml
index e1d2b18d7167..a3d0fcffc813 100644
--- a/data/etc/car/com.android.car.cluster.home.xml
+++ b/data/etc/car/com.android.car.cluster.home.xml
@@ -18,5 +18,6 @@
<privapp-permissions package="com.android.car.cluster.home">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"/>
+ <permission name="android.car.permission.CAR_MONITOR_INPUT"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.android.car.rotary.xml b/data/etc/car/com.android.car.rotary.xml
index eddef1acbbc7..a39b244da358 100644
--- a/data/etc/car/com.android.car.rotary.xml
+++ b/data/etc/car/com.android.car.rotary.xml
@@ -18,6 +18,7 @@
<privapp-permissions package="com.android.car.rotary">
<permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <permission name="android.car.permission.CAR_MONITOR_INPUT"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 3c9086dde021..ac5e2d0fcacb 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -961,6 +961,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/AppTransitionController.java"
},
+ "-1003678883": {
+ "message": "Cleaning splash screen token=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-1003060523": {
"message": "Finish needs to pause: %s",
"level": "VERBOSE",
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 954d062b55e9..6aa74cb415f9 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -753,8 +753,12 @@ public class HardwareRenderer {
nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
}
+ private ASurfaceTransactionCallback mASurfaceTransactionCallback;
+
/** @hide */
public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) {
+ // ensure callback is kept alive on the java side since weak ref is used in native code
+ mASurfaceTransactionCallback = callback;
nSetASurfaceTransactionCallback(mNativeProxy, callback);
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index fe80b5845bf5..1651a8cdcad5 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -221,6 +221,7 @@ public class RippleDrawable extends LayerDrawable {
private boolean mForceSoftware;
// Patterned
+ private boolean mAddRipple = false;
private float mTargetBackgroundOpacity;
private ValueAnimator mBackgroundAnimation;
private float mBackgroundOpacity;
@@ -716,6 +717,7 @@ public class RippleDrawable extends LayerDrawable {
}
cancelExitingRipples();
+ exitPatternedAnimation();
}
@Override
@@ -807,7 +809,7 @@ public class RippleDrawable extends LayerDrawable {
}
private void startPatternedAnimation() {
- mRippleActive = true;
+ mAddRipple = true;
invalidateSelf(false);
}
@@ -862,17 +864,17 @@ public class RippleDrawable extends LayerDrawable {
h = bounds.height();
w = bounds.width();
}
- boolean shouldAnimate = mRippleActive;
+ boolean addRipple = mAddRipple;
boolean shouldExit = mExitingAnimation;
- mRippleActive = false;
mExitingAnimation = false;
- if (mRunningAnimations.size() > 0 && !shouldAnimate) {
+ mAddRipple = false;
+ if (mRunningAnimations.size() > 0 && !addRipple) {
// update paint when view is invalidated
getRipplePaint();
}
drawContent(canvas);
drawPatternedBackground(canvas, cx, cy);
- if (shouldAnimate && mRunningAnimations.size() <= MAX_RIPPLES) {
+ if (addRipple && mRunningAnimations.size() <= MAX_RIPPLES) {
RippleAnimationSession.AnimationProperties<Float, Paint> properties =
createAnimationProperties(x, y, cx, cy, w, h);
mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps)
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 0195f3df83a6..c5e79f87ca50 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -62,9 +62,9 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubble schließen"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Unterhaltung nicht als Bubble anzeigen"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bubbles zum Chatten verwenden"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Neue Unterhaltungen erscheinen als unverankerte Symbole, \"Bubbles\" genannt. Wenn du die Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Neue Unterhaltungen erscheinen als unverankerte Symbole, „Bubbles“ genannt. Wenn du eine Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Bubble-Einstellungen festlegen"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tippe auf \"Verwalten\", um Bubbles für diese App zu deaktivieren"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tippe auf „Verwalten“, um Bubbles für diese App zu deaktivieren"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Keine kürzlich geschlossenen Bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Hier werden aktuelle und geschlossene Bubbles angezeigt"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 34f75dab7a1b..c788a03a5b29 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -62,7 +62,7 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignora bolla"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Non mettere la conversazione nella bolla"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatta utilizzando le bolle"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Le nuove conversazioni vengono visualizzate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Le nuove conversazioni vengono mostrate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Controlla le bolle quando vuoi"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tocca Gestisci per disattivare le bolle dall\'app"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index ef5ed00b4bda..36700bd81717 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -63,7 +63,7 @@
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"会話をバブルで表示しない"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"チャットでバブルを使う"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新しい会話はフローティング アイコン(バブル)として表示されます。タップするとバブルが開きます。ドラッグしてバブルを移動できます。"</string>
- <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"いつでもバブルを管理"</string>
+ <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"バブルはいつでも管理可能"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"このアプリからのバブルを OFF にするには、[管理] をタップしてください"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近閉じたバブルはありません"</string>
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 4c2863e4f594..8cea869aea34 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -40,7 +40,7 @@
<integer name="long_press_dock_anim_duration">250</integer>
<!-- Animation duration for translating of one handed when trigger / dismiss. -->
- <integer name="config_one_handed_translate_animation_duration">800</integer>
+ <integer name="config_one_handed_translate_animation_duration">600</integer>
<!-- One handed mode default offset % of display size -->
<fraction name="config_one_handed_offset">40%</fraction>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index f7fb63d9ab98..4b1955e56a6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -325,6 +325,13 @@ public class ShellTaskOrganizer extends TaskOrganizer {
}
@Override
+ public void onAppSplashScreenViewRemoved(int taskId) {
+ if (mStartingWindow != null) {
+ mStartingWindow.onAppSplashScreenViewRemoved(taskId);
+ }
+ }
+
+ @Override
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
synchronized (mLock) {
onTaskAppeared(new TaskAppearedInfo(taskInfo, leash));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 8c8a56a773f7..dfd878f63283 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -368,6 +368,13 @@ public class BubbleController {
return;
}
}
+ for (Bubble b : mBubbleData.getOverflowBubbles()) {
+ if (task.taskId == b.getTaskId()) {
+ promoteBubbleFromOverflow(b);
+ mBubbleData.setExpanded(true);
+ return;
+ }
+ }
}
});
@@ -815,7 +822,35 @@ public class BubbleController {
setIsBubble(bubble, true /* isBubble */);
}
- @VisibleForTesting
+ /**
+ * Expands and selects the provided bubble as long as it already exists in the stack or the
+ * overflow.
+ *
+ * This is currently only used when opening a bubble via clicking on a conversation widget.
+ */
+ public void expandStackAndSelectBubble(Bubble b) {
+ if (b == null) {
+ return;
+ }
+ if (mBubbleData.hasBubbleInStackWithKey(b.getKey())) {
+ // already in the stack
+ mBubbleData.setSelectedBubble(b);
+ mBubbleData.setExpanded(true);
+ } else if (mBubbleData.hasOverflowBubbleWithKey(b.getKey())) {
+ // promote it out of the overflow
+ promoteBubbleFromOverflow(b);
+ }
+ }
+
+ /**
+ * Expands and selects a bubble based on the provided {@link BubbleEntry}. If no bubble
+ * exists for this entry, and it is able to bubble, a new bubble will be created.
+ *
+ * This is the method to use when opening a bubble via a notification or in a state where
+ * the device might not be unlocked.
+ *
+ * @param entry the entry to use for the bubble.
+ */
public void expandStackAndSelectBubble(BubbleEntry entry) {
if (mIsStatusBarShade) {
mNotifEntryToExpandOnShadeUnlock = null;
@@ -1383,6 +1418,21 @@ public class BubbleController {
}
@Override
+ public void expandStackAndSelectBubble(Bubble bubble) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.expandStackAndSelectBubble(bubble);
+ });
+ }
+
+ @Override
+ @Nullable
+ public Bubble getBubbleWithShortcutId(String shortcutId) {
+ return mMainExecutor.executeBlockingForResult(() -> {
+ return BubbleController.this.mBubbleData.getAnyBubbleWithShortcutId(shortcutId);
+ }, Bubble.class);
+ }
+
+ @Override
public void onTaskbarChanged(Bundle b) {
mMainExecutor.execute(() -> {
BubbleController.this.onTaskbarChanged(b);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 69a741c674db..6f5cfd114688 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -26,6 +26,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.LocusId;
import android.content.pm.ShortcutInfo;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -874,6 +875,34 @@ public class BubbleData {
return b;
}
+ /** @return any bubble (in the stack or the overflow) that matches the provided shortcutId. */
+ @Nullable
+ Bubble getAnyBubbleWithShortcutId(String shortcutId) {
+ if (TextUtils.isEmpty(shortcutId)) {
+ return null;
+ }
+ for (int i = 0; i < mBubbles.size(); i++) {
+ Bubble bubble = mBubbles.get(i);
+ String bubbleShortcutId = bubble.getShortcutInfo() != null
+ ? bubble.getShortcutInfo().getId()
+ : bubble.getMetadataShortcutId();
+ if (shortcutId.equals(bubbleShortcutId)) {
+ return bubble;
+ }
+ }
+
+ for (int i = 0; i < mOverflowBubbles.size(); i++) {
+ Bubble bubble = mOverflowBubbles.get(i);
+ String bubbleShortcutId = bubble.getShortcutInfo() != null
+ ? bubble.getShortcutInfo().getId()
+ : bubble.getMetadataShortcutId();
+ if (shortcutId.equals(bubbleShortcutId)) {
+ return bubble;
+ }
+ }
+ return null;
+ }
+
@VisibleForTesting(visibility = PRIVATE)
@Nullable
public Bubble getBubbleInStackWithKey(String key) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 16b8150467fd..c71f123459ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -50,7 +50,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
-import android.view.WindowInsets;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.FrameLayout;
@@ -1018,7 +1017,10 @@ public class BubbleStackView extends FrameLayout
removeView(mDismissView);
}
mDismissView = new DismissView(getContext());
+ int elevation = getResources().getDimensionPixelSize(R.dimen.bubble_elevation);
+
addView(mDismissView);
+ mDismissView.setElevation(elevation);
final ContentResolver contentResolver = getContext().getContentResolver();
final int dismissRadius = Settings.Secure.getInt(
@@ -1028,6 +1030,8 @@ public class BubbleStackView extends FrameLayout
// MagnetizedObjects.
mMagneticTarget = new MagnetizedObject.MagneticTarget(
mDismissView.getCircle(), dismissRadius);
+
+ mBubbleContainer.bringToFront();
}
// TODO: Create ManageMenuView and move setup / animations there
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index a93ce01dfc7b..c73b5eebc5c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -118,6 +118,19 @@ public interface Bubbles {
*/
void expandStackAndSelectBubble(BubbleEntry entry);
+ /**
+ * Request the stack expand if needed, then select the specified Bubble as current.
+ *
+ * @param bubble the bubble to be selected
+ */
+ void expandStackAndSelectBubble(Bubble bubble);
+
+ /**
+ * @return a bubble that matches the provided shortcutId, if one exists.
+ */
+ @Nullable
+ Bubble getBubbleWithShortcutId(String shortcutId);
+
/** Called for any taskbar changes. */
void onTaskbarChanged(Bundle b);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
index ee2202a48bf2..261ff2f8de83 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
@@ -550,12 +550,14 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays
update(mDisplayController.getDisplayContext(
mContext.getDisplayId()).getResources().getConfiguration());
// Set resizable directly here because applyEnterSplit already resizes home stack.
- mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
+ mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits,
+ mRotateSplitLayout != null ? mRotateSplitLayout : mSplitLayout);
}
public void prepareEnterSplitTransition(WindowContainerTransaction outWct) {
// Set resizable directly here because buildEnterSplit already resizes home stack.
- mHomeStackResizable = mWindowManagerProxy.buildEnterSplit(outWct, mSplits, mSplitLayout);
+ mHomeStackResizable = mWindowManagerProxy.buildEnterSplit(outWct, mSplits,
+ mRotateSplitLayout != null ? mRotateSplitLayout : mSplitLayout);
}
public void finishEnterSplitTransition(boolean minimized) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
index 8dc05de9bb8f..a525c2c0219c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
@@ -68,6 +68,11 @@ public interface OneHanded {
void setLockedDisabled(boolean locked, boolean enabled);
/**
+ * Registers callback to notify WMShell when user tap shortcut to expand notification.
+ */
+ void registerEventCallback(OneHandedEventCallback callback);
+
+ /**
* Registers callback to be notified after {@link OneHandedDisplayAreaOrganizer}
* transition start or finish
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 49266ce1bb62..b43daa0da2c0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -43,6 +43,7 @@ import android.util.Slog;
import android.view.Surface;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -71,6 +72,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
"persist.debug.one_handed_offset_percentage";
private static final String ONE_HANDED_MODE_GESTURAL_OVERLAY =
"com.android.internal.systemui.onehanded.gestural";
+ private static final int OVERLAY_ENABLED_DELAY_MS = 250;
+ private static final int DISPLAY_AREA_READY_RETRY_MS = 10;
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
@@ -98,6 +101,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private final Handler mMainHandler;
private final OneHandedImpl mImpl = new OneHandedImpl();
+ private OneHandedEventCallback mEventCallback;
private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;
@@ -287,7 +291,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mTimeoutObserver = getObserver(this::onTimeoutSettingChanged);
mTaskChangeExitObserver = getObserver(this::onTaskChangeExitSettingChanged);
mSwipeToNotificationEnabledObserver =
- getObserver(this::onSwipeToNotificationEnabledSettingChanged);
+ getObserver(this::onSwipeToNotificationEnabledChanged);
mDisplayController.addDisplayChangingController(mRotationController);
setupCallback();
@@ -357,14 +361,23 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
Slog.d(TAG, "Temporary lock disabled");
return;
}
+
+ if (!mDisplayAreaOrganizer.isReady()) {
+ // Must wait until DisplayAreaOrganizer is ready for transitioning.
+ mMainExecutor.executeDelayed(this::startOneHanded, DISPLAY_AREA_READY_RETRY_MS);
+ return;
+ }
+
if (mState.isTransitioning() || mState.isInOneHanded()) {
return;
}
+
final int currentRotation = mDisplayAreaOrganizer.getDisplayLayout().rotation();
if (currentRotation != Surface.ROTATION_0 && currentRotation != Surface.ROTATION_180) {
Slog.w(TAG, "One handed mode only support portrait mode");
return;
}
+
mState.setState(STATE_ENTERING);
final int yOffSet = Math.round(
mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
@@ -393,6 +406,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mOneHandedUiEventLogger.writeEvent(uiEvent);
}
+ void registerEventCallback(OneHandedEventCallback callback) {
+ mEventCallback = callback;
+ }
+
@VisibleForTesting
void registerTransitionCallback(OneHandedTransitionCallback callback) {
mDisplayAreaOrganizer.registerTransitionCallback(callback);
@@ -463,8 +480,29 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
@VisibleForTesting
+ void notifyExpandNotification() {
+ mMainExecutor.execute(() -> mEventCallback.notifyExpandNotification());
+ }
+
+ @VisibleForTesting
+ void notifyUserConfigChanged(boolean success) {
+ if (!success) {
+ return;
+ }
+ // TODO Check UX if popup Toast to notify user when auto-enabled one-handed is good option.
+ Toast.makeText(mContext, R.string.one_handed_tutorial_title, Toast.LENGTH_LONG).show();
+ }
+
+ @VisibleForTesting
void onActivatedActionChanged() {
- if (mState.isTransitioning() || !isOneHandedEnabled()) {
+ if (!isOneHandedEnabled()) {
+ final boolean success = mOneHandedSettingsUtil.setOneHandedModeEnabled(
+ mContext.getContentResolver(), 1 /* Enabled for shortcut */, mUserId);
+ notifyUserConfigChanged(success);
+ }
+
+ if (isSwipeToNotificationEnabled()) {
+ notifyExpandNotification();
return;
}
@@ -495,7 +533,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
// Also checks swipe to notification settings since they all need gesture overlay.
setEnabledGesturalOverlay(
enabled || mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
- mContext.getContentResolver(), mUserId));
+ mContext.getContentResolver(), mUserId), true /* DelayExecute */);
}
@VisibleForTesting
@@ -539,7 +577,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
@VisibleForTesting
- void onSwipeToNotificationEnabledSettingChanged() {
+ void onSwipeToNotificationEnabledChanged() {
final boolean enabled =
mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
mContext.getContentResolver(), mUserId);
@@ -548,7 +586,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
// Also checks one handed mode settings since they all need gesture overlay.
setEnabledGesturalOverlay(
enabled || mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
- mContext.getContentResolver(), mUserId));
+ mContext.getContentResolver(), mUserId), true /* DelayExecute */);
}
private void setupTimeoutListener() {
@@ -566,11 +604,19 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
return mIsOneHandedEnabled;
}
+ @VisibleForTesting
+ boolean isSwipeToNotificationEnabled() {
+ return mIsSwipeToNotificationEnabled;
+ }
+
private void updateOneHandedEnabled() {
if (mState.getState() == STATE_ENTERING || mState.getState() == STATE_ACTIVE) {
mMainExecutor.execute(() -> stopOneHanded());
}
+ // Reset and align shortcut one_handed_mode_activated status with current mState
+ notifyShortcutState(mState.getState());
+
mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
if (!mIsOneHandedEnabled) {
@@ -605,12 +651,19 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
if (info != null && !info.isEnabled()) {
// Enable the default gestural one handed overlay.
- setEnabledGesturalOverlay(true);
+ setEnabledGesturalOverlay(true /* enabled */, false /* delayExecute */);
}
}
@VisibleForTesting
- private void setEnabledGesturalOverlay(boolean enabled) {
+ private void setEnabledGesturalOverlay(boolean enabled, boolean delayExecute) {
+ if (mState.isTransitioning() || delayExecute) {
+ // Enabled overlay package may affect the current animation(e.g:Settings switch),
+ // so we delay 250ms to enabled overlay after switch animation finish, only delay once.
+ mMainExecutor.executeDelayed(() -> setEnabledGesturalOverlay(enabled, false),
+ OVERLAY_ENABLED_DELAY_MS);
+ return;
+ }
try {
mOverlayManager.setEnabled(ONE_HANDED_MODE_GESTURAL_OVERLAY, enabled, USER_CURRENT);
} catch (RemoteException e) {
@@ -625,6 +678,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
if (enabled == isFeatureEnabled) {
return;
}
+
mLockedDisabled = locked && !enabled;
}
@@ -758,6 +812,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
@Override
+ public void registerEventCallback(OneHandedEventCallback callback) {
+ mMainExecutor.execute(() -> {
+ OneHandedController.this.registerEventCallback(callback);
+ });
+ }
+
+ @Override
public void registerTransitionCallback(OneHandedTransitionCallback callback) {
mMainExecutor.execute(() -> {
OneHandedController.this.registerTransitionCallback(callback);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index b8da37fd0c25..d749c320bf94 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -61,11 +61,12 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
private DisplayLayout mDisplayLayout = new DisplayLayout();
- private float mLastVisualOffset = 0;
private final Rect mLastVisualDisplayBounds = new Rect();
private final Rect mDefaultDisplayBounds = new Rect();
private final OneHandedSettingsUtil mOneHandedSettingsUtil;
+ private boolean mIsReady;
+ private float mLastVisualOffset = 0;
private int mEnterExitAnimationDurationMs;
private ArrayMap<WindowContainerToken, SurfaceControl> mDisplayAreaTokenMap = new ArrayMap();
@@ -157,6 +158,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
}
+ mIsReady = true;
updateDisplayBounds();
return displayAreaInfos;
}
@@ -164,9 +166,14 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
@Override
public void unregisterOrganizer() {
super.unregisterOrganizer();
+ mIsReady = false;
resetWindowsOffset();
}
+ boolean isReady() {
+ return mIsReady;
+ }
+
/**
* Handler for display rotation changes by {@link DisplayLayout}
*
@@ -312,6 +319,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
pw.println(mDisplayAreaTokenMap);
pw.print(innerPrefix + "mDefaultDisplayBounds=");
pw.println(mDefaultDisplayBounds);
+ pw.print(innerPrefix + "mIsReady=");
+ pw.println(mIsReady);
pw.print(innerPrefix + "mLastVisualDisplayBounds=");
pw.println(mLastVisualDisplayBounds);
pw.print(innerPrefix + "mLastVisualOffset=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEventCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEventCallback.java
new file mode 100644
index 000000000000..d07eea271eac
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEventCallback.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.onehanded;
+
+/**
+ * Additional callback interface for OneHanded events.
+ */
+public interface OneHandedEventCallback {
+ /**
+ * Called to notify expand notification shade.
+ */
+ default void notifyExpandNotification() {
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
index 90fc823fb574..da53b359a304 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
@@ -105,6 +105,17 @@ public final class OneHandedSettingsUtil {
}
/**
+ * Sets one handed enable or disable flag from Settings provider.
+ *
+ * @return true if the value was set, false on database errors
+ */
+ public boolean setOneHandedModeEnabled(ContentResolver resolver, int enabled, int userId) {
+ return Settings.Secure.putIntForUser(resolver,
+ Settings.Secure.ONE_HANDED_MODE_ENABLED, enabled, userId);
+ }
+
+
+ /**
* Queries taps app to exit config from Settings provider.
*
* @return enable or disable taps app exit.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index 32553f97c020..f0bd8a2846ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -235,15 +235,20 @@ public class PipResizeGestureHandler {
@VisibleForTesting
void onInputEvent(InputEvent ev) {
+ if (!mEnableDragCornerResize && !mEnablePinchResize) {
+ // No need to handle anything if neither form of resizing is enabled.
+ return;
+ }
+
// Don't allow resize when PiP is stashed.
if (mPipBoundsState.isStashed()) {
return;
}
if (ev instanceof MotionEvent) {
- if (mOngoingPinchToResize) {
+ if (mEnablePinchResize && mOngoingPinchToResize) {
onPinchResize((MotionEvent) ev);
- } else {
+ } else if (mEnableDragCornerResize) {
onDragCornerResize((MotionEvent) ev);
}
}
@@ -318,8 +323,8 @@ public class PipResizeGestureHandler {
case MotionEvent.ACTION_POINTER_DOWN:
if (mEnablePinchResize && ev.getPointerCount() == 2) {
onPinchResize(ev);
- mOngoingPinchToResize = true;
- return true;
+ mOngoingPinchToResize = mAllowGesture;
+ return mAllowGesture;
}
break;
@@ -536,8 +541,9 @@ public class PipResizeGestureHandler {
mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
PipAnimationController.TRANSITION_DIRECTION_USER_RESIZE, callback);
}
+ final float magnetRadiusPercent = (float) mLastResizeBounds.width() / mMinSize.x / 2.f;
mPipDismissTargetHandler
- .setMagneticFieldRadiusPercent((float) mLastResizeBounds.width() / mMinSize.x);
+ .setMagneticFieldRadiusPercent(magnetRadiusPercent);
mPipUiEventLogger.log(
PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 4d33cb0452dc..46db35a6e29f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -35,6 +35,7 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
+import android.os.RemoteCallback;
import android.os.Trace;
import android.os.UserHandle;
import android.util.Slog;
@@ -42,6 +43,7 @@ import android.util.SparseArray;
import android.view.Choreographer;
import android.view.Display;
import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
@@ -121,6 +123,13 @@ public class StartingSurfaceDrawer {
private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
+ /**
+ * Records of {@link SurfaceControlViewHost} where the splash screen icon animation is
+ * rendered and that have not yet been removed by their client.
+ */
+ private final SparseArray<SurfaceControlViewHost> mAnimatedSplashScreenSurfaceHosts =
+ new SparseArray<>(1);
+
/** Obtain proper context for showing splash screen on the provided display. */
private Context getDisplayContext(Context context, int displayId) {
if (displayId == DEFAULT_DISPLAY) {
@@ -386,25 +395,58 @@ public class StartingSurfaceDrawer {
/**
* Called when the Task wants to copy the splash screen.
- * @param taskId
*/
public void copySplashScreenView(int taskId) {
final StartingWindowRecord preView = mStartingWindowRecords.get(taskId);
SplashScreenViewParcelable parcelable;
- if (preView != null && preView.mContentView != null
- && preView.mContentView.isCopyable()) {
- parcelable = new SplashScreenViewParcelable(preView.mContentView);
- preView.mContentView.onCopied();
+ SplashScreenView splashScreenView = preView != null ? preView.mContentView : null;
+ if (splashScreenView != null && splashScreenView.isCopyable()) {
+ parcelable = new SplashScreenViewParcelable(splashScreenView);
+ parcelable.setClientCallback(
+ new RemoteCallback((bundle) -> mSplashScreenExecutor.execute(
+ () -> onAppSplashScreenViewRemoved(taskId, false))));
+ splashScreenView.onCopied();
+ mAnimatedSplashScreenSurfaceHosts.append(taskId, splashScreenView.getSurfaceHost());
} else {
parcelable = null;
}
if (DEBUG_SPLASH_SCREEN) {
Slog.v(TAG, "Copying splash screen window view for task: " + taskId
- + " parcelable? " + parcelable);
+ + " parcelable: " + parcelable);
}
ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
}
+ /**
+ * Called when the {@link SplashScreenView} is removed from the client Activity view's hierarchy
+ * or when the Activity is clean up.
+ *
+ * @param taskId The Task id on which the splash screen was attached
+ */
+ public void onAppSplashScreenViewRemoved(int taskId) {
+ onAppSplashScreenViewRemoved(taskId, true /* fromServer */);
+ }
+
+ /**
+ * @param fromServer If true, this means the removal was notified by the server. This is only
+ * used for debugging purposes.
+ * @see #onAppSplashScreenViewRemoved(int)
+ */
+ private void onAppSplashScreenViewRemoved(int taskId, boolean fromServer) {
+ SurfaceControlViewHost viewHost =
+ mAnimatedSplashScreenSurfaceHosts.get(taskId);
+ if (viewHost == null) {
+ return;
+ }
+ mAnimatedSplashScreenSurfaceHosts.remove(taskId);
+ if (DEBUG_SPLASH_SCREEN) {
+ String reason = fromServer ? "Server cleaned up" : "App removed";
+ Slog.v(TAG, reason + "the splash screen. Releasing SurfaceControlViewHost for task:"
+ + taskId);
+ }
+ viewHost.getView().post(viewHost::release);
+ }
+
protected boolean addWindow(int taskId, IBinder appToken, View view, WindowManager wm,
WindowManager.LayoutParams params) {
boolean shouldSaveView = true;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index cffc789106cb..9c1dde925762 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -150,6 +150,14 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
}
/**
+ * @see StartingSurfaceDrawer#onAppSplashScreenViewRemoved(int)
+ */
+ public void onAppSplashScreenViewRemoved(int taskId) {
+ mSplashScreenExecutor.execute(
+ () -> mStartingSurfaceDrawer.onAppSplashScreenViewRemoved(taskId));
+ }
+
+ /**
* Called when the content of a task is ready to show, starting window can be removed.
*/
public void removeStartingWindow(int taskId, SurfaceControl leash, Rect frame,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index 1852279ee96c..47789b7490ee 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
@@ -74,6 +74,8 @@ public class OneHandedControllerTest extends OneHandedTestCase {
@Mock
OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
@Mock
+ OneHandedEventCallback mMockEventCallback;
+ @Mock
OneHandedTouchHandler mMockTouchHandler;
@Mock
OneHandedTutorialHandler mMockTutorialHandler;
@@ -106,6 +108,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
+ when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true);
when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash);
when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn(
mDefaultEnabled);
@@ -241,7 +244,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
@Test
public void testSettingsObserverUpdateSwipeToNotification() {
- mSpiedOneHandedController.onSwipeToNotificationEnabledSettingChanged();
+ mSpiedOneHandedController.onSwipeToNotificationEnabledChanged();
verify(mSpiedOneHandedController).setSwipeToNotificationEnabled(anyBoolean());
}
@@ -311,6 +314,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout);
testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
mSpiedTransitionState.setState(STATE_NONE);
+ when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true);
when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout);
mSpiedOneHandedController.setOneHandedEnabled(true);
mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */);
@@ -372,8 +376,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
- verify(mSpiedOneHandedController, never()).startOneHanded();
- verify(mSpiedOneHandedController, never()).stopOneHanded();
+ verify(mSpiedTransitionState, never()).setState(STATE_EXITING);
}
@Test
@@ -383,20 +386,20 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
- verify(mSpiedOneHandedController, never()).startOneHanded();
- verify(mSpiedOneHandedController, never()).stopOneHanded();
+ verify(mSpiedTransitionState, never()).setState(STATE_ENTERING);
}
@Test
- public void testOneHandedDisabled_shortcutEnabled_skipActions() {
+ public void testOneHandedDisabled_shortcutTrigger_thenAutoEnabled() {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
- when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
+ when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false);
+ when(mMockSettingsUitl.setOneHandedModeEnabled(any(), anyInt(), anyInt())).thenReturn(
+ false);
mSpiedOneHandedController.onActivatedActionChanged();
- verify(mSpiedOneHandedController, never()).startOneHanded();
- verify(mSpiedOneHandedController, never()).stopOneHanded();
+ verify(mSpiedOneHandedController).notifyUserConfigChanged(anyBoolean());
}
@Test
@@ -408,4 +411,28 @@ public class OneHandedControllerTest extends OneHandedTestCase {
verify(mSpiedTransitionState).addSListeners(mMockTutorialHandler);
}
+
+ @Test
+ public void testNotifyEventCallbackWithMainExecutor() {
+ when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true);
+ when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
+ when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
+ when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
+ mSpiedOneHandedController.registerEventCallback(mMockEventCallback);
+ mSpiedOneHandedController.onActivatedActionChanged();
+
+ verify(mMockShellMainExecutor).execute(any());
+ }
+
+ @Test
+ public void testNotifyShortcutState_whenUpdateOneHandedEnabled() {
+ when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
+ when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
+ when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
+ when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
+ mSpiedOneHandedController.registerEventCallback(mMockEventCallback);
+ mSpiedOneHandedController.setOneHandedEnabled(true);
+
+ verify(mSpiedOneHandedController).notifyShortcutState(anyInt());
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
index a27ed114de70..ef16fd391235 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java
@@ -418,4 +418,18 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
verify(mSpiedDisplayAreaOrganizer, never()).resetWindowsOffset();
}
+
+ @Test
+ public void testDisplayArea_notReadyForTransition() {
+ OneHandedDisplayAreaOrganizer testSpiedDisplayAreaOrganizer = spy(
+ new OneHandedDisplayAreaOrganizer(mContext,
+ mDisplayLayout,
+ mMockSettingsUitl,
+ mMockAnimationController,
+ mTutorialHandler,
+ mMockBackgroundOrganizer,
+ mMockShellMainExecutor));
+
+ assertThat(testSpiedDisplayAreaOrganizer.isReady()).isFalse();
+ }
}
diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp
index ee7b26058952..d86d9ee56f4c 100644
--- a/libs/hwui/jni/Typeface.cpp
+++ b/libs/hwui/jni/Typeface.cpp
@@ -204,10 +204,9 @@ static sk_sp<SkData> makeSkDataCached(const std::string& path, bool hasVerity) {
return entry;
}
-static std::function<std::shared_ptr<minikin::MinikinFont>()> readMinikinFontSkia(
- minikin::BufferReader* reader) {
- const void* buffer = reader->data();
- size_t pos = reader->pos();
+static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader);
+
+static minikin::Font::TypefaceLoader* readMinikinFontSkia(minikin::BufferReader* reader) {
// Advance reader's position.
reader->skipString(); // fontPath
reader->skip<int>(); // fontIndex
@@ -217,60 +216,63 @@ static std::function<std::shared_ptr<minikin::MinikinFont>()> readMinikinFontSki
reader->skip<uint32_t>(); // expectedFontRevision
reader->skipString(); // expectedPostScriptName
}
- return [buffer, pos]() -> std::shared_ptr<minikin::MinikinFont> {
- minikin::BufferReader fontReader(buffer, pos);
- std::string_view fontPath = fontReader.readString();
- std::string path(fontPath.data(), fontPath.size());
- ATRACE_FORMAT("Loading font %s", path.c_str());
- int fontIndex = fontReader.read<int>();
- const minikin::FontVariation* axesPtr;
- uint32_t axesCount;
- std::tie(axesPtr, axesCount) = fontReader.readArray<minikin::FontVariation>();
- bool hasVerity = static_cast<bool>(fontReader.read<int8_t>());
- uint32_t expectedFontRevision;
- std::string_view expectedPostScriptName;
- if (hasVerity) {
- expectedFontRevision = fontReader.read<uint32_t>();
- expectedPostScriptName = fontReader.readString();
- }
- sk_sp<SkData> data = makeSkDataCached(path, hasVerity);
- if (data.get() == nullptr) {
- // This may happen if:
- // 1. When the process failed to open the file (e.g. invalid path or permission).
- // 2. When the process failed to map the file (e.g. hitting max_map_count limit).
- ALOGE("Failed to make SkData from file name: %s", path.c_str());
+ return &loadMinikinFontSkia;
+}
+
+static std::shared_ptr<minikin::MinikinFont> loadMinikinFontSkia(minikin::BufferReader reader) {
+ std::string_view fontPath = reader.readString();
+ std::string path(fontPath.data(), fontPath.size());
+ ATRACE_FORMAT("Loading font %s", path.c_str());
+ int fontIndex = reader.read<int>();
+ const minikin::FontVariation* axesPtr;
+ uint32_t axesCount;
+ std::tie(axesPtr, axesCount) = reader.readArray<minikin::FontVariation>();
+ bool hasVerity = static_cast<bool>(reader.read<int8_t>());
+ uint32_t expectedFontRevision;
+ std::string_view expectedPostScriptName;
+ if (hasVerity) {
+ expectedFontRevision = reader.read<uint32_t>();
+ expectedPostScriptName = reader.readString();
+ }
+ sk_sp<SkData> data = makeSkDataCached(path, hasVerity);
+ if (data.get() == nullptr) {
+ // This may happen if:
+ // 1. When the process failed to open the file (e.g. invalid path or permission).
+ // 2. When the process failed to map the file (e.g. hitting max_map_count limit).
+ ALOGE("Failed to make SkData from file name: %s", path.c_str());
+ return nullptr;
+ }
+ const void* fontPtr = data->data();
+ size_t fontSize = data->size();
+ if (hasVerity) {
+ // Verify font metadata if verity is enabled.
+ minikin::FontFileParser parser(fontPtr, fontSize, fontIndex);
+ std::optional<uint32_t> revision = parser.getFontRevision();
+ if (!revision.has_value() || revision.value() != expectedFontRevision) {
+ LOG_ALWAYS_FATAL("Wrong font revision: %s", path.c_str());
return nullptr;
}
- const void* fontPtr = data->data();
- size_t fontSize = data->size();
- if (hasVerity) {
- // Verify font metadata if verity is enabled.
- minikin::FontFileParser parser(fontPtr, fontSize, fontIndex);
- std::optional<uint32_t> revision = parser.getFontRevision();
- if (!revision.has_value() || revision.value() != expectedFontRevision) {
- LOG_ALWAYS_FATAL("Wrong font revision: %s", path.c_str());
- return nullptr;
- }
- std::optional<std::string> psName = parser.getPostScriptName();
- if (!psName.has_value() || psName.value() != expectedPostScriptName) {
- LOG_ALWAYS_FATAL("Wrong PostScript name: %s", path.c_str());
- return nullptr;
- }
- }
- std::vector<minikin::FontVariation> axes(axesPtr, axesPtr + axesCount);
- std::shared_ptr<minikin::MinikinFont> minikinFont =
- fonts::createMinikinFontSkia(std::move(data), fontPath, fontPtr, fontSize,
- fontIndex, axes);
- if (minikinFont == nullptr) {
- ALOGE("Failed to create MinikinFontSkia: %s", path.c_str());
+ std::optional<std::string> psName = parser.getPostScriptName();
+ if (!psName.has_value() || psName.value() != expectedPostScriptName) {
+ LOG_ALWAYS_FATAL("Wrong PostScript name: %s", path.c_str());
return nullptr;
}
- return minikinFont;
- };
+ }
+ std::vector<minikin::FontVariation> axes(axesPtr, axesPtr + axesCount);
+ std::shared_ptr<minikin::MinikinFont> minikinFont = fonts::createMinikinFontSkia(
+ std::move(data), fontPath, fontPtr, fontSize, fontIndex, axes);
+ if (minikinFont == nullptr) {
+ ALOGE("Failed to create MinikinFontSkia: %s", path.c_str());
+ return nullptr;
+ }
+ return minikinFont;
}
static void writeMinikinFontSkia(minikin::BufferWriter* writer,
const minikin::MinikinFont* typeface) {
+ // When you change the format of font metadata, please update code to parse
+ // typefaceMetadataReader() in
+ // frameworks/base/libs/hwui/jni/fonts/Font.cpp too.
const std::string& path = typeface->GetFontPath();
writer->writeString(path);
writer->write<int>(typeface->GetFontIndex());
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 602c32a966d3..819a34b21a05 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -500,6 +500,28 @@ private:
jobject mObject;
};
+class JWeakGlobalRefHolder {
+public:
+ JWeakGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm) {
+ mWeakRef = getenv(vm)->NewWeakGlobalRef(object);
+ }
+
+ virtual ~JWeakGlobalRefHolder() {
+ if (mWeakRef != nullptr) getenv(mVm)->DeleteWeakGlobalRef(mWeakRef);
+ mWeakRef = nullptr;
+ }
+
+ jobject ref() { return mWeakRef; }
+ JavaVM* vm() { return mVm; }
+
+private:
+ JWeakGlobalRefHolder(const JWeakGlobalRefHolder&) = delete;
+ void operator=(const JWeakGlobalRefHolder&) = delete;
+
+ JavaVM* mVm;
+ jobject mWeakRef;
+};
+
using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>;
struct PictureCaptureState {
@@ -633,15 +655,19 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback(
} else {
JavaVM* vm = nullptr;
LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
- auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(
- vm, env->NewGlobalRef(aSurfaceTransactionCallback));
+ auto globalCallbackRef =
+ std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback);
proxy->setASurfaceTransactionCallback(
[globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) {
JNIEnv* env = getenv(globalCallbackRef->vm());
- env->CallVoidMethod(globalCallbackRef->object(),
- gASurfaceTransactionCallback.onMergeTransaction,
+ jobject localref = env->NewLocalRef(globalCallbackRef->ref());
+ if (CC_UNLIKELY(!localref)) {
+ return;
+ }
+ env->CallVoidMethod(localref, gASurfaceTransactionCallback.onMergeTransaction,
static_cast<jlong>(transObj), static_cast<jlong>(scObj),
static_cast<jlong>(frameNr));
+ env->DeleteLocalRef(localref);
});
}
}
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index bd3b7c93466c..09be630dc741 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -192,7 +192,7 @@ static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong
// Critical Native
static jlong Font_getMinikinFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- return reinterpret_cast<jlong>(font->font->typeface().get());
+ return reinterpret_cast<jlong>(font->font.get());
}
// Critical Native
@@ -224,12 +224,21 @@ static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) {
// Fast Native
static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- const std::string& path = minikinFont->GetFontPath();
- if (path.empty()) {
- return nullptr;
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ if (reader.data() != nullptr) {
+ std::string path = std::string(reader.readString());
+ if (path.empty()) {
+ return nullptr;
+ }
+ return env->NewStringUTF(path.c_str());
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ const std::string& path = minikinFont->GetFontPath();
+ if (path.empty()) {
+ return nullptr;
+ }
+ return env->NewStringUTF(path.c_str());
}
- return env->NewStringUTF(path.c_str());
}
// Fast Native
@@ -257,22 +266,43 @@ static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
// Critical Native
static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- return minikinFont->GetFontIndex();
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ if (reader.data() != nullptr) {
+ reader.skipString(); // fontPath
+ return reader.read<int>();
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ return minikinFont->GetFontIndex();
+ }
}
// Critical Native
static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- return minikinFont->GetAxes().size();
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ if (reader.data() != nullptr) {
+ reader.skipString(); // fontPath
+ reader.skip<int>(); // fontIndex
+ return reader.readArray<minikin::FontVariation>().second;
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ return minikinFont->GetAxes().size();
+ }
}
// Critical Native
static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint index) {
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
- const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
- minikin::FontVariation var = minikinFont->GetAxes().at(index);
+ minikin::BufferReader reader = font->font->typefaceMetadataReader();
+ minikin::FontVariation var;
+ if (reader.data() != nullptr) {
+ reader.skipString(); // fontPath
+ reader.skip<int>(); // fontIndex
+ var = reader.readArray<minikin::FontVariation>().first[index];
+ } else {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
+ var = minikinFont->GetAxes().at(index);
+ }
uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
}
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 46e806081c0c..ded2b06fb3cf 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -210,6 +210,14 @@ void CacheManager::onFrameCompleted() {
}
}
+void CacheManager::performDeferredCleanup(nsecs_t cleanupOlderThanMillis) {
+ if (mGrContext) {
+ mGrContext->performDeferredCleanup(
+ std::chrono::milliseconds(cleanupOlderThanMillis),
+ /* scratchResourcesOnly */true);
+ }
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 713ea990ff23..af82672c6f23 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -23,6 +23,7 @@
#include <SkSurface.h>
#include <utils/String8.h>
#include <vector>
+#include "utils/TimeUtils.h"
namespace android {
@@ -53,6 +54,8 @@ public:
size_t getBackgroundCacheSize() const { return mBackgroundResourceBytes; }
void onFrameCompleted();
+ void performDeferredCleanup(nsecs_t cleanupOlderThanMillis);
+
private:
friend class RenderThread;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a0d93e928876..8bfc2c14ad7c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -461,6 +461,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy
}
void CanvasContext::stopDrawing() {
+ cleanupResources();
mRenderThread.removeFrameCallback(this);
mAnimationContext->pauseAnimators();
mGenerationID++;
@@ -619,10 +620,25 @@ nsecs_t CanvasContext::draw() {
}
}
+ cleanupResources();
mRenderThread.cacheManager().onFrameCompleted();
return mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration);
}
+void CanvasContext::cleanupResources() {
+ auto& tracker = mJankTracker.frames();
+ auto size = tracker.size();
+ auto capacity = tracker.capacity();
+ if (size == capacity) {
+ nsecs_t nowNanos = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t frameCompleteNanos =
+ tracker[0].get(FrameInfoIndex::FrameCompleted);
+ nsecs_t frameDiffNanos = nowNanos - frameCompleteNanos;
+ nsecs_t cleanupMillis = ns2ms(std::max(frameDiffNanos, 10_s));
+ mRenderThread.cacheManager().performDeferredCleanup(cleanupMillis);
+ }
+}
+
void CanvasContext::reportMetricsWithPresentTime() {
if (mFrameMetricsReporter == nullptr) {
return;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6f90e81e51b0..4bdc2514db8c 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -312,6 +312,7 @@ private:
bool mExpectSurfaceStats = false;
std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
+ void cleanupResources();
};
} /* namespace renderthread */
diff --git a/location/java/android/location/LocationManagerInternal.java b/location/java/android/location/LocationManagerInternal.java
index 763835c9cbe2..d59756d02348 100644
--- a/location/java/android/location/LocationManagerInternal.java
+++ b/location/java/android/location/LocationManagerInternal.java
@@ -16,14 +16,10 @@
package android.location;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.location.util.identity.CallerIdentity;
-
-import com.android.internal.annotations.Immutable;
-
-import java.util.Set;
+import android.os.PackageTagsList;
/**
* Location manager local system service interface.
@@ -43,18 +39,14 @@ public abstract class LocationManagerInternal {
}
/**
- * Interface for getting callbacks when a location provider's location tags change.
- *
- * @see LocationTagInfo
+ * Interface for getting callbacks when an app id's location provider package tags change.
*/
- public interface OnProviderLocationTagsChangeListener {
+ public interface LocationPackageTagsListener {
/**
- * Called when the location tags for a provider change.
- *
- * @param providerLocationTagInfo The tag info for a provider.
+ * Called when the package tags for a location provider change for a uid.
*/
- void onLocationTagsChanged(@NonNull LocationTagInfo providerLocationTagInfo);
+ void onLocationPackageTagsChanged(int uid, @NonNull PackageTagsList packageTagsList);
}
/**
@@ -109,58 +101,9 @@ public abstract class LocationManagerInternal {
public abstract @Nullable LocationTime getGnssTimeMillis();
/**
- * Sets a listener for changes in the location providers' tags. Passing
+ * Sets a listener for changes in an app id's location provider package tags. Passing
* {@code null} clears the current listener.
- *
- * @param listener The listener.
*/
- public abstract void setOnProviderLocationTagsChangeListener(
- @Nullable OnProviderLocationTagsChangeListener listener);
-
- /**
- * This class represents the location permission tags used by the location provider
- * packages in a given UID. These tags are strictly used for accessing state guarded
- * by the location permission(s) by a location provider which are required for the
- * provider to fulfill its function as being a location provider.
- */
- @Immutable
- public static class LocationTagInfo {
- private final int mUid;
-
- @NonNull
- private final String mPackageName;
-
- @Nullable
- private final Set<String> mLocationTags;
-
- public LocationTagInfo(int uid, @NonNull String packageName,
- @Nullable Set<String> locationTags) {
- mUid = uid;
- mPackageName = packageName;
- mLocationTags = locationTags;
- }
-
- /**
- * @return The UID for which tags are related.
- */
- public int getUid() {
- return mUid;
- }
-
- /**
- * @return The package for which tags are related.
- */
- @NonNull
- public String getPackageName() {
- return mPackageName;
- }
-
- /**
- * @return The tags for the package used for location related accesses.
- */
- @Nullable
- public Set<String> getTags() {
- return mLocationTags;
- }
- }
+ public abstract void setLocationPackageTagsListener(
+ @Nullable LocationPackageTagsListener listener);
}
diff --git a/location/java/android/location/provider/LocationProviderBase.java b/location/java/android/location/provider/LocationProviderBase.java
index eada22cd94dc..88a24794411c 100644
--- a/location/java/android/location/provider/LocationProviderBase.java
+++ b/location/java/android/location/provider/LocationProviderBase.java
@@ -62,6 +62,10 @@ import java.util.Objects;
* <p>The service should have an intent filter in place for the location provider it wishes to
* implements. Defaults for some providers are specified as constants in this class.
*
+ * <p>Location providers are identified by their UID / package name / attribution tag. Based on this
+ * identity, location providers may be given some special privileges (such as making special
+ * requests to other location providers).
+ *
* @hide
*/
@SystemApi
@@ -95,14 +99,14 @@ public abstract class LocationProviderBase {
public static final String ACTION_FUSED_PROVIDER =
"com.android.location.service.FusedLocationProvider";
- private final String mTag;
- private final @Nullable String mAttributionTag;
- private final IBinder mBinder;
+ final String mTag;
+ final @Nullable String mAttributionTag;
+ final IBinder mBinder;
// write locked on mBinder, read lock is optional depending on atomicity requirements
- private @Nullable volatile ILocationProviderManager mManager;
- private volatile ProviderProperties mProperties;
- private volatile boolean mAllowed;
+ volatile @Nullable ILocationProviderManager mManager;
+ volatile ProviderProperties mProperties;
+ volatile boolean mAllowed;
public LocationProviderBase(@NonNull Context context, @NonNull String tag,
@NonNull ProviderProperties properties) {
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 1a2a1aee0eb3..345d9b27c8a8 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -696,13 +696,17 @@ public class MediaRouter {
@Override
public void onGlobalA2dpChanged(boolean a2dpOn) {
mHandler.post(() -> {
- if (mSelectedRoute == null) {
+ if (mSelectedRoute == null || mBluetoothA2dpRoute == null) {
return;
}
if (mSelectedRoute.isDefault() && a2dpOn) {
- setSelectedRoute(mBluetoothA2dpRoute, /*explicit=*/false);
+ setSelectedRoute(mBluetoothA2dpRoute, /*explicit=*/ false);
+ dispatchRouteUnselected(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
+ dispatchRouteSelected(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
} else if (mSelectedRoute.isBluetooth() && !a2dpOn) {
- setSelectedRoute(mDefaultAudioVideo, /*explicit=*/false);
+ setSelectedRoute(mDefaultAudioVideo, /*explicit=*/ false);
+ dispatchRouteUnselected(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
+ dispatchRouteSelected(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
}
});
}
@@ -1363,6 +1367,9 @@ public class MediaRouter {
}
static void dispatchRouteSelected(int type, RouteInfo info) {
+ if (DEBUG) {
+ Log.d(TAG, "Dispatching route selected: " + info);
+ }
for (CallbackInfo cbi : sStatic.mCallbacks) {
if (cbi.filterRouteEvent(info)) {
cbi.cb.onRouteSelected(cbi.router, type, info);
@@ -1371,6 +1378,9 @@ public class MediaRouter {
}
static void dispatchRouteUnselected(int type, RouteInfo info) {
+ if (DEBUG) {
+ Log.d(TAG, "Dispatching route unselected: " + info);
+ }
for (CallbackInfo cbi : sStatic.mCallbacks) {
if (cbi.filterRouteEvent(info)) {
cbi.cb.onRouteUnselected(cbi.router, type, info);
diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk
index bb6dfa3a4ede..18915039b6a1 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index 2835d57474d9..eb2202586753 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index bb6dfa3a4ede..18915039b6a1 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index 2e1a78989b70..b3f923c4176f 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml b/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml
index 120b0859a70a..73163fca5362 100644
--- a/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml
@@ -18,6 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.settingslib.widget">
- <uses-sdk android:minSdkVersion="21" />
+ <uses-sdk android:minSdkVersion="28" />
</manifest>
diff --git a/packages/SettingsLib/IllustrationPreference/res/drawable/ic_gesture_play_button.xml b/packages/SettingsLib/IllustrationPreference/res/drawable/ic_gesture_play_button.xml
deleted file mode 100644
index 55b3115a58a4..000000000000
--- a/packages/SettingsLib/IllustrationPreference/res/drawable/ic_gesture_play_button.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path android:fillColor="#FFFFFF" android:pathData="M24,24m-19,0a19,19 0,1 1,38 0a19,19 0,1 1,-38 0"/>
- <path android:fillColor="#1A73E8" android:pathData="M20,33l12,-9l-12,-9z"/>
- <path android:fillColor="#1A73E8" android:pathData="M24,4C12.96,4 4,12.96 4,24s8.96,20 20,20s20,-8.96 20,-20S35.04,4 24,4zM24,40c-8.82,0 -16,-7.18 -16,-16S15.18,8 24,8s16,7.18 16,16S32.82,40 24,40z"/>
-</vector>
diff --git a/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml b/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml
index 0929cc3d84a7..efcd41c2778b 100644
--- a/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml
+++ b/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml
@@ -20,44 +20,38 @@
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?android:attr/colorBackground"
+ android:importantForAccessibility="noHideDescendants"
android:gravity="center"
android:orientation="horizontal">
- <LinearLayout
- android:layout_width="match_parent"
+ <FrameLayout
+ android:id="@+id/illustration_frame"
+ android:layout_width="wrap_content"
android:layout_height="@dimen/settingslib_illustration_height"
android:layout_gravity="center"
android:gravity="center_vertical"
android:padding="@dimen/settingslib_illustration_padding"
android:orientation="vertical">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/protection_background"/>
+
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_view"
- android:adjustViewBounds="true"
- android:maxWidth="@dimen/settingslib_illustration_width"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_gravity="center"
- android:clipToOutline="true"
- android:background="@drawable/protection_background"
- android:importantForAccessibility="no"/>
- </LinearLayout>
+ android:layout_gravity="center" />
- <FrameLayout
- android:id="@+id/middleground_layout"
- android:layout_width="@dimen/settingslib_illustration_width"
- android:layout_height="@dimen/settingslib_illustration_height"
- android:padding="@dimen/settingslib_illustration_padding"
- android:background="@android:color/transparent"
- android:layout_gravity="center"
- android:visibility="gone"/>
-
- <ImageView
- android:id="@+id/video_play_button"
- android:layout_width="36dp"
- android:layout_height="36dp"
- android:layout_gravity="center"
- android:visibility="gone"
- android:src="@drawable/ic_gesture_play_button"/>
+ <FrameLayout
+ android:id="@+id/middleground_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/transparent"
+ android:layout_gravity="center"
+ android:visibility="gone"/>
+ </FrameLayout>
</FrameLayout>
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/ColorUtils.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/ColorUtils.java
index cd2ddebe6367..07102d55ef7e 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/ColorUtils.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/ColorUtils.java
@@ -39,13 +39,6 @@ import java.util.HashMap;
public class ColorUtils {
private static HashMap<String, Integer> sSysColors;
- static {
- sSysColors = new HashMap<>();
- sSysColors.put(".colorAccent", android.R.attr.colorAccent);
- sSysColors.put(".colorPrimary", android.R.attr.colorPrimary);
- sSysColors.put(".colorPrimaryDark", android.R.attr.colorPrimaryDark);
- sSysColors.put(".colorSecondary", android.R.attr.colorSecondary);
- }
private static HashMap<String, Pair<Integer, Integer>> sFixedColors;
static {
@@ -110,19 +103,6 @@ public class ColorUtils {
* Apply the color of tags to the animation.
*/
public static void applyDynamicColors(Context context, LottieAnimationView animationView) {
- for (String key : sSysColors.keySet()) {
- final int color = sSysColors.get(key);
- animationView.addValueCallback(
- new KeyPath("**", key, "**"),
- LottieProperty.COLOR_FILTER,
- new SimpleLottieValueCallback<ColorFilter>() {
- @Override
- public ColorFilter getValue(LottieFrameInfo<ColorFilter> frameInfo) {
- return new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
- }
- }
- );
- }
for (String key : sFixedColors.keySet()) {
final Pair<Integer, Integer> fixedColorPair = sFixedColors.get(key);
final int color = isDarkMode(context) ? fixedColorPair.second : fixedColorPair.first;
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index 7b2a0af269a6..e91dd94c715d 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -18,17 +18,15 @@ package com.android.settingslib.widget;
import android.content.Context;
import android.content.res.TypedArray;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
+import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceViewHolder;
import com.airbnb.lottie.LottieAnimationView;
@@ -36,14 +34,14 @@ import com.airbnb.lottie.LottieAnimationView;
/**
* IllustrationPreference is a preference that can play lottie format animation
*/
-public class IllustrationPreference extends Preference implements OnPreferenceClickListener {
+public class IllustrationPreference extends Preference {
- static final String TAG = "IllustrationPreference";
+ private static final String TAG = "IllustrationPreference";
+
+ private static final boolean IS_ENABLED_LOTTIE_ADAPTIVE_COLOR = false;
private int mAnimationId;
- private boolean mIsAnimating;
private boolean mIsAutoScale;
- private ImageView mPlayButton;
private LottieAnimationView mIllustrationView;
private View mMiddleGroundView;
private FrameLayout mMiddleGroundLayout;
@@ -71,42 +69,32 @@ public class IllustrationPreference extends Preference implements OnPreferenceCl
Log.w(TAG, "Invalid illustration resource id.");
return;
}
+
+ // To solve the problem of non-compliant illustrations, we set the frame height
+ // to 300dp and set the length of the short side of the screen to
+ // the width of the frame.
+ final int screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
+ final int screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
+ final FrameLayout illustrationFrame = (FrameLayout) holder.findViewById(
+ R.id.illustration_frame);
+ final LayoutParams lp = (LayoutParams) illustrationFrame.getLayoutParams();
+ lp.width = screenWidth < screenHeight ? screenWidth : screenHeight;
+ illustrationFrame.setLayoutParams(lp);
+
mMiddleGroundLayout = (FrameLayout) holder.findViewById(R.id.middleground_layout);
- mPlayButton = (ImageView) holder.findViewById(R.id.video_play_button);
mIllustrationView = (LottieAnimationView) holder.findViewById(R.id.lottie_view);
mIllustrationView.setAnimation(mAnimationId);
mIllustrationView.loop(true);
- ColorUtils.applyDynamicColors(getContext(), mIllustrationView);
mIllustrationView.playAnimation();
- updateAnimationStatus(mIsAnimating);
if (mIsAutoScale) {
enableAnimationAutoScale(mIsAutoScale);
}
if (mMiddleGroundView != null) {
enableMiddleGroundView();
}
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- mIsAnimating = !isAnimating();
- updateAnimationStatus(mIsAnimating);
- return true;
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- Parcelable superState = super.onSaveInstanceState();
- SavedState ss = new SavedState(superState);
- ss.mIsAnimating = mIsAnimating;
- return ss;
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- SavedState ss = (SavedState) state;
- super.onRestoreInstanceState(ss.getSuperState());
- mIsAnimating = ss.mIsAnimating;
+ if (IS_ENABLED_LOTTIE_ADAPTIVE_COLOR) {
+ ColorUtils.applyDynamicColors(getContext(), mIllustrationView);
+ }
}
@VisibleForTesting
@@ -149,6 +137,13 @@ public class IllustrationPreference extends Preference implements OnPreferenceCl
mIsAutoScale ? ImageView.ScaleType.CENTER_CROP : ImageView.ScaleType.CENTER_INSIDE);
}
+ /**
+ * Set the lottie illustration resource id.
+ */
+ public void setLottieAnimationResId(int resId) {
+ mAnimationId = resId;
+ }
+
private void enableMiddleGroundView() {
mMiddleGroundLayout.removeAllViews();
mMiddleGroundLayout.addView(mMiddleGroundView);
@@ -158,7 +153,6 @@ public class IllustrationPreference extends Preference implements OnPreferenceCl
private void init(Context context, AttributeSet attrs) {
setLayoutResource(R.layout.illustration_preference);
- mIsAnimating = true;
mIsAutoScale = false;
if (attrs != null) {
final TypedArray a = context.obtainStyledAttributes(attrs,
@@ -166,56 +160,5 @@ public class IllustrationPreference extends Preference implements OnPreferenceCl
mAnimationId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0);
a.recycle();
}
- setOnPreferenceClickListener(this);
- }
-
- private void updateAnimationStatus(boolean playAnimation) {
- if (playAnimation) {
- mIllustrationView.resumeAnimation();
- mPlayButton.setVisibility(View.INVISIBLE);
- } else {
- mIllustrationView.pauseAnimation();
- mPlayButton.setVisibility(View.VISIBLE);
- }
- }
-
- static class SavedState extends BaseSavedState {
- boolean mIsAnimating;
-
- SavedState(Parcelable superState) {
- super(superState);
- }
-
- /**
- * Constructor called from {@link #CREATOR}
- */
- private SavedState(Parcel in) {
- super(in);
- mIsAnimating = (Boolean) in.readValue(null);
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeValue(mIsAnimating);
- }
-
- @Override
- public String toString() {
- return "IllustrationPreference.SavedState{"
- + Integer.toHexString(System.identityHashCode(this))
- + " mIsAnimating=" + mIsAnimating + "}";
- }
-
- public static final Parcelable.Creator<SavedState> CREATOR =
- new Parcelable.Creator<SavedState>() {
- public SavedState createFromParcel(Parcel in) {
- return new SavedState(in);
- }
-
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
}
}
diff --git a/packages/SettingsLib/RadioButtonPreference/res/layout/preference_radio.xml b/packages/SettingsLib/RadioButtonPreference/res/layout/preference_radio.xml
index b299061ce591..906ff2cc09d5 100644
--- a/packages/SettingsLib/RadioButtonPreference/res/layout/preference_radio.xml
+++ b/packages/SettingsLib/RadioButtonPreference/res/layout/preference_radio.xml
@@ -104,7 +104,7 @@
android:gravity="center_vertical">
<View
android:layout_width=".75dp"
- android:layout_height="match_parent"
+ android:layout_height="32dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:background="?android:attr/dividerVertical" />
diff --git a/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml b/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml
index 92c45ba7e187..323fa67ce1f3 100644
--- a/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Параметрлерді іздеу"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Параметр іздеу"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml
index 100acd2e917a..f13f4cde496c 100644
--- a/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"खोजसम्बन्धी सेटिङहरू"</string>
+ <string name="search_menu" msgid="1914043873178389845">"सेटिङमा खोज्नुहोस्"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml
index 5683b6ae85d0..0fa4bd3351e2 100644
--- a/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Pesquisar em Configurações"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Pesquisar nas Configurações"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml
index 5683b6ae85d0..0fa4bd3351e2 100644
--- a/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Pesquisar em Configurações"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Pesquisar nas Configurações"</string>
</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml
index b5cf36881643..6b18f2879659 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/themes.xml
@@ -20,7 +20,9 @@
<style name="Theme.SettingsBase" parent="@android:style/Theme.DeviceDefault.Settings" >
<item name="android:textAppearanceListItem">@style/TextAppearance.PreferenceTitle.SettingsLib</item>
<item name="android:listPreferredItemPaddingStart">24dp</item>
+ <item name="android:listPreferredItemPaddingLeft">24dp</item>
<item name="android:listPreferredItemPaddingEnd">16dp</item>
+ <item name="android:listPreferredItemPaddingRight">16dp</item>
<item name="preferenceTheme">@style/PreferenceTheme.SettingsLib</item>
<item name="android:switchStyle">@style/Switch.SettingsLib</item>
<item name="android:progressBarStyleHorizontal">@style/HorizontalProgressBar.SettingsLib</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 6b16a294b8bc..366cb0677e46 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Wys snitgrense, kantlyne, ens."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Dwing RTL-uitlegrigting"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Dwing skermuitlegrigting na RTL vir alle locales"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Laat venstervlakwasighede toe"</string>
<string name="force_msaa" msgid="4081288296137775550">"Dwing 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktiveer 4x MSAA in OpenGL ES 2.0-programme"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Ontfout nie-reghoekige knipbedrywighede"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Wekkers en onthounotas"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Laat toe dat wekkers en onthounotas gestel word"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wekkers en onthounotas"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Laat hierdie program toe om wekkers te stel en ander handelinge te skeduleer. Hierdie program kan gebruik word wanneer jy nie jou foon gebruik nie, en kan dalk meer batterykrag gebruik. As hierdie toestemming af is, sal hierdie program dalk nie normaal funksioneer en sy wekkers nie werk soos geskeduleer nie."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Laat hierdie program toe om wekkers te stel en ander handelinge te skeduleer. Hierdie program kan gebruik word wanneer jy nie jou tablet gebruik nie, en kan dalk meer batterykrag gebruik. As hierdie toestemming af is, sal hierdie program dalk nie normaal funksioneer en sy wekkers nie werk soos geskeduleer nie."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Laat hierdie program toe om wekkers te stel en ander handelinge te skeduleer. Hierdie program kan gebruik word wanneer jy nie jou toestel gebruik nie, en kan dalk meer batterykrag gebruik. As hierdie toestemming af is, sal hierdie program dalk nie normaal funksioneer en sy wekkers nie werk soos geskeduleer nie."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Laat hierdie program toe om wekkers te stel en tydsensitiewe handelinge te skeduleer. Dit laat die program op die agtergrond werk, wat meer batterykrag kan gebruik.\n\nAs hierdie toestemming af is, sal bestaande wekkers en tydgegronde geleenthede wat deur hierdie program geskeduleer is, nie werk nie."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"skedule, wekker, onthounota, horlosie"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Skakel aan"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Skakel Moenie steur nie aan"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 9943bbb235eb..8a5da977717d 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"የቅንጥብ ገደቦች፣ ጠርዞች፣ ወዘተ አሳይ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"የቀኝ-ወደ-ግራ አቀማመጥ አቅጣጫ አስገድድ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ለሁሉም አካባቢዎች የማያ ገጽ አቀማመጥ ከቀኝ-ወደ-ግራ እንዲሆን አስገድድ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"የመስኮት ደረጃ ብዥታዎችን ፍቀድ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA አስገድድ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA በ OpenGL ES 2.0 መተግበሪያዎች ውስጥ ያንቁ"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"አራት ማእዘን ያልሆኑ የቅንጥብ ክዋኔዎችን ስህተት አርም"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ማንቂያዎች እና አስታዋሾች"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ማንቂያዎች እና አስታዋሾች እንዲዋቀሩ ይፍቀዱ"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ማንቂያዎች እና አስታዋሾች"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና ለሌሎች እርምጃዎች የጊዜ መርሐግብር እንዲያዘጋጅ ይፍቀዱለት። ይህ መተግበሪያ መሣሪያዎን በማይጠቀሙበት ጊዜ ጥቅም ላይ ሊውል ይችላል፤ ይኽም ተጨማሪ ባትሪ ሊጠቀም ይችላል። ይህ ፈቃድ ከጠፋ ይህ መተግበሪያ መደበኛ ሥራውን ላይሰራ ይችላል፣ እንዲሁም ማንቂያዎቹ በጊዜ መርሐግብራቸው መሰረት አይሰሩም።"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና ለሌሎች እርምጃዎች የጊዜ መርሐግብር እንዲያዘጋጅ ይፍቀዱለት። ይህ መተግበሪያ መሣሪያዎን በማይጠቀሙበት ጊዜ ጥቅም ላይ ሊውል ይችላል፤ ይኽም ተጨማሪ ባትሪ ሊጠቀም ይችላል። ይህ ፈቃድ ከጠፋ ይህ መተግበሪያ መደበኛ ሥራውን ላይሰራ ይችላል፣ እንዲሁም ማንቂያዎቹ በጊዜ መርሐግብራቸው መሰረት አይሰሩም።"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና ለሌሎች እርምጃዎች የጊዜ መርሐግብር እንዲያዘጋጅ ይፍቀዱለት። ይህ መተግበሪያ መሣሪያዎን በማይጠቀሙበት ጊዜ ጥቅም ላይ ሊውል ይችላል፤ ይኽም ተጨማሪ ባትሪ ሊጠቀም ይችላል። ይህ ፈቃድ ከጠፋ ይህ መተግበሪያ መደበኛ ሥራውን ላይሰራ ይችላል፣ እንዲሁም ማንቂያዎቹ በጊዜ መርሐግብራቸው መሰረት አይሰሩም።"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና የጊዜ ትብነት ያላቸው እርምጃዎችን መርሐግብር እንዲያስይዝ ይፍቀዱለት። ይህ መተግበሪያው ከበስተጀርባ ማሄድ እንዲችል ያስችለዋል፣ ይህም የበለጠ ባትሪ ሊጠቀም ይችላል።\n\nይህ ፈቃድ ከጠፋ በዚህ መተግበሪያ መርሐግብር የተያዘላቸው ነባር ማንቂያዎች እና ጊዜ-ተኮር ክስተቶች አይሰሩም።"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"የጊዜ መርሐግብር፣ ማንቂያ፣ አስታዋሽ ሰዓት"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"አብራ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"አትረብሽን አብራ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 8f146e04a0a7..0eef43b18a9a 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"عرض حدود وهوامش المقطع وما إلى ذلك"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"فرض اتجاه التنسيق ليكون من اليمين إلى اليسار"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"فرض اتجاه تنسيق الشاشة ليكون من اليمين إلى اليسار لجميع اللغات"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"السماح بعمليات التعتيم على مستوى النافذة"</string>
<string name="force_msaa" msgid="4081288296137775550">"‏فرض 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"‏تفعيل 4x MSAA في تطبيقات OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"تصحيح أخطاء عمليات القصاصات غير المستطيلة"</string>
@@ -512,9 +511,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"المنبّهات والتذكيرات"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"السماح بضبط المنبّهات والتذكيرات"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"المنبّهات والتذكيرات"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"يمكنك السماح لهذا التطبيق بضبط المنبّهات وجدولة الإجراءات الأخرى. قد يتم استخدام هذا التطبيق عند عدم استخدامك للهاتف، مما قد يستهلك المزيد من شحن البطارية. إذا كان هذا الإذن غير مفعّل، قد لا يعمل هذا التطبيق بشكل طبيعي ولن تعمل المنبّهات فيه كما هو مقرر."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"يمكنك السماح لهذا التطبيق بضبط المنبّهات وجدولة الإجراءات الأخرى. قد يتم استخدام هذا التطبيق عند عدم استخدامك للجهاز اللوحي، مما قد يستهلك المزيد من شحن البطارية. إذا كان هذا الإذن غير مفعّل، قد لا يعمل هذا التطبيق بشكل طبيعي ولن تعمل المنبّهات فيه كما هو مقرر."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"يمكنك السماح لهذا التطبيق بضبط المنبّهات وجدولة الإجراءات الأخرى. قد يتم استخدام هذا التطبيق عند عدم استخدامك للجهاز، مما قد يستهلك المزيد من شحن البطارية. إذا كان هذا الإذن غير مفعّل، قد لا يعمل هذا التطبيق بشكل طبيعي ولن تعمل المنبّهات فيه كما هو مقرر."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"جدول زمني، جدولة، منبّه، تذكير، ساعة"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"تفعيل"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"تفعيل ميزة \"عدم الإزعاج\""</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index de942a33f6bf..b8796fe107e7 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ক্লিপ বাউণ্ড, মাৰ্জিন আদিসমূহ দেখুৱাওক"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"আৰটিএল চানেকিৰ দিশ বলেৰে সলনি কৰক"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"সকলো ভাষাৰ বাবে স্ক্ৰীণৰ চানেকিৰ দিশ RTLলৈ বলেৰে সলনি কৰক"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ৱিণ্ড’ স্তৰত অস্পষ্ট কৰাৰ অনুমতি দিয়ক"</string>
<string name="force_msaa" msgid="4081288296137775550">"বল ৪গুণ MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 এপত ৪গুণ MSAA সক্ষম কৰক"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"আয়তাকৃতিৰ নোহোৱা ক্লিপ প্ৰক্ৰিয়াসমূহ ডিবাগ কৰক"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"এলাৰ্ম আৰু ৰিমাইণ্ডাৰ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"এলাৰ্ম আৰু ৰিমাইণ্ডাৰ ছেট কৰাৰ অনুমতি দিয়ক"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"এলাৰ্ম আৰু ৰিমাইণ্ডাৰ"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"এই এপ্‌টোক এলাৰ্ম ছেট কৰিবলৈ আৰু অন্য কাৰ্যৰ সময়সূচী নিৰ্ধাৰণ কৰিবলৈ দিয়ক। এই এপ্‌টো আপুনি নিজৰ ফ’নটো ব্যৱহাৰ কৰি নথকাৰ সময়ত ব্যৱহাৰ কৰা হ’ব পাৰে, যি অধিক বেটাৰী খৰচ কৰিব পাৰে। যদি এই অনুমতিটো অফ কৰি ৰখা হয়, এই এপ্‌টোৱে স্বাভাৱিকভাৱে কাম নকৰিব পাৰে আৰু ইয়াৰ এলাৰ্মসমূহে নিৰ্ধাৰিত সময়সূচী অনুযায়ী কাম নকৰিব।"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"এই এপ্‌টোক এলাৰ্ম ছেট কৰিবলৈ আৰু অন্য কাৰ্যৰ সময়সূচী নিৰ্ধাৰণ কৰিবলৈ দিয়ক। এই এপ্‌টো আপুনি নিজৰ টেবলেটটো ব্যৱহাৰ কৰি নথকাৰ সময়ত ব্যৱহাৰ কৰা হ’ব পাৰে, যি অধিক বেটাৰী খৰচ কৰিব পাৰে। যদি এই অনুমতিটো অফ কৰি ৰখা হয়, এই এপ্‌টোৱে স্বাভাৱিকভাৱে কাম নকৰিব পাৰে আৰু ইয়াৰ এলাৰ্মসমূহে নিৰ্ধাৰিত সময়সূচী অনুযায়ী কাম নকৰিব।"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"এই এপ্‌টোক এলাৰ্ম ছেট কৰিবলৈ আৰু অন্য কাৰ্যৰ সময়সূচী নিৰ্ধাৰণ কৰিবলৈ দিয়ক। এই এপ্‌টো আপুনি নিজৰ ডিভাইচটো ব্যৱহাৰ কৰি নথকাৰ সময়ত ব্যৱহাৰ কৰা হ’ব পাৰে, যি অধিক বেটাৰী খৰচ কৰিব পাৰে। যদি এই অনুমতিটো অফ কৰি ৰখা হয়, এই এপ্‌টোৱে স্বাভাৱিকভাৱে কাম নকৰিব পাৰে আৰু ইয়াৰ এলাৰ্মসমূহে নিৰ্ধাৰিত সময়সূচী অনুযায়ী কাম নকৰিব।"</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"সময়সূচী, এলাৰ্ম, ৰিমাইণ্ডাৰ, ঘড়ী"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"অন কৰক"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"অসুবিধা নিদিব অন কৰক"</string>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index 6eeef0a581e5..4224e5a93d39 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -54,9 +54,9 @@
<item msgid="9048424957228926377">"Həmişə yoxlayın"</item>
</string-array>
<string-array name="hdcp_checking_summaries">
- <item msgid="4045840870658484038">"Heç vaxt HDCP yoxlama istifadə etməyin"</item>
- <item msgid="8254225038262324761">"Yalnız DRM məzmun oxumaq üçün HDCP istifadə edin"</item>
- <item msgid="6421717003037072581">"Həmişə HDCP yoxlama istifadə edin"</item>
+ <item msgid="4045840870658484038">"HDCP yoxlanılmasın"</item>
+ <item msgid="8254225038262324761">"Yalnız DRM kontenti oxumaq üçün HDCP istifadə edilsin"</item>
+ <item msgid="6421717003037072581">"HDCP yoxlanılsın"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
<item msgid="695678520785580527">"Deaktivdir"</item>
@@ -171,11 +171,11 @@
</string-array>
<string-array name="select_logd_size_summaries">
<item msgid="409235464399258501">"Deaktiv"</item>
- <item msgid="4195153527464162486">"hər jurnal buferinə 64K"</item>
- <item msgid="7464037639415220106">"hər jurnal buferinə 256K"</item>
- <item msgid="8539423820514360724">"hər jurnal buferinə 1M"</item>
- <item msgid="1984761927103140651">"hər jurnal buferinə 4M"</item>
- <item msgid="2983219471251787208">"hər jurnal buferinə 8M"</item>
+ <item msgid="4195153527464162486">"Bufer. Maks: 64K"</item>
+ <item msgid="7464037639415220106">"Bufer. Maks: 256K"</item>
+ <item msgid="8539423820514360724">"Bufer. Maks: 1M"</item>
+ <item msgid="1984761927103140651">"Bufer. Maks: 4M"</item>
+ <item msgid="2983219471251787208">"Bufer. Maks: 8M"</item>
</string-array>
<string-array name="select_logpersist_titles">
<item msgid="704720725704372366">"Deaktiv"</item>
@@ -185,9 +185,9 @@
</string-array>
<string-array name="select_logpersist_summaries">
<item msgid="97587758561106269">"Qeyri-aktiv"</item>
- <item msgid="7126170197336963369">"Bütün loq buferləri"</item>
- <item msgid="7167543126036181392">"Radio loq buferlərindən başqa hamısı"</item>
- <item msgid="5135340178556563979">"yalnız kernel loq bufferi"</item>
+ <item msgid="7126170197336963369">"Bütün jurnal buferləri"</item>
+ <item msgid="7167543126036181392">"Sistem jurnalı buferindən başqa hamısı"</item>
+ <item msgid="5135340178556563979">"yalnız nüvə jurnalı buferi"</item>
</string-array>
<string-array name="window_animation_scale_entries">
<item msgid="2675263395797191850">"Animasiya deaktiv"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index aaa8753b6fe0..a5a3321d821b 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -68,7 +68,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ayrılır..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Qoşulur..."</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Qoşuludur<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"Cütləşdirmə"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"Birləşdirilir..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Qoşuludur (telefon yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Qoşuludur (media yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Qoşuludur (mesaj girişi yoxdur)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -94,7 +94,7 @@
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-karta giriş"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eşitmə Aparatı"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eşitmə cihazları"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Eşitmə Aparatlarına qoşuldu"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Media audioya birləşdirilib"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Telefon audiosuna qoşulu"</string>
@@ -120,7 +120,7 @@
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ilə birləşdirmək alınmadı."</string>
<string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Yanlış PIN və ya parola görə <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulmaq olmur."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ilə ünsiyyət qurula bilmir."</string>
- <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Cütləşdirmə <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tərəfindən rədd edildi."</string>
+ <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> birləşmir."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Kompüter"</string>
<string name="bluetooth_talkback_headset" msgid="3406852564400882682">"Qulaqlıq"</string>
<string name="bluetooth_talkback_phone" msgid="868393783858123880">"Telefon"</string>
@@ -156,18 +156,18 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"Bəzi susmaya görələr təyin edilib"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"Defolt ayarlanmayıb"</string>
<string name="tts_settings" msgid="8130616705989351312">"Mətndən-danışığa parametrləri"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"Mətndən-nitqə daxiletmə"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"Mətnin səsləndirilməsi"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Nitq diapazonu"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"Mətnin səsləndirilmə sürəti"</string>
- <string name="tts_default_pitch_title" msgid="6988592215554485479">"Pitç"</string>
+ <string name="tts_default_pitch_title" msgid="6988592215554485479">"Ton"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"Sintez olunmuş nitqin tonuna təsir edir"</string>
<string name="tts_default_lang_title" msgid="4698933575028098940">"Dil"</string>
- <string name="tts_lang_use_system" msgid="6312945299804012406">"Sistem dili işlədin"</string>
+ <string name="tts_lang_use_system" msgid="6312945299804012406">"Sistem dili"</string>
<string name="tts_lang_not_selected" msgid="7927823081096056147">"Dil seçilməyib"</string>
<string name="tts_default_lang_summary" msgid="9042620014800063470">"Danışılan oxunulan mətnə dil üçün spesifik səs ayarlayır"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"Nümunə dinləyin"</string>
<string name="tts_play_example_summary" msgid="634044730710636383">"Nitq sintezindən nümunə göstərin"</string>
- <string name="tts_install_data_title" msgid="1829942496472751703">"Səs datasını quraşdırın"</string>
+ <string name="tts_install_data_title" msgid="1829942496472751703">"Səs datasının quraşdırılması"</string>
<string name="tts_install_data_summary" msgid="3608874324992243851">"Nitq sintezi üçün səs datası quraşdırın"</string>
<string name="tts_engine_security_warning" msgid="3372432853837988146">"Bu nitq sitnez mühərriki danışılan bütün mətni, həmçinin parollarınızı və kredir kart nömrələrinizi toplaya bilər. <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> mühərrikindən gəlir. Nitq sintez mühərriki istifadə olunsun?"</string>
<string name="tts_engine_network_required" msgid="8722087649733906851">"Bu dil mətnin nitqə çıxışı üçün şəbəkə bağlantısı tələb edir."</string>
@@ -179,7 +179,7 @@
<string name="tts_status_checking" msgid="8026559918948285013">"Yoxlanılır..."</string>
<string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> üçün ayarlar"</string>
<string name="tts_engine_settings_button" msgid="477155276199968948">"Mühərrik parametrlərini başladın"</string>
- <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Tərcih olunmuş mühərrik"</string>
+ <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Defolt nitq sintezatoru"</string>
<string name="tts_general_section_title" msgid="8919671529502364567">"Ümumi"</string>
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Nitq tembrini sıfırlayın"</string>
<string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Mətnin defolt səsləndirilmə tembrini sıfırlayın."</string>
@@ -205,18 +205,18 @@
<string name="tethering_settings_not_available" msgid="266821736434699780">"Modem ayarları bu istifadəçiyə qapalıdır"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"Giriş Nöqtəsi Ad Ayarları bu istifadəçi üçün əlçatmazdır"</string>
<string name="enable_adb" msgid="8072776357237289039">"USB debaq prosesi"</string>
- <string name="enable_adb_summary" msgid="3711526030096574316">"USB qoşulu olan zaman debaq rejimi"</string>
- <string name="clear_adb_keys" msgid="3010148733140369917">"USB debaq avtorizasiyasını ləğv edin"</string>
+ <string name="enable_adb_summary" msgid="3711526030096574316">"USB qoşulanda sazlama"</string>
+ <string name="clear_adb_keys" msgid="3010148733140369917">"USB ilə sazlama icazəsi ləğv edilsin"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Wi-Fi vasitəsilə sazlama"</string>
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi qoşulduqda sazlama rejimi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Xəta"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Wi-Fi vasitəsilə sazlama"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Cihazları görmək və istifadə etmək üçün WiFi vasitəsilə sazlamanı işə salın"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR kodu ilə cihazı cütləşdirin"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR kodu ilə cihazı birləşdirin"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR kod skanerindən istifadə etməklə yeni cihazları birləşdirin"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Qoşulma kodu ilə cihazı əlavə edin"</string>
- <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Altı rəqəmli koddan istifadə etməklə yeni cihazları cütləşdirin"</string>
- <string name="adb_paired_devices_title" msgid="5268997341526217362">"Cütləşdirilmiş cihazlar"</string>
+ <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Altı rəqəmli kod istifadə etməklə yeni cihazları birləşdirin"</string>
+ <string name="adb_paired_devices_title" msgid="5268997341526217362">"Birləşdirilmiş cihazlar"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Hazırda qoşulub"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Cihaz detalları"</string>
<string name="adb_device_forget" msgid="193072400783068417">"Unudun"</string>
@@ -227,7 +227,7 @@
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi qoşulma kodu"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Qoşula bilmir"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Eyni şəbəkəyə qoşulduğunu dəqiqləşdirin."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR kodu skanlamaqla cihazı Wi‑Fi vasitəsilə cütləşdirin"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR kodunu skan edib cihazı Wi‑Fi ilə birləşdirin"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Cihaz cütləşdirilir…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Cihazı cütləşdirmək alınmadı. Ya QR kodu yanlış idi, ya da cihaz eyni şəbəkəyə qoşulmayıb."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ünvanı və Port"</string>
@@ -235,11 +235,11 @@
<string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR kodu skanlamaqla cihazı Wi‑Fi vasitəsilə birləşdirin"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi şəbəkəsinə qoşulun"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
- <string name="bugreport_in_power" msgid="8664089072534638709">"Baq raportu qısa yolu"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Baq raportunu götürmək üçün qidalanma menyusunda düyməni göstərin"</string>
+ <string name="bugreport_in_power" msgid="8664089072534638709">"Xəta hesabatı"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Qidalanma düyməsi menyusunda xəta hesabatının göndərilməsi punktu göstərilsin"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Oyaq qal"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Enereji doldurularkən ekran heç vaxt yuxu rejimində olmur"</string>
- <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI izləmə jurnalını aktivləşdir"</string>
+ <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI jurnalı aktivləşdirilsin"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Bluetooth paketləri əldə edin. (Bu ayarı dəyişdikdən sonra Bluetooth\'u aktiv/deaktiv edin)"</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"OEM kilidinin açılması"</string>
<string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Əməliyyat sistemi yükləyicisinin kilidinin açılmasına icazə ver"</string>
@@ -249,25 +249,25 @@
<string name="mock_location_app_not_set" msgid="6972032787262831155">"Ayarlanmış saxta məkan tətbiqi yoxdur"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"Saxta məkan tətbiqi: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Şəbəkələşmə"</string>
- <string name="wifi_display_certification" msgid="1805579519992520381">"Simsiz displey sertifikatlaşması"</string>
+ <string name="wifi_display_certification" msgid="1805579519992520381">"Simsiz monitor sertifikatlaşması"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi skanlamasının tənzimlənməsi"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi axtarışının məhdudlaşdırılması"</string>
<string name="wifi_enhanced_mac_randomization" msgid="882650208573834301">"Wi‑Fi müvəqqəti MAC randomizasiyası"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Mobil data həmişə aktiv"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Modem rejimində cihaz sürətləndiricisi"</string>
- <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth cihazlarını adsız göstərin"</string>
- <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Mütləq səs həcmi deaktiv edin"</string>
- <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche\'ni aktiv edin"</string>
+ <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth cihazları adsız göstərilsin"</string>
+ <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Mütləq səs həcmi deaktiv edilsin"</string>
+ <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche aktiv edilsin"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP Versiya"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP Versiyasını seçin"</string>
<string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP Versiyası"</string>
<string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP Versiyasını seçin"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio Kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth Audio KodeK\nSeçimini aktiv edin"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth Audio Nümunə Göstəricisi"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"Bluetooth Audio Kodek\nSeçimini aktiv edin: Nümunə Göstəricisi"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio diskredizasiya tezliyi"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"Bluetooth üçün audiokodek işə salınsın\nSeçim: Diskredizasiya tezliyi"</string>
<string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"Boz rəng telefon və ya qulaqlıq tərəfindən dəstəklənmədiyini bildirir"</string>
- <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"Hər Nümunə Üçün Bluetooth Audio Bit"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"Bluetooth səs örnəyi üzrə bit"</string>
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"Bluetooth Audio Kodek\nSeçimini aktiv edin: Hər Nümunə üçün Bit"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"Bluetooth Audio Kanal Rejimi"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Bluetooth Audio Kodek\nSeçimini aktiv edin: Kanal Rejimi"</string>
@@ -281,24 +281,24 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"Şəxsi DNS provayder hostunun adı"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS provayder host adını daxil edin"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Qoşulmaq mümkün olmadı"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Simsiz monitorların sertifikasiya parametrləri göstərilsin"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string>
- <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Batareya istifadəsini azaldır &amp; şəbəkə performansını yaxşılaşdırır"</string>
- <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"Bu rejim deaktiv edildikdə, bu cihaz hər dəfə MAC randomizasiyası aktiv edilmiş şəbəkəyə qoşulanda onun MAC ünvanı dəyişə bilər."</string>
+ <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Enerji sərfiyyatını azaldır və şəbəkənin işini yaxşılaşdırır"</string>
+ <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"Bu rejimdə şəbəkəyə hər dəfə qoşulanda cihaza təsadüfi MAC ünvanı verilə bilər."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Tarif sayğacılı"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Limitsiz"</string>
- <string name="select_logd_size_title" msgid="1604578195914595173">"Logger bufer ölçüləri"</string>
- <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Hər jurnal buferinı Logger ölçüsü seçin"</string>
+ <string name="select_logd_size_title" msgid="1604578195914595173">"Jurnal buferi ölçüsü"</string>
+ <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Jurnal buferi ölçüsünü seçin"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Loqqerin davamlı yaddaşı silinsin?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Artıq davamlı loqqer ilə izləmədiyimiz zaman, cihazınızdakı loqqer data rezidentini silmək tələb olunur."</string>
- <string name="select_logpersist_title" msgid="447071974007104196">"Loqqer datasını davamlı olaraq cihazda saxlayın"</string>
+ <string name="select_logpersist_title" msgid="447071974007104196">"Jurnal məlumatları daima cihazda saxlanılsın"</string>
<string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Davamlı olaraq cihazda yadda saxlamaq üçün loq buferlərini seçin"</string>
<string name="select_usb_configuration_title" msgid="6339801314922294586">"USB Sazlaması seçin"</string>
<string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"USB Sazlaması seçin"</string>
<string name="allow_mock_location" msgid="2102650981552527884">"Sınaq yerləşmələrə icazə verin"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"Sınaq yerləşmələrə icazə verin"</string>
- <string name="debug_view_attributes" msgid="3539609843984208216">"Atribut inspeksiyasına baxışa icazə verin"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Hətta Wi‑Fi aktiv olanda da mobil datanı həmişə aktiv saxlayın (sürətli şəbəkək keçidi üçün)."</string>
+ <string name="debug_view_attributes" msgid="3539609843984208216">"Atributlar yoxlanılsın"</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Hətta Wi-Fi bağlantısı olanda da məlumatların mobil şəbəkə ilə ötürülməsi yolu açıq qalsın (şəbəkələr arasında cəld keçid üçün)"</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"İmkan olduqda, modem rejimində cihaz sürətləndiricisi istifadə olunsun"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB debaq funksiyasına icazə verilsin?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB sazlanması yalnız inkişaf məqsədlidir. Kompüteriniz və cihazınız arasında datanı kopyalamaq üçün ondan istifadə edin, bildiriş olmadan tətbiqləri cihazınıza quraşdırın və qeydiyyat datasını oxuyun."</string>
@@ -307,80 +307,79 @@
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Əvvəl icazə verdiyiniz kompüterlərdən USB debaq əməliyyatına giriş ləğv olunsun?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"İnkişaf ayarlarına icazə verilsin mi?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Bu parametrlər yalnız inkişafetdirici istifadə üçün nəzərdə tutulub. Onlar cihaz və tətbiqlərinizin sınması və ya pis işləməsinə səbəb ola bilər."</string>
- <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB üzərindən tətbiqləri yoxlayın"</string>
+ <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Tətbiqlər quraşdırılanda yoxlanılsın"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT vasitəsi ilə quraşdırılmış tətbiqləri zərərli davranış üzrə yoxlayın."</string>
- <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Adsız Bluetooth cihazları (yalnız MAC ünvanları) göstəriləcək"</string>
- <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Uzaqdan idarə olunan cihazlarda dözülməz yüksək səs həcmi və ya nəzarət çatışmazlığı kimi səs problemləri olduqda Bluetooth mütləq səs həcmi xüsusiyyətini deaktiv edir."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche funksiyasını aktiv edir."</string>
+ <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth cihazları adsız (yalnız MAC ünvanları ilə) göstərilsin"</string>
+ <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Kənar cihazlarda problem olanda (yüksək səs həcmi və ya nəzarət çatışmazlığı) Bluetooth səs həcminin mütləq səviyyəsini deaktiv edir."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche funksiya toplusunu aktiv edir."</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Qabaqcıl məlumat mübadiləsini aktiv edir."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Yerli terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Yerli örtük girişini təklif edən terminal tətbiqi aktiv edin"</string>
- <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP yoxlanılır"</string>
- <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP davranış yoxlamasını ayarlayın"</string>
+ <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP yoxlanışı"</string>
+ <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP yoxlanışı qaydası ayalansın"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Sazlama"</string>
- <string name="debug_app" msgid="8903350241392391766">"Debaq tətbiqi seçin"</string>
- <string name="debug_app_not_set" msgid="1934083001283807188">"Debaq tətbiqi ayarlanmayıb"</string>
+ <string name="debug_app" msgid="8903350241392391766">"Sazlamaq üçün tətbiq seçin"</string>
+ <string name="debug_app_not_set" msgid="1934083001283807188">"Sazlamaq üçün tətbiq seçilməyib"</string>
<string name="debug_app_set" msgid="6599535090477753651">"Tətbiq debaq olunur: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="select_application" msgid="2543228890535466325">"Tətbiq seçin"</string>
<string name="no_application" msgid="9038334538870247690">"Heç nə"</string>
- <string name="wait_for_debugger" msgid="7461199843335409809">"Sazlamanı gözləyin"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Sazlanmış tətbiq icradan əvvəl qoşulmaq üçün sazlayıcı gözləyir"</string>
+ <string name="wait_for_debugger" msgid="7461199843335409809">"Sazlayıcını gözləyin"</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Tətbiq sazlayıcının qoşulmasını gözləyir"</string>
<string name="debug_input_category" msgid="7349460906970849771">"Daxiletmə"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"Təsvir"</string>
- <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Avadanlıq qaldırma renderi"</string>
+ <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Renderinq aparat sürətlənməsi"</string>
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitorinq"</string>
- <string name="strict_mode" msgid="889864762140862437">"Məhdud rejim aktivdir"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"Əsas axında tətbiqlərin əlavə əməliyyatlar etməsi zamanı ekran işartısı olsun"</string>
+ <string name="strict_mode" msgid="889864762140862437">"Ciddi rejim"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"Uzun əməliyyatlar ərzində ekran işıqlandırılsın"</string>
<string name="pointer_location" msgid="7516929526199520173">"Kursor yeri"</string>
- <string name="pointer_location_summary" msgid="957120116989798464">"Cari əlaqə datasını göstərən ekran örtüyü"</string>
- <string name="show_touches" msgid="8437666942161289025">"Tıklamaları göstərin"</string>
- <string name="show_touches_summary" msgid="3692861665994502193">"Tıklamalar üçün vizual cavab rəylərini göstərin"</string>
- <string name="show_screen_updates" msgid="2078782895825535494">"Səth güncəlləşməsini göstər"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"Güncəlləmədən sonra bütün ekranda işartı olsun"</string>
- <string name="show_hw_screen_updates" msgid="2021286231267747506">"Görüntü yeniliklərinə baxın"</string>
- <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"pəncərələrin daxilindəki fleş görüntüləri"</string>
- <string name="show_hw_layers_updates" msgid="5268370750002509767">"Avadanlıq düzənlərinin güncəlləşməsini göstərin"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Onlar güncəllənəndən sonra avadanlıq qatlarında işartı olsun"</string>
- <string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU böyütməsini sazlayın"</string>
- <string name="disable_overlays" msgid="4206590799671557143">"HW overlay deaktiv edin"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Həmişə ekran kompozisiyası üçün GPU istifadə edin"</string>
- <string name="simulate_color_space" msgid="1206503300335835151">"Rəng sahəsini simulyasiya edin"</string>
+ <string name="pointer_location_summary" msgid="957120116989798464">"Toxunuş və jest datası göstərilsin"</string>
+ <string name="show_touches" msgid="8437666942161289025">"Vizual reaksiya"</string>
+ <string name="show_touches_summary" msgid="3692861665994502193">"Toxunuşa vizual reaksiya verilsin"</string>
+ <string name="show_screen_updates" msgid="2078782895825535494">"Səth yenilənməsi göstərilsin"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"Pəncərə səthi təzələnəndə işıqlansın"</string>
+ <string name="show_hw_screen_updates" msgid="2021286231267747506">"Baxış yenilənməsi göstərilsin"</string>
+ <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Çəkəndə ekran sahələri işıqlansın"</string>
+ <string name="show_hw_layers_updates" msgid="5268370750002509767">"Aparat yenilənməsi göstərilsin"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Yenilənəndə aparat qatları yaşıl rənglə ayrılsın"</string>
+ <string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU artıqlaması sazlansın"</string>
+ <string name="disable_overlays" msgid="4206590799671557143">"Aparat qatı deaktiv edilsin"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Ekran kompozisiyası üçün GPU istifadə edilsin"</string>
+ <string name="simulate_color_space" msgid="1206503300335835151">"Anomaliya simulyasiyası"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGL izlərini aktivləşdirin"</string>
- <string name="usb_audio_disable_routing" msgid="3367656923544254975">"USB audio marşrutu deaktiv edin"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"USB audio periferiyalara avtomatik marşrutu deaktiv edin"</string>
- <string name="debug_layout" msgid="1659216803043339741">"Düzən həddini göstər"</string>
- <string name="debug_layout_summary" msgid="8825829038287321978">"Klip sərhədləri, boşluqları və s. göstər"</string>
+ <string name="usb_audio_disable_routing" msgid="3367656923544254975">"USB audiomarşrut deaktiv edilsin"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Xarici USB-yə avto-marşrutizasiya deaktiv edilsin"</string>
+ <string name="debug_layout" msgid="1659216803043339741">"Element sərhəddi göstərilsin"</string>
+ <string name="debug_layout_summary" msgid="8825829038287321978">"Kəsim sərhəddi, sahəsi və digər şeyləri göstərilsin"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL düzən istiqamətinə məcbur edin"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Ekran düzən istiqamətini RTL üzərinə bütün yerli variantlar üçün məcbur edin"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
- <string name="force_msaa" msgid="4081288296137775550">"4x MSAA məcbur edin"</string>
- <string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 tətbiqlərində 4x MSAA aktiv et"</string>
- <string name="show_non_rect_clip" msgid="7499758654867881817">"Qeyri-düzbucaqlı klip əməliyyatlarını debaq edin"</string>
- <string name="track_frame_time" msgid="522674651937771106">"Profil HWUI bərpası"</string>
- <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU debaq təbəqələrini aktiv edin"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU debaq təbəqələrinin yüklənməsinə icazə verin"</string>
- <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Detallı təchizatçı qeydini aktiv edin"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xəta hesabatlarına cihaza xas əlavə təchizatçı jurnallarını daxil edin, lakin nəzərə alın ki, onlar şəxsi məlumatları ehtiva edə, daha çox batareya istifadə edə və/və ya daha çox yaddaş istifadə edə bilər."</string>
- <string name="window_animation_scale_title" msgid="5236381298376812508">"Pəncərə animasiya miqyası"</string>
- <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animasiya keçid miqyası"</string>
- <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator müddət şkalası"</string>
+ <string name="window_blurs" msgid="6831008984828425106">"Pəncərə səviyyəsində bulanıqlığa icazə verin"</string>
+ <string name="force_msaa" msgid="4081288296137775550">"4x MSAA aktiv edilsin"</string>
+ <string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 tətbiqlərində 4x MSAA aktiv edilsin"</string>
+ <string name="show_non_rect_clip" msgid="7499758654867881817">"Mürəkkəb formaların kəsilməsi əməliyyatı sazlansın"</string>
+ <string name="track_frame_time" msgid="522674651937771106">"HWUI iş vaxtı uçotu"</string>
+ <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Qrafik prosessor sazlanması"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Qrafik prosessor qatları sazlanmasının yüklənməsinə icazə verilsin"</string>
+ <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Təfsilatlı təchizatçı jurnalı"</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xəta hesabatına təchizatçının cihaz haqqında əlavə qeydləri daxil edilsin. Qeydlərdə şəxsi məlumatlar ola, onlar artıq yer tuta və enerji sərfiyyatını artıra bilər."</string>
+ <string name="window_animation_scale_title" msgid="5236381298376812508">"Pəncərə animasiyası"</string>
+ <string name="transition_animation_scale_title" msgid="1278477690695439337">"Keçid animasiyası"</string>
+ <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animasiya müddəti"</string>
<string name="overlay_display_devices_title" msgid="5411894622334469607">"İkincili displeyi imitasiya edin"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"Tətbiqlər"</string>
- <string name="immediately_destroy_activities" msgid="1826287490705167403">"Fəaliyyətləri saxlamayın"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"İstifadəçinin tərk etdiyi hər fəaliyyəti dərhal məhv et"</string>
+ <string name="immediately_destroy_activities" msgid="1826287490705167403">"Fəaliyyətlər saxlanmasın"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"İstifadəçi çıxan kimi fəaliyyət silinsin"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"Fon prosesi limiti"</string>
- <string name="show_all_anrs" msgid="9160563836616468726">"Arxa fon ANR-lərini göstərin"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"Arxa fon tətbiqləri üçün Tətbiq Cavab Vermir dialoqunu göstərin"</string>
+ <string name="show_all_anrs" msgid="9160563836616468726">"Fonda ANR"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Fondakı tətbiq cavab verməyəndə bildirilsin"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Xəbərdarlıqları göstərin"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bildiriş paylaşıldıqda xəbərdarlıq göstərir"</string>
- <string name="force_allow_on_external" msgid="9187902444231637880">"Tətbiqlərə xaricdən məcburi icazə"</string>
- <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Seçilmiş hər hansı tətbiqi bəyannamə dəyərlərindən aslı olmayaraq xarici yaddaşa yazılabilən edir."</string>
- <string name="force_resizable_activities" msgid="7143612144399959606">"Ölçü dəyişdirmək üçün məcburi fəaliyyətlər"</string>
- <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bəyannamə dəyərlərindən aslı olmayaraq, bütün fəaliyyətləri çoxsaylı pəncərə üçün dəyişkən ölçülü edin."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Freeform windows aktiv edin"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Sınaq üçün freeform windows aktiv edilir."</string>
+ <string name="force_allow_on_external" msgid="9187902444231637880">"Xarici daşıyıcılarda saxlanmaya icazə verilsin"</string>
+ <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest dəyərindən asılı olmayaraq tətbiqlərin xarici daşıyıcılarda saxlanmasına icazə verilsin"</string>
+ <string name="force_resizable_activities" msgid="7143612144399959606">"Çoxpəncərəli rejimdə ölçü dəyişdirilməsi"</string>
+ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest dəyərindən asılı olmayaraq çoxpəncərəli rejimdə pəncərə ölçüsünün dəyişdirilməsinə icazə verilsin"</string>
+ <string name="enable_freeform_support" msgid="7599125687603914253">"İxtiyari formada pəncərə yaradılsın"</string>
+ <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Eksperimental olaraq ixtiyari formada pəncərə yaradılsın"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü rezerv parolu"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam rezervlər hazırda qorunmayıblar."</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstünün tam rezerv kopyalanması üçün parolu dəyişmək və ya silmək üçün basın"</string>
@@ -398,20 +397,20 @@
<item msgid="4548987861791236754">"Gözlə göründüyü kimi təbii rənglər"</item>
<item msgid="1282170165150762976">"Rəqəmsal məzmun üçün optimallaşdırılan rənglər"</item>
</string-array>
- <string name="inactive_apps_title" msgid="5372523625297212320">"Arxa fonda məhdudlaşdırılan tətbiq"</string>
+ <string name="inactive_apps_title" msgid="5372523625297212320">"Gözləmə rejimində tətbiqlər"</string>
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Deaktivdir. Keçid etmək üçün basın."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktivdir. Keçid etmək üçün basın."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Tətbiqin gözləmə rejimi:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <string name="transcode_settings_title" msgid="2581975870429850549">"Media yenidən kodlaşdırma ayarları"</string>
+ <string name="transcode_settings_title" msgid="2581975870429850549">"Media kodçevirmə ayarları"</string>
<string name="transcode_user_control" msgid="6176368544817731314">"Yenidən kodlaşdırma defoltlarını əvəzləyin"</string>
<string name="transcode_enable_all" msgid="2411165920039166710">"Yenidən kodlaşdırmanı aktiv edin"</string>
<string name="transcode_default" msgid="3784803084573509491">"Tətbiqlərin müasir formatları dəstəklədiyini qəbul edin"</string>
<string name="transcode_notification" msgid="5560515979793436168">"Kod dəyişmə bildirişlərini göstərin"</string>
<string name="transcode_disable_cache" msgid="3160069309377467045">"Keşin kodlaşdırılmasını deaktiv edin"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"İşləyən xidmətlər"</string>
- <string name="runningservices_settings_summary" msgid="1046080643262665743">"Hazırda prosesdə olan xidmətləri görüntüləyin və onlara nəzarət edin"</string>
- <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView icrası"</string>
- <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView icrasını ayarlayın"</string>
+ <string name="runningservices_settings_summary" msgid="1046080643262665743">"İşlək xidmətlərə baxış və onların idarəedilməsi"</string>
+ <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView servisi"</string>
+ <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView servisini ayarlayın"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Bu seçim artıq etibarlı deyil. Yenidən cəhd edin."</string>
<string name="convert_to_file_encryption" msgid="2828976934129751818">"Fayl şifrələnməsinə çevirin"</string>
<string name="convert_to_file_encryption_enabled" msgid="840757431284311754">"Çevirin..."</string>
@@ -426,8 +425,8 @@
<string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomaliya (qırmızı-yaşıl)"</string>
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaliya (qırmızı-yaşıl)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaliya (göy-sarı)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Rəng düzəlişi"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Cihazınızda rənglərin necə göstərilməsini tənzimləyin. Bu, aşağıdakıları etmək istədikdə faydalı ola bilər:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Rəngləri daha dəqiq görmək&lt;/li&gt; &lt;li&gt;&amp;nbsp;Fokuslanmaq üçün rəngləri ləğv etmək&lt;/li&gt; &lt;/ol&gt;"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Rəng korreksiyası"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ekranda rəngi korreksiya edə bilərsiniz. Mümkün olanlar:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;rəng ötürülməsinin yaxşılaşdırılması;&lt;/li&gt; &lt;li&gt;&amp;nbsp;rahat fokuslanmaq üçün ağ-qara rejimə keçid.&lt;/li&gt; &lt;/ol&gt;"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Siqnallar və xatırladıcılar"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Siqnallar və xatırlatmaları ayarlamağa icazə verin"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Siqnallar və xatırlatmalar"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Bu tətbiqə zəngli saat və bildiriş hazırlamaq icazəsi verdiyiniz halda tətbiq cihaz istifadə edilmədiyi zaman da işləyəcək, enerji daha tez qurtaracaq. Bu ayar deaktiv ediləndən sonra tətbiqin işində kəsintilər ola, zəngli saatlar vaxtında işləməyə bilər."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Bu tətbiqə zəngli saat və bildiriş hazırlamaq icazəsi verdiyiniz halda tətbiq cihaz istifadə edilmədiyi zaman da işləyəcək, enerji daha tez qurtaracaq. Bu ayar deaktiv ediləndən sonra tətbiqin işində kəsintilər ola, zəngli saatlar vaxtında işləməyə bilər."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Bu tətbiqə zəngli saat və bildiriş hazırlamaq icazəsi verdiyiniz halda tətbiq cihaz istifadə edilmədiyi zaman da işləyəcək, enerji daha tez qurtaracaq. Bu ayar deaktiv ediləndən sonra tətbiqin işində kəsintilər ola, zəngli saatlar vaxtında işləməyə bilər."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu tətbiqə siqnallar ayarlamağa və vaxta əsaslanan əməliyyatları planlaşdırmağa icazə verin. Bu, tətbiqin arxa fonda işləməsinə imkan verir ki, nəticədə daha çox enerji istifadə edilə bilər.\n\nBu icazə deaktiv olsa, bu tətbiq tərəfindən planlaşdırılan mövcud siqnallar və vaxta əsaslanan tədbirlər işləməyəcəkdir."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"cədvəl, siqnal, xatırlatma, saat"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktiv edin"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Narahat Etməyin\" rejimini aktiv edin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 1edd95e5e4da..790323003ba1 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -236,7 +236,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na WiFi mrežu"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izveštaj o greškama"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Prikazuje dugme u meniju napajanja za pravljenje izveštaja o greškama"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Prikazuje dugme u meniju dugmeta za uključivanje za pravljenje izveštaja o greškama"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Ne zaključavaj"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Ekran neće biti u režimu spavanja tokom punjenja"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Omogući snoop evid. za Bluetooth HCI"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Prikazuje granice klipa, margine itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Nametni smer rasporeda zdesna nalevo"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nameće smer rasporeda ekrana zdesna nalevo za sve lokalitete"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Dozvoli zamagljenja prozora"</string>
<string name="force_msaa" msgid="4081288296137775550">"Nametni 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Omogućava 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Otkloni greške isecanja oblasti nepravougaonog oblika"</string>
@@ -509,9 +508,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsetnici"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Omogući podešavanje alarma i podsetnika"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsetnici"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje druge radnje. Ova aplikacija može da se koristi kada ne koristite telefon, što može da dodatno troši bateriju. Ako je ova dozvola isključena, ova aplikacija možda neće raditi normalno i njeni alarmi neće raditi po rasporedu."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje druge radnje. Ova aplikacija može da se koristi kada ne koristite tablet, što može da dodatno troši bateriju. Ako je ova dozvola isključena, ova aplikacija možda neće raditi normalno i njeni alarmi neće raditi po rasporedu."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje druge radnje. Ova aplikacija može da se koristi kada ne koristite uređaj, što može da dodatno troši bateriju. Ako je ova dozvola isključena, ova aplikacija možda neće raditi normalno i njeni alarmi neće raditi po rasporedu."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje vremenski osetljive radnje. To omogućava da aplikacija bude pokrenuta u pozadini, što može da troši više baterije.\n\nAko je ova dozvola isključena, postojeći alarmi i događaji zasnovani na vremenu zakazani pomoću ove aplikacije neće raditi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"zakazati, alarm, podsetnik, sat"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite režim Ne uznemiravaj"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index d20e5daeae31..0fb717898be6 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Паказаць межы абрэзкі, палі і г. д."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Прымусовая раскладка справа налева"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Прымусовая раскладка экрана справа налева для ўсіх рэгіянальных налад"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Размываць на ўзроўні акна"</string>
<string name="force_msaa" msgid="4081288296137775550">"Прымусовае выкананне 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Уключыць 4x MSAA у праграмах з OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Адладка аперацый непрамавугольнага кліпа"</string>
@@ -510,9 +509,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будзільнікі і напаміны"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Дазволіць усталёўваць будзільнікі і напаміны"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будзільнікі і напаміны"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Дазвольце гэтай праграме ўсталёўваць будзільнікі і задаваць расклад для дзеянняў. Праграма можа працаваць, калі вы не выкарыстоўваеце тэлефон, і ў выніку хутчэй разраджаць акумулятар. Калі гэты дазвол выключаны, праграма можа не працаваць належым чынам, а яе будзільнікі – не спрацоўваць як запланавана."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Дазвольце гэтай праграме ўсталёўваць будзільнікі і задаваць расклад для дзеянняў. Праграма можа працаваць, калі вы не выкарыстоўваеце планшэт, і ў выніку хутчэй разраджаць акумулятар. Калі гэты дазвол выключаны, праграма можа не працаваць належым чынам, а яе будзільнікі – не спрацоўваць як запланавана."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Дазвольце гэтай праграме ўсталёўваць будзільнікі і задаваць расклад для дзеянняў. Праграма можа працаваць, калі вы не выкарыстоўваеце прыладу, і ў выніку хутчэй разраджаць акумулятар. Калі гэты дазвол выключаны, праграма можа не працаваць належым чынам, а яе будзільнікі – не спрацоўваць як запланавана."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"расклад, будзільнік, напамін, гадзіннік"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Уключыць"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Уключэнне рэжыму \"Не турбаваць\""</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index d92256d3b98f..4d92282b62d6 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Показв. на границите на изрязване, полетата и др."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Принуд. оформл. от дясно наляво"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудително оформление на екрана от дясно наляво за всички локали"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Замъгл. на ниво прозорец"</string>
<string name="force_msaa" msgid="4081288296137775550">"Задаване на 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Активиране на 4x MSAA в прилож. с OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Отстр. на грешки при неправоъг. изрязване"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будилници и напомняния"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Разреш. на задаването на будилници и напомняния"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будилници и напомняния"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Разрешете на това приложение да задава будилници и да насрочва други действия. То може да работи, когато не използвате телефона си, и затова да изразходва повече енергия. Ако това разрешение е изключено, приложението може да не функционира нормално, а зададените будилници няма да работят."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Разрешете на това приложение да задава будилници и да насрочва други действия. То може да работи, когато не използвате таблета си, и затова да изразходва повече енергия. Ако това разрешение е изключено, приложението може да не функционира нормално, а зададените будилници няма да работят."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Разрешете на това приложение да задава будилници и да насрочва други действия. То може да работи, когато не използвате устройството си, и затова да изразходва повече енергия. Ако това разрешение е изключено, приложението може да не функционира нормално, а зададените будилници няма да работят."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Разрешаване на това приложение да задава будилници и да насрочва действия, ограничени във времето. Това му позволява да работи на заден план, при което може да се използва повече батерия.\n\nАко разрешението е изключено, съществуващите будилници и събитията въз основа на времето, насрочени от приложението, няма да работят."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, будилник, напомняне, часовник"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включване"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включване на режима „Не безпокойте“"</string>
@@ -563,7 +560,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="add_user_failed" msgid="4809887794313944872">"Неуспешно създаване на нов потребител"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 9c8eff45fc28..b7fdef23ce67 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ক্লিপ বাউন্ড, মার্জিন ইত্যাদি দেখান"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL লেআউট দিকনির্দেশ জোর দিন"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"সমস্ত স্থানের জন্য RTL এ স্ক্রিন লেআউট দিকনির্দেশে জোর দেয়"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"উইন্ডো-লেভেল অস্পষ্ট করার সুবিধা চালু করুন"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA-এ জোর দিন"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 অ্যাপের মধ্যে 4x MSAA চালু করুন"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"অ-আয়তক্ষেত্রাকার ক্লিপ অ্যাক্টিভিটি ডিবাগ করুন"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"অ্যালার্ম এবং রিমাইন্ডার"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"অ্যালার্ম এবং রিমাইন্ডার সেট করার অনুমতি দিন"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"অ্যালার্ম এবং রিমাইন্ডার"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"অন্যান্য অ্যাকশন শিডিউল করতে এবং অ্যালার্ম সেট করার জন্য এই অ্যাপকে অনুমতি দিন। আপনি ফোন ব্যবহার না করার সময় এই অ্যাপ ব্যবহার করা হতে পারে, যার ফলে আরও ব্যাটারির চার্জ খরচ হতে পারে। অনুমতি দেওয়া না থাকলে, এই অ্যাপ সঠিকভাবে কাজ নাও করতে পারে এবং অ্যালার্মও শিডিউল অনুযায়ী বাজবে না।"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"অন্যান্য অ্যাকশন শিডিউল করতে এবং অ্যালার্ম সেট করার জন্য এই অ্যাপকে অনুমতি দিন। আপনি ট্যাবলেট ব্যবহার না করার সময় এই অ্যাপ ব্যবহার করা হতে পারে, যার ফলে আরও ব্যাটারির চার্জ খরচ হতে পারে। অনুমতি দেওয়া না থাকলে, এই অ্যাপ সঠিকভাবে কাজ নাও করতে পারে এবং অ্যালার্মও শিডিউল অনুযায়ী বাজবে না।"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"অন্যান্য অ্যাকশন শিডিউল করতে এবং অ্যালার্ম সেট করার জন্য এই অ্যাপকে অনুমতি দিন। আপনি ডিভাইস ব্যবহার না করার সময় এই অ্যাপ ব্যবহার করা হতে পারে, যার ফলে আরও ব্যাটারির চার্জ খরচ হতে পারে। অনুমতি দেওয়া না থাকলে, এই অ্যাপ সঠিকভাবে কাজ নাও করতে পারে এবং অ্যালার্মও শিডিউল অনুযায়ী বাজবে না।"</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"শিডিউল, অ্যালার্ম, রিমাইন্ডার, ঘড়ি"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"চালু করুন"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'বিরক্ত করবে না\' মোড চালু করুন"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 46921a4f3262..d3049b13eb93 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -180,7 +180,7 @@
<string name="tts_engine_settings_title" msgid="7849477533103566291">"Postavke za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
<string name="tts_engine_settings_button" msgid="477155276199968948">"Pokreni postavke programa"</string>
<string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Željeni alat"</string>
- <string name="tts_general_section_title" msgid="8919671529502364567">"Opće postavke"</string>
+ <string name="tts_general_section_title" msgid="8919671529502364567">"Opće"</string>
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Postavite visinu glasa"</string>
<string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Visinu glasa koji izgovara tekst postavite na podrazumjevanu."</string>
<string-array name="tts_rate_entries">
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Prikaz granica isječka, margina itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Prisilno postavi raspored s desna ulijevo"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Prisilno postavljanje rasporeda ekrana s desna ulijevo za sve regije"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Dozvoli zamućenja prozora"</string>
<string name="force_msaa" msgid="4081288296137775550">"Prinudno primijeni 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Omogućava 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Otkl. greške na operac. nepravoug. isjecanja"</string>
@@ -509,9 +508,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsjetnici"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Dozvoli postavljanje alarma i podsjetnika"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Dozvolite ovoj aplikaciji da postavlja alarme i zakaže druge radnje. Ova aplikacija se može koristiti kada ne koristite telefon, čime se može povećati potrošnja baterije. Ako isključite ovo odobrenje, moguće je da ova aplikacija neće funkcionirati kako je namijenjeno, a njeni alarmi neće funkcionirati prema rasporedu."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Dozvolite ovoj aplikaciji da postavlja alarme i zakaže druge radnje. Ova aplikacija se može koristiti kada ne koristite tablet, čime se može povećati potrošnja baterije. Ako isključite ovo odobrenje, moguće je da ova aplikacija neće funkcionirati kako je namijenjeno, a njeni alarmi neće funkcionirati prema rasporedu."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Dozvolite ovoj aplikaciji da postavlja alarme i zakaže druge radnje. Ova aplikacija se može koristiti kada ne koristite uređaj, čime se može povećati potrošnja baterije. Ako isključite ovo odobrenje, moguće je da ova aplikacija neće funkcionirati kako je namijenjeno, a njeni alarmi neće funkcionirati prema rasporedu."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dozvolite ovoj aplikaciji da postavlja alarme i zakazuje vremenski osjetljive radnje. Ovim će se omogućiti aplikaciji da radi u pozadini, čime se može povećati potrošnja baterije.\n\nAko je ovo odobrenje isključeno, postojeći alarmi i događaji zasnovani na vremenu koje je ova aplikacija zakazala neće funkcionirati."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključi način rada Ne ometaj"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 557e917d243b..eab1cd2b71a5 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra els límits de clips, els marges, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Força direcció dreta-esquerra"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Força direcció de pantalla dreta-esquerra en totes les llengües"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permet desenfoc. finestra"</string>
<string name="force_msaa" msgid="4081288296137775550">"Força MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activa MSAA 4x en aplicacions d\'OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depura operacions de retall no rectangulars"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes i recordatoris"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permet la configuració d\'alarmes i recordatoris"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes i recordatoris"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permet que aquesta aplicació configuri alarmes i programi altres accions. Aquesta aplicació es pot utilitzar quan no fas servir el telèfon, que pot consumir més bateria. Si aquest permís està desactivat, pot ser que l\'aplicació no funcioni amb normalitat i que les alarmes no funcionin tal com s\'han programat."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permet que aquesta aplicació configuri alarmes i programi altres accions. Aquesta aplicació es pot utilitzar quan no fas servir la tauleta, que pot consumir més bateria. Si aquest permís està desactivat, pot ser que l\'aplicació no funcioni amb normalitat i que les alarmes no funcionin tal com s\'han programat."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permet que aquesta aplicació configuri alarmes i programi altres accions. Aquesta aplicació es pot utilitzar quan no fas servir el dispositiu, que pot consumir més bateria. Si aquest permís està desactivat, pot ser que l\'aplicació no funcioni amb normalitat i que les alarmes no funcionin tal com s\'han programat."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permet que aquesta aplicació configuri alarmes i programi accions urgents. Això permet a l\'aplicació executar-se en segon pla i, per tant, és possible que consumeixi més bateria.\n\nSi aquest permís està desactivat, les alarmes i els esdeveniments urgents que ja hagi programat l\'aplicació no funcionaran."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programació, alarma, recordatori, rellotge"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activa"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activa el mode No molestis"</string>
@@ -527,7 +524,7 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Ara mateix"</string>
<string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altaveu del telèfon"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Aquest telèfon"</string>
- <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Desactiva el dispositiu i torna\'l a activar."</string>
+ <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Apaga el dispositiu i torna\'l a encendre."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositiu d\'àudio amb cable"</string>
<string name="help_label" msgid="3528360748637781274">"Ajuda i suggeriments"</string>
<string name="storage_category" msgid="2287342585424631813">"Emmagatzematge"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 2a3b0855669b..7376d7eeaa93 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"U výstřižku zobrazit ohraničení, okraje atd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Vynutit rozvržení zprava doleva"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vynutit ve všech jazycích rozvržení obrazovky zprava doleva"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Povolit rozmazávání oken"</string>
<string name="force_msaa" msgid="4081288296137775550">"Vynutit 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Povolit 4x MSAA v aplikacích OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Ladit operace s neobdélníkovými výstřižky"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Budíky a připomenutí"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Povolit nastavování budíků a připomenutí"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a připomenutí"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Umožní této aplikaci nastavovat budíky a plánovat další akce. Aplikace může být použita, i když telefon nepoužíváte, a tak může docházet k vyšší spotřebě baterie. Když je toto oprávnění vypnuté, aplikace nemusí fungovat normálně a její budíky nebudou fungovat podle plánu."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Umožní této aplikaci nastavovat budíky a plánovat další akce. Aplikace může být použita, i když tablet nepoužíváte, a tak může docházet k vyšší spotřebě baterie. Když je toto oprávnění vypnuté, aplikace nemusí fungovat normálně a její budíky nebudou fungovat podle plánu."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Umožní této aplikaci nastavovat budíky a plánovat další akce. Aplikace může být použita, i když zařízení nepoužíváte, a tak může docházet k vyšší spotřebě baterie. Když je toto oprávnění vypnuté, aplikace nemusí fungovat normálně a její budíky nebudou fungovat podle plánu."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povolte aplikaci nastavovat budíky a plánovat akce závislé na čase. Aplikace poběží na pozadí, což může vést k vyšší spotřebě baterie.\n\nPokud je toto oprávnění vypnuté, stávající budíky a události závislé na čase naplánované touto aplikací nebudou fungovat."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, připomenutí, hodiny"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnout"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapněte funkci Nerušit"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index d7c5d5571ff7..1dc2d146622b 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Vis grænser for klip, margener osv."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Tving læsning mod venstre"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Gennemtving højre mod venstre-layout for alle sprog"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Tillad vinduessløring"</string>
<string name="force_msaa" msgid="4081288296137775550">"Gennemtving 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktivér 4x MSAA i apps med OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Fejlret på ikke-rektangulære klippehandlinger"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmer og påmindelser"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Tillad indstilling af alarmer og påmindelser"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmer og påmindelser"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Tillad, at denne app indstiller alarmer og planlægger andre handlinger. Denne app kan blive brugt, når du ikke bruger din telefon, hvilket kan øge batteriforbruget. Hvis denne tilladelse deaktiveres, fungerer denne app muligvis ikke som normalt, og dens alarmer fungerer ikke på de planlagte tider."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Tillad, at denne app indstiller alarmer og planlægger andre handlinger. Denne app kan blive brugt, når du ikke bruger din tablet, hvilket kan øge batteriforbruget. Hvis denne tilladelse deaktiveres, fungerer denne app muligvis ikke som normalt, og dens alarmer fungerer ikke på de planlagte tider."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Tillad, at denne app indstiller alarmer og planlægger andre handlinger. Denne app kan blive brugt, når du ikke bruger din enhed, hvilket kan øge batteriforbruget. Hvis denne tilladelse deaktiveres, fungerer denne app muligvis ikke som normalt, og dens alarmer fungerer ikke på de planlagte tider."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillad, at denne app indstiller alarmer og planlægger tidsbestemte handlinger. Appen vil køre i baggrunden, hvor den muligvis bruger mere batteri.\n\nHvis denne tilladelse er deaktiveret, vil eksisterende alarmer og tidsbestemte handlinger, der er planlagt af denne app, ikke fungere."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planlæg, alarm, påmindelse, ur"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivér"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivér Forstyr ikke"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 492c6de6bdbf..f092a5198f6c 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Zuschnittbegrenzungen, Ränder usw. anzeigen"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Linksläufiges Layout erzwingen"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Für alle Sprachen wird das linksläufige Bildschirmlayout verwendet"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Weichzeichnen auf Fensterebene zulassen"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA erzwingen"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"In OpenGL ES 2.0-Apps 4x MSAA aktivieren"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Nichtrechteckige Zuschnitte debuggen"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Wecker und Erinnerungen"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Erlauben, Wecker und Erinnerungen einzurichten"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wecker und Erinnerungen"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Dieser App erlauben, Wecker zu stellen und andere Aktionen zu planen. So kann die App gestartet und ausgeführt werden, auch wenn du das Gerät nicht verwendest. Dies kann den Akkuverbrauch erhöhen. Wenn diese Berechtigung deaktiviert ist, funktionieren die App und die zugehörigen Wecker möglicherweise nicht wie erwartet."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Dieser App erlauben, Wecker zu stellen und andere Aktionen zu planen. So kann die App gestartet und ausgeführt werden, auch wenn du das Gerät nicht verwendest. Dies kann den Akkuverbrauch erhöhen. Wenn diese Berechtigung deaktiviert ist, funktionieren die App und die zugehörigen Wecker möglicherweise nicht wie erwartet."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Dieser App erlauben, Wecker zu stellen und andere Aktionen zu planen. So kann die App gestartet und ausgeführt werden, auch wenn du das Gerät nicht verwendest. Dies kann den Akkuverbrauch erhöhen. Wenn diese Berechtigung deaktiviert ist, funktionieren die App und die zugehörigen Wecker möglicherweise nicht wie erwartet."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planen, Wecker, Erinnerung, Uhr"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivieren"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„Bitte nicht stören“ aktivieren"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 19ccac65b44c..5d4301c2afd3 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Εμφάνιση ορίων κλιπ, περιθωρίων, κλπ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Επιβολή κατ. διάταξης RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Επιβολή διάταξης οθόν. RTL για όλες τις τοπ. ρυθμ."</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Θάμπωμα σε επίπεδο παραθ."</string>
<string name="force_msaa" msgid="4081288296137775550">"Αναγκαστικά 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ενεργοποίηση 4x MSAA σε εφαρμογές OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Εντοπισμός σφαλμάτων σε λειτουργίες μη ορθογώνιας περιοχής"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ξυπνητήρια και ειδοποιήσεις"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Να επιτρέπεται ο ορισμός ξυπνητ. και υπενθυμίσεων"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ξυπνητήρια και υπενθυμίσεις"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Να επιτρέπεται σε αυτήν την εφαρμογή να ορίζει ξυπνητήρια και να προγραμματίζει άλλες ενέργειες. Αυτή η εφαρμογή ενδέχεται να χρησιμοποιείται όταν δεν χρησιμοποιείτε το τηλέφωνό σας, κάτι που μπορεί να οδηγήσει σε μεγαλύτερη κατανάλωση μπαταρίας. Εάν αυτή η άδεια είναι απενεργοποιημένη, η εφαρμογή ενδέχεται να μην λειτουργεί φυσιολογικά και τα ξυπνητήρια της δεν θα λειτουργούν σύμφωνα με τον προγραμματισμό τους."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Να επιτρέπεται σε αυτήν την εφαρμογή να ορίζει ξυπνητήρια και να προγραμματίζει άλλες ενέργειες. Αυτή η εφαρμογή ενδέχεται να χρησιμοποιείται όταν δεν χρησιμοποιείτε το tablet, κάτι που μπορεί να οδηγήσει σε μεγαλύτερη κατανάλωση μπαταρίας. Εάν αυτή η άδεια είναι απενεργοποιημένη, η εφαρμογή ενδέχεται να μην λειτουργεί φυσιολογικά και τα ξυπνητήρια της δεν θα λειτουργούν σύμφωνα με τον προγραμματισμό τους."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Να επιτρέπεται σε αυτήν την εφαρμογή να ορίζει ξυπνητήρια και να προγραμματίζει άλλες ενέργειες. Αυτή η εφαρμογή ενδέχεται να χρησιμοποιείται όταν δεν χρησιμοποιείτε τη συσκευή σας, κάτι που μπορεί να οδηγήσει σε μεγαλύτερη κατανάλωση μπαταρίας. Εάν αυτή η άδεια είναι απενεργοποιημένη, η εφαρμογή ενδέχεται να μην λειτουργεί φυσιολογικά και τα ξυπνητήρια της δεν θα λειτουργούν σύμφωνα με τον προγραμματισμό τους."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"χρονοδιάγραμμα, ξυπνητήρι, υπενθύμιση, ρολόι"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ενεργοποίηση"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ενεργοποίηση λειτουργίας \"Μην ενοχλείτε\""</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 2caa3f78876a..02317eae12e6 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -507,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms &amp; reminders"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your phone, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your tablet, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your device, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index f307e16fdfa7..f15db49c2af1 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -507,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms &amp; reminders"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your phone, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your tablet, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your device, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 2caa3f78876a..02317eae12e6 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -507,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms &amp; reminders"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your phone, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your tablet, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your device, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 2caa3f78876a..02317eae12e6 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -507,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms &amp; reminders"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your phone, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your tablet, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your device, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 2d2b036d90c7..ce5a6bc780e1 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -507,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎Alarms and reminders‎‏‎‎‏‎"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎Allow setting alarms and reminders‎‏‎‎‏‎"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎Alarms &amp; reminders‎‏‎‎‏‎"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your phone, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled.‎‏‎‎‏‎"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your tablet, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled.‎‏‎‎‏‎"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎Allow this app to set alarms and schedule other actions. This app may be used when you’re not using your device, which may use more battery. If this permission is off, this app may not function normally, and its alarms won’t work as scheduled.‎‏‎‎‏‎"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If this permission is off, existing alarms and time-based events scheduled by this app won’t work.‎‏‎‎‏‎"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎schedule, alarm, reminder, clock‎‏‎‎‏‎"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎Turn on‎‏‎‎‏‎"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎Turn on Do Not Disturb‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 3ee5dab48cb3..d050ff874df3 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostrar límites de recortes, márgenes, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar diseño der. a izq."</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forzar diseño de pantalla de derecha a izquierda para todos los idiomas"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permitir difuminación en ventana"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activar MSAA 4x en aplicaciones OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operaciones de recorte no rectangulares"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas y recordatorios"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permitir configuración de alarmas y recordatorios"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permite que esta app configure alarmas y programe otras acciones. Esta app podría ejecutarse cuando no estás usando el teléfono, lo que podría consumir más batería. Si este permiso está desactivado, es posible que la app no funcione con normalidad, y las alarmas no seguirán su programación."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permite que esta app configure alarmas y programe otras acciones. Esta app podría ejecutarse cuando no estás usando la tablet, lo que podría consumir más batería. Si este permiso está desactivado, es posible que la app no funcione con normalidad, y las alarmas no seguirán su programación."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permite que esta app configure alarmas y programe otras acciones. Esta app se puede usar cuando no estás usando el dispositivo, lo que podría consumir más batería. Si este permiso está desactivado, es posible que la app no funcione con normalidad, y las alarmas no seguirán su programación."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar No interrumpir"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index d63ea7b26d55..540a47200e46 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Muestra límites de vídeo, márgenes, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección de diseño RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Fuerza la dirección RTL para todos los idiomas"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Difuminar ventanas"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Habilita MSAA 4x en aplicaciones de OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operaciones de recorte no rectangulares"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas y recordatorios"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permitir la programación de alarmas y recordatorios"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permite que esta aplicación programe alarmas y otras acciones. Puede que la aplicación siga funcionando aunque no estés usando el teléfono, lo que puede consumir más batería. Si este permiso está desactivado, es posible que esta aplicación no funcione correctamente y que las alarmas no se activen según estén programadas."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permite que esta aplicación programe alarmas y otras acciones. Puede que la aplicación siga funcionando aunque no estés usando el tablet, lo que puede consumir más batería. Si este permiso está desactivado, es posible que esta aplicación no funcione correctamente y que las alarmas no se activen según estén programadas."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permite que esta aplicación programe alarmas y otras acciones. Puede que la aplicación siga funcionando aunque no estés usando el dispositivo, lo que puede consumir más batería. Si este permiso está desactivado, es posible que esta aplicación no funcione correctamente y que las alarmas no se activen según estén programadas."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones de carácter temporal. Este permite sirve para que la aplicación siga activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivados, no funcionarán las alarmas ni los eventos con carácter temporal programados por esta aplicación."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar el modo No molestar"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index ed698e2de922..f740cc5495a4 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Kuva klipi piirid, veerised jms"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Jõusta paremalt vasakule paigutus"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Jõusta kõikides lokaatides paremalt vasakule ekraanipaigutus"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Luba akna tasemel hägust."</string>
<string name="force_msaa" msgid="4081288296137775550">"Jõusta 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Luba 4x MSAA OpenGL ES 2.0 rakendustes"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Silu mittetäisnurksed kärpimistoimingud"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmid ja meeldetuletused"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Luba alarmide ja meeldetuletuste määramine"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmid ja meeldetuletused"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Lubage sellel rakendusel määrata alarme ja ajastada muid toiminguid. Seda rakendust võidakse kasutada ajal, kui te oma telefoni ei kasuta, ja see võib akukasutust suurendada. Kui see luba on välja lülitatud, ei pruugi see rakendus korralikult toimida ja selle alarmid ei tööta ajakava järgi."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Lubage sellel rakendusel määrata alarme ja ajastada muid toiminguid. Seda rakendust võidakse kasutada ajal, kui te oma tahvelarvutit ei kasuta, ja see võib akukasutust suurendada. Kui see luba on välja lülitatud, ei pruugi see rakendus korralikult toimida ja selle alarmid ei tööta ajakava järgi."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Lubage sellel rakendusel määrata alarme ja ajastada muid toiminguid. Seda rakendust võidakse kasutada ajal, kui te oma seadet ei kasuta, ja see võib akukasutust suurendada. Kui see luba on välja lülitatud, ei pruugi see rakendus korralikult toimida ja selle alarmid ei tööta ajakava järgi."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lubage sellel rakendusel määrata äratusi ja ajastada kiire tähtajaga toiminguid. See võimaldab rakendusel töötada taustal, mistõttu võib akukasutus olla suurem.\n\nKui see luba on välja lülitatud, siis olemasolevad äratused ja selle rakenduse ajastatud ajapõhised sündmused ei tööta."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajakava, äratus, meeldetuletus, kell"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Lülita sisse"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Valiku Mitte segada sisselülitamine"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index ebc62f2fd852..06e1abd70e78 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Erakutsi kliparen mugak, marjinak, etab."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Behartu eskuin-ezker norabidea"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Behartu pantaila-diseinuaren norabidea eskuin-ezker izatera lurraldeko ezarpen guztiekin"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Gaitu leiho-lausotzeak"</string>
<string name="force_msaa" msgid="4081288296137775550">"Behartu 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Gaitu 4x MSAA, OpenGL ES 2.0 aplikazioetan"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Araztu angeluzuzenak ez diren klip-eragiketak"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmak eta abisuak"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Eman alarmak eta abisuak ezartzeko baimena"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmak eta abisuak"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Eman alarmak ezartzeko eta beste ekintza batzuk programatzeko baimena aplikazioari. Telefonoa erabili ez arren, agian aplikazioak martxan jarraituko du, eta bateria gehiago erabiliko. Baimena desaktibatuta badago, baliteke aplikazioak zuzen ez funtzionatzea eta programatutako alarmek ez jotzea."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Eman alarmak ezartzeko eta beste ekintza batzuk programatzeko baimena aplikazioari. Tableta erabili ez arren, agian aplikazioak martxan jarraituko du, eta bateria gehiago erabiliko. Baimena desaktibatuta badago, baliteke aplikazioak zuzen ez funtzionatzea eta programatutako alarmek ez jotzea."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Eman alarmak ezartzeko eta beste ekintza batzuk programatzeko baimena aplikazioari. Gailua erabili ez arren, agian aplikazioak martxan jarraituko du, eta bateria gehiago erabiliko. Baimena desaktibatuta badago, baliteke aplikazioak zuzen ez funtzionatzea eta programatutako alarmek ez jotzea."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Eman alarmak ezartzeko eta denbora-muga duten ekintzak programatzeko baimena aplikazioari. Hala, aplikazioak atzeko planoan funtzionatuko du, eta litekeena da bateria gehiago kontsumitzea.\n\nEz baduzu ematen baimen hori, ez dute funtzionatuko aplikazio honen bidez programatutako alarmek eta denbora-muga duten ekintzek."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programazioa, alarma, abisua, erlojua"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktibatu"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu ez molestatzeko modua"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 00a18d363ec4..92e624dcaf71 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"نمایش مرزها، حاشیه‌ها و ویژگی‌های دیگر کلیپ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"اجباری کردن چیدمان راست‌چین"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"اجباری کردن چیدمان راست‌چین صفحه برای همه زبان‌ها"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"محو کردن در سطح پنجره"</string>
<string name="force_msaa" msgid="4081288296137775550">"‏اجبار 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"‏فعال کردن 4X MSAA در برنامه‌های OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"اشکال‌زدایی عملکردهای کلیپ غیرمربعی"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"زنگ‌های هشدار و یادآوری‌ها"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"مجاز کردن تنظیم زنگ ساعت و یادآوری"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"زنگ‌های ساعت و یادآوری‌ها"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"به این برنامه اجازه داده می‌شود که زنگ ساعت تنظیم کند و کنش‌های دیگر را زمان‌بندی کند. ممکن است از این برنامه زمانی استفاده شود که از تلفنتان استفاده نمی‌کنید؛ این موضوع شاید موجب مصرف شارژ بیشتری شود. اگر این اجازه خاموش باشد، ممکن است این برنامه به‌درستی کار نکند، و زنگ‌های ساعت آن طبق زمان‌بندی کار نخواهد کرد."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"به این برنامه اجازه داده می‌شود که زنگ ساعت تنظیم کند و کنش‌های دیگر را زمان‌بندی کند. ممکن است از این برنامه زمانی استفاده شود که از رایانه لوحی‌تان استفاده نمی‌کنید؛ این موضوع شاید موجب مصرف شارژ بیشتری شود. اگر این اجازه خاموش باشد، ممکن است این برنامه به‌درستی کار نکند، و زنگ‌های ساعت آن طبق زمان‌بندی کار نخواهد کرد."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"به این برنامه اجازه داده می‌شود که زنگ ساعت تنظیم کند و کنش‌های دیگر را زمان‌بندی کند. ممکن است از این برنامه زمانی استفاده شود که از دستگاهتان استفاده نمی‌کنید؛ این موضوع شاید موجب مصرف شارژ بیشتری شود. اگر این اجازه خاموش باشد، ممکن است این برنامه به‌درستی کار نکند، و زنگ‌های ساعت آن طبق زمان‌بندی کار نخواهد کرد."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"به این برنامه اجازه می‌دهد زنگ ساعت تنظیم کند و کنش‌های حساس به زمان زمان‌بندی کند. این تنظیم به برنامه اجازه می‌دهد در پس‌زمینه اجرا شود که ممکن است باتری بیشتری مصرف کند.\n\nاگر این اجازه خاموش باشد، زنگ‌های ساعت موجود و رویدادهای مبتنی بر زمان که این برنامه زمان‌بندی کرده است کار نخواهند کرد."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"زمان‌بندی، زنگ ساعت، یادآوری، ساعت"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"روشن کردن"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"روشن کردن «مزاحم نشوید»"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index b3187a53ae94..11bcb3a36b06 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Näytä leikkeiden rajat, marginaalit jne."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Pakota RTL-ulkoasun suunta"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Pakota kaikkien kielten näytön ulkoasun suunnaksi RTL"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Salli ikkunoiden sumennus"</string>
<string name="force_msaa" msgid="4081288296137775550">"Pakota 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ota käyttöön 4x MSAA OpenGL ES 2.0 -sovelluksissa"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Korjaa ei-suorakulmaisten leiketoimintojen virheet"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Herätykset ja muistutukset"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Salli herätysten ja muistutusten lisääminen"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Herätykset ja muistutukset"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Salli sovelluksen lisätä herätyksiä ja ajoittaa muita toimintoja. Sovellus voi olla käytössä, vaikka et käyttäisi puhelintasi, mikä voi kuluttaa enemmän virtaa. Ilman tätä lupaa sovellus ei välttämättä toimi normaalisti, eivätkä sen herätykset toimi aikataulun mukaisesti."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Salli sovelluksen lisätä herätyksiä ja ajoittaa muita toimintoja. Sovellus voi olla käytössä, vaikka et käyttäisi tablettiasi, mikä voi kuluttaa enemmän virtaa. Ilman tätä lupaa sovellus ei välttämättä toimi normaalisti, eivätkä sen herätykset toimi aikataulun mukaisesti."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Salli sovelluksen lisätä herätyksiä ja ajoittaa muita toimintoja. Sovellus voi olla käytössä, vaikka et käyttäisi laitettasi, mikä voi kuluttaa enemmän virtaa. Ilman tätä lupaa sovellus ei välttämättä toimi normaalisti, eivätkä sen herätykset toimi aikataulun mukaisesti."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajoitus, herätys, muistutus, kello"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ota käyttöön"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ota Älä häiritse ‑tila käyttöön"</string>
@@ -579,7 +577,7 @@
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Laitteesi on käynnistettävä uudelleen, jotta muutos tulee voimaan. Käynnistä uudelleen nyt tai peru."</string>
<string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Langalliset kuulokkeet"</string>
<string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Päällä"</string>
- <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Poissa päältä"</string>
+ <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Ei käytössä"</string>
<string name="carrier_network_change_mode" msgid="4257621815706644026">"Operaattorin verkko muuttuu"</string>
<string name="data_connection_3g" msgid="931852552688157407">"3G"</string>
<string name="data_connection_edge" msgid="4625509456544797637">"EDGE"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index b7851656362f..a622385a652a 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Afficher les limites, les marges de clip, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forcer droite à gauche"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forcer l\'orientation droite à gauche (toutes langues)"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Autoriser le flou au niveau des fenêtres"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forcer MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applications OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Déboguer opérations de découpage non rectangulaire"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autoriser la création d\'alarmes et de rappels"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Autorisez cette application à créer des alarmes et à programmer d\'autres actions. Cette application pourrait continuer de fonctionner lorsque vous n\'utilisez pas votre téléphone, ce qui pourrait solliciter davantage la pile. Si l\'autorisation est désactivée, l\'application pourrait ne pas fonctionner normalement et ses alarmes ne se déclencheront pas aux heures prévues."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Autorisez cette application à créer des alarmes et à programmer d\'autres actions. Cette application pourrait continuer de fonctionner lorsque vous n\'utilisez pas votre tablette, ce qui pourrait solliciter davantage la pile. Si l\'autorisation est désactivée, l\'application pourrait ne pas fonctionner normalement et ses alarmes ne se déclencheront pas aux heures prévues."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Autorisez cette application à créer des alarmes et à programmer d\'autres actions. Cette application pourrait continuer de fonctionner lorsque vous n\'utilisez pas votre appareil, ce qui pourrait solliciter davantage la pile. Si l\'autorisation est désactivée, l\'application pourrait ne pas fonctionner normalement et ses alarmes ne se déclencheront pas aux heures prévues."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette application à créer des alarmes et à programmer des actions urgentes. Cela permet à l’application de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette application ne fonctionneront pas."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"horaire, alarme, rappel, horloge"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 52c4ec29d914..c4797fc33b7b 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Afficher les limites de coupe, les marges, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forcer écriture droite à gauche"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forcer l\'orientation du texte de droite à gauche pour toutes les langues"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Autor. floutage fenêtre"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forcer MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applications OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Déboguer découpage non rectangulaire"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autoriser à définir des alarmes et des rappels"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Autoriser cette appli à définir des alarmes et à programmer d\'autres actions. Cette appli peut être utilisée quand vous n\'utilisez pas votre téléphone, ce qui peut consommer davantage de batterie. Si cette autorisation est désactivée, l\'appli peut ne pas fonctionner correctement, et les alarmes définies ne se déclencheront pas comme prévu."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Autoriser cette appli à définir des alarmes et à programmer d\'autres actions. Cette appli peut être utilisée lorsque vous n\'utilisez pas votre tablette, ce qui peut consommer davantage de batterie. Si cette autorisation est désactivée, l\'appli peut ne pas fonctionner correctement, et les alarmes définies ne se déclencheront pas comme prévu."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Autoriser cette appli à définir des alarmes et à programmer d\'autres actions. Cette appli peut être utilisée quand vous n\'utilisez pas votre appareil, ce qui peut consommer davantage de batterie. Si cette autorisation est désactivée, l\'appli peut ne pas fonctionner correctement, et les alarmes définies ne se déclencheront pas comme prévu."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à définir des alarmes et à planifier des actions soumises à un délai. Cela lui permet de s\'exécuter en arrière-plan, ce qui peut consommer plus de batterie.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements basés sur l\'heure planifiés par cette appli ne fonctionneront pas."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"définir, alarme, rappel, horloge"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 037a9a972fb7..0d009de170ce 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -211,7 +211,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración de erros ao conectarse á wifi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Produciuse un erro"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración sen fíos"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar os dispositivos dispoñibles, activa a depuración sen fíos"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar os dispositivos dispoñibles, activa a depuración sen fíos."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincular o dispositivo cun código QR"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincula dispositivos novos mediante un escáner de códigos QR"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular o dispositivo co código de vinculación"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra os límites dos clips, as marxes etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección do deseño RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forza a dirección de pantalla a RTL (dereita a esquerda) para todas as configuración rexionais"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permitir desenfoque ventá"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activa MSAA 4x en aplicacións OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar accións recorte non rectangulares"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas e recordatorios"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permitir axuste de alarmas e recordatorios"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas e recordatorios"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permite que esta aplicación defina alarmas e planifique outras accións. Pode usarse cando non utilices o teléfono, o cal consome máis batería. Se este permiso está desactivado, é posible que a aplicación non funcione con normalidade e que as alarmas non se activen segundo o planificado."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permite que esta aplicación defina alarmas e planifique outras accións. Pode usarse cando non utilices a tableta, o cal consome máis batería. Se este permiso está desactivado, é posible que a aplicación non funcione con normalidade e que as alarmas non se activen segundo o planificado."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permite que esta aplicación defina alarmas e planifique outras accións. Pode usarse cando non utilices o dispositivo, o cal consome máis batería. Se este permiso está desactivado, é posible que a aplicación non funcione con normalidade e que as alarmas non se activen segundo o planificado."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planificar, alarma, recordatorio, reloxo"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar modo Non molestar"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 6aaa23ef9913..b8d8f3597176 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ક્લિપ બાઉન્ડ, હાંસિયાં વગેરે બતાવો."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL લેઆઉટ દિશા નિર્દેશની ફરજ પાડો"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"તમામ લૉકેલ માટે સ્ક્રીન લેઆઉટ દિશા નિર્દેશને RTLની ફરજ પાડો"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"વિન્ડો-લેવલને ઝાંખું કરવાની સુવિધા ચાલુ કરો"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAAને ફરજ પાડો"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ઍપમાં 4x MSAA ચાલુ કરો"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"બિન-લંબચોરસ ક્લિપ કામગીરી ડીબગ કરો"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"અલાર્મ અને રિમાઇન્ડર"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"અલાર્મ અને રિમાન્ડરના સેટિંગની મંજૂરી આપો"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"અલાર્મ અને રિમાઇન્ડર"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"આ ઍપને અલાર્મ સેટ કરવા અને અન્ય ક્રિયાઓ શેડ્યૂલ કરવા માટે મંજૂરી આપો. જ્યારે તમે તમારા ફોનનો ઉપયોગ ન કરતા હો, ત્યારે આ ઍપનો ઉપયોગ થઈ શકે છે, જેમાં વધારે બૅટરી વપરાઈ શકે છે. જો આ પરવાનગી બંધ હોય, તો આ ઍપ સામાન્ય રીતે કાર્ય ન પણ કરી શકે અને તેના અલાર્મ શેડ્યૂલ કર્યા મુજબ કાર્ય ન પણ કરે."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"આ ઍપને અલાર્મ સેટ કરવા અને અન્ય ક્રિયાઓ શેડ્યૂલ કરવા માટે મંજૂરી આપો. જ્યારે તમે તમારા ટૅબ્લેટનો ઉપયોગ ન કરતા હો, ત્યારે આ ઍપનો ઉપયોગ થઈ શકે છે, જેમાં વધારે બૅટરી વપરાઈ શકે છે. જો આ પરવાનગી બંધ હોય, તો આ ઍપ સામાન્ય રીતે કાર્ય ન પણ કરી શકે અને તેના અલાર્મ શેડ્યૂલ કર્યા મુજબ કાર્ય ન પણ કરે."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"આ ઍપને અલાર્મ સેટ કરવા અને અન્ય ક્રિયાઓ શેડ્યૂલ કરવા માટે મંજૂરી આપો. જ્યારે તમે તમારા ડિવાઇસનો ઉપયોગ ન કરતા હો, ત્યારે આ ઍપનો ઉપયોગ થઈ શકે છે, જેમાં વધારે બૅટરી વપરાઈ શકે છે. જો આ પરવાનગી બંધ હોય, તો આ ઍપ સામાન્ય રીતે કાર્ય ન પણ કરી શકે અને તેના અલાર્મ શેડ્યૂલ કર્યા મુજબ કાર્ય ન પણ કરે."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"શેડ્યૂલ, અલાર્મ, રિમાઇન્ડર, ઘડિયાળ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ચાલુ કરો"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ખલેલ પાડશો નહીં ચાલુ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index b6ac9597776f..8abbfcf74094 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -94,7 +94,7 @@
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम ऐक्सेस"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"एचडी ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"एचडी ऑडियो"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"सुनने में मदद करने वाले डिवाइस"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"कान की मशीन"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"सुनने में मदद करने वाले डिवाइस से कनेक्ट है"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मीडिया ऑडियो से कनेक्‍ट किया गया"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"फ़ोन ऑडियो से कनेक्‍ट किया गया"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमाएं, मार्जिन वगैरह दिखाएं."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"लेआउट की दिशा दाएं से बाएं करें"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"सभी भाषाओं के लिए स्क्रीन लेआउट की दिशा दाएं से बाएं रखें"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"विंडो को धुंधला करने की सुविधा चालू करें"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA को हर हाल में चालू करें"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ऐप में 4x MSAA को चालू करें"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"उन क्लिप ऑपरेशन को डीबग करें, जो आयताकार नहीं हैं"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म और रिमाइंडर"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म और रिमाइंडर सेट करने की अनुमति दें"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म और रिमाइंडर"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"इस ऐप्लिकेशन को अनुमति दें कि यह अलार्म सेट कर सके और दूसरी कार्रवाइयां शेड्यूल कर सके. इस ऐप्लिकेशन का इस्तेमाल तब भी किया जा सकता है, जब आप अपने फ़ोन का इस्तेमाल नहीं कर रहे होते. इससे बैटरी ज़्यादा खर्च हो सकती है. अगर आप यह अनुमति नहीं देते हैं, तो हो सकता है कि यह ऐप्लिकेशन ठीक तरह से काम न करे. साथ ही, इसमें शेड्यूल किए गए अलार्म भी नहीं बजेंगे."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"इस ऐप्लिकेशन को अनुमति दें कि यह अलार्म सेट कर सके और दूसरी कार्रवाइयां शेड्यूल कर सके. इस ऐप्लिकेशन का इस्तेमाल तब भी किया जा सकता है, जब आप अपने टैबलेट का इस्तेमाल नहीं कर रहे होते. इससे बैटरी ज़्यादा खर्च हो सकती है. अगर आप यह अनुमति नहीं देते हैं, तो हो सकता है कि यह ऐप्लिकेशन ठीक तरह से काम न करे. साथ ही, इसमें शेड्यूल किए गए अलार्म भी नहीं बजेंगे."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"इस ऐप्लिकेशन को अनुमति दें कि यह अलार्म सेट कर सके और दूसरी कार्रवाइयां शेड्यूल कर सके. इस ऐप्लिकेशन का इस्तेमाल तब भी किया जा सकता है, जब आप अपने डिवाइस का इस्तेमाल नहीं कर रहे होते. इससे बैटरी ज़्यादा खर्च हो सकती है. अगर आप यह अनुमति नहीं देते हैं, तो हो सकता है कि यह ऐप्लिकेशन ठीक तरह से काम न करे. साथ ही, इसमें शेड्यूल किए गए अलार्म भी नहीं बजेंगे."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे, बैटरी ज़्यादा खर्च होती है.\n\nअगर आप यह अनुमति नहीं देते हैं, तो इस ऐप्लिकेशन की मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्यूल, अलार्म, रिमाइंडर, घड़ी"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करें"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'परेशान न करें\' चालू करें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ac074b0d5d1c..217ff15ef20d 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Prikazuju se obrubi, margine itd. isječaka."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Nametni zdesna ulijevo"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nametni smjer zdesna ulijevo za sve zemlje/jezike"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Dopusti zamućenja na razini prozora"</string>
<string name="force_msaa" msgid="4081288296137775550">"Nametni 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Omogući 4x MSAA u aplikacijama OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Otkloni pogreške operacija nepravokutnog isječka"</string>
@@ -509,9 +508,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsjetnici"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Dopusti postavljanje alarma i podsjetnika"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Aplikaciji omogućuje da postavlja alarme i zakazuje druge radnje. Aplikacija se može koristiti kad ne upotrebljavate telefon, što može dodatno trošiti bateriju. Ako je to dopuštenje isključeno, aplikacija možda neće funkcionirati kako treba i njezini se alarmi neće oglašavati prema rasporedu."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Aplikaciji omogućuje da postavlja alarme i zakazuje druge radnje. Aplikacija se može koristiti kad ne upotrebljavate tablet, što može dodatno trošiti bateriju. Ako je to dopuštenje isključeno, aplikacija možda neće funkcionirati kako treba i njezini se alarmi neće oglašavati prema rasporedu."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Aplikaciji omogućuje da postavlja alarme i zakazuje druge radnje. Aplikacija se može koristiti kad ne upotrebljavate uređaj, što može dodatno trošiti bateriju. Ako je to dopuštenje isključeno, aplikacija možda neće funkcionirati kako treba i njezini se alarmi neće oglašavati prema rasporedu."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Aplikaciji omogućuje da postavlja alarme i zakazuje vremenski osjetljive radnje. To aplikaciji omogućuje da se izvodi u pozadini, pa je moguće dodatno trošenje baterije.\n\nAko je to dopuštenje isključeno, postojeći alarmi i događaji temeljeni na vremenu koji su zakazani putem ove aplikacije neće funkcionirati."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite opciju Ne uznemiravaj."</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 3377c456572a..e75b0ddf5b17 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Kliphatárok, margók stb. megjelenítése."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Elrendezés jobbról balra"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Elrendezés jobbról balra minden nyelvnél"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Ablakszintű homályosítás"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA kényszerítése"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"A 4x MSAA engedélyezése az OpenGL ES 2.0-nál"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Nem négyzetes kivágási műveletek hibakeresése"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ébresztések és emlékeztetők"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Beállíthat ébresztéseket és emlékeztetőket"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ébresztések és emlékeztetők"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Engedélyezheti ennek az alkalmazásnak, hogy ébresztéseket állítson be és további műveleteket ütemezzen. Ez az alkalmazás használatban lehet, amikor nem használja a telefonját, ami jobban igénybe veheti az akkumulátort. Ha ez az engedély ki van kapcsolva, előfordulhat, hogy az alkalmazás nem működik megfelelően, és az ébresztések nem működnek az ütemezésnek megfelelően."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Engedélyezheti ennek az alkalmazásnak, hogy ébresztéseket állítson be és további műveleteket ütemezzen. Ez az alkalmazás használatban lehet, amikor nem használja a táblagépét, ami jobban igénybe veheti az akkumulátort. Ha ez az engedély ki van kapcsolva, előfordulhat, hogy az alkalmazás nem működik megfelelően, és az ébresztések nem működnek az ütemezésnek megfelelően."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Engedélyezheti ennek az alkalmazásnak, hogy ébresztéseket állítson be és további műveleteket ütemezzen. Ez az alkalmazás használatban lehet, amikor nem használja az eszközét, ami jobban igénybe veheti az akkumulátort. Ha ez az engedély ki van kapcsolva, előfordulhat, hogy az alkalmazás nem működik megfelelően, és az ébresztések nem működnek az ütemezésnek megfelelően."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lehetővé teszi ennek az alkalmazásnak, hogy ébresztéseket állítson be és időérzékeny feladatokat ütemezzen. Ezzel engedélyezi az alkalmazásnak, hogy a háttérben fusson, ami megnövekedett akkumulátorhasználattal járhat.\n\nHa ez az engedély ki van kapcsolva, az alkalmazás által beállított ébresztések és ütemezett időérzékeny események nem fognak működni."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ütemezés, ébresztés, emlékeztető, óra"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bekapcsolás"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"A Ne zavarjanak mód bekapcsolása"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 5f6c1a298958..44b322d0b2da 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -212,9 +212,9 @@
<string name="adb_wireless_error" msgid="721958772149779856">"Սխալ"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Անլար վրիպազերծում"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Հասանելի սարքերը տեսնելու և օգտագործելու համար միացրեք անլար վրիպազերծումը"</string>
- <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Զուգակցեք սարքը՝ օգտագործելով QR կոդը"</string>
+ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Զուգակցել սարքը QR կոդով"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Զուգակցեք նոր սարքեր՝ օգտագործելով QR կոդերի սկաները"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Զուգակցեք սարքը՝ օգտագործելով զուգակցման կոդը"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Զուգակցել սարքը զուգակցման կոդով"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Զուգակցեք նոր սարքեր՝ օգտագործելով վեցանիշ կոդը"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Զուգակցված սարքեր"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Միացված է"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Ցույց տալ կտրվածքի սահմանները, լուսանցքները և այլն"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Ուղղությունը դարձնել RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Բոլոր լեզուների համար էկրանի տեքստի ուղղությունը դարձնել աջից ձախ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Շաղում պատուհանի մակարդակում"</string>
<string name="force_msaa" msgid="4081288296137775550">"Ստիպել 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Միացնել 4x MSAA-ը OpenGL ES 2.0 հավելվածներում"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Վրիպազերծել ոչ ուղղանկյուն կտրումների գործողությունները"</string>
@@ -506,11 +505,9 @@
<string name="cancel" msgid="5665114069455378395">"Չեղարկել"</string>
<string name="okay" msgid="949938843324579502">"Եղավ"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Զարթուցիչներ և հիշեցումներ"</string>
- <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Թույլատրել զարթուցիչների/հիշեցումների կարգավորումը"</string>
+ <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Թույլատրել զարթուցիչների և հիշեցումների սահմանումը"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Զարթուցիչներ և հիշեցումներ"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Թույլ տվեք այս հավելվածին կարգավորել զարթուցիչներ և պլանավորել այլ գործողություններ։ Այս հավելվածը կարող է օգտագործվել այն ժամանակ, երբ դուք չեք օգտվում ձեր հեռախոսից, ինչը կարող է արագացնել մարտկոցի լիցքի սպառումը։ Եթե այս թույլտվությունն անջատված է, այս գործառույթը կարող է պատշաճ չաշխատել, իսկ զարթուցիչները պլանավորված ժամերին չեն աշխատի։"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Թույլ տվեք այս հավելվածին կարգավորել զարթուցիչներ և պլանավորել այլ գործողություններ։ Այս հավելվածը կարող է օգտագործվել այն ժամանակ, երբ դուք չեք օգտվում ձեր պլանշետից, ինչը կարող է արագացնել մարտկոցի լիցքի սպառումը։ Եթե այս թույլտվությունն անջատված է, այս գործառույթը կարող է պատշաճ չաշխատել, իսկ զարթուցիչները պլանավորված ժամերին չեն աշխատի։"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Թույլ տվեք այս հավելվածին կարգավորել զարթուցիչներ և պլանավորել այլ գործողություններ։ Այս հավելվածը կարող է օգտագործվել այն ժամանակ, երբ դուք չեք օգտվում ձեր սարքից, ինչը կարող է արագացնել մարտկոցի լիցքի սպառումը։ Եթե այս թույլտվությունն անջատված է, այս գործառույթը կարող է պատշաճ չաշխատել, իսկ զարթուցիչները պլանավորված ժամերին չեն աշխատի։"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Թույլատրեք այս հավելվածին դնել զարթուցիչներ և ստեղծել գործողությունների կատարման ժամանակացույցներ։ Այդպես հավելվածը կկարողանա աշխատել ֆոնային ռեժիմում, ինչի արդյունքում ավելի շատ մարտկոցի լիցք կսպառվի։\n\nԵթե այս թույլտվությունն անջատված է, հավելվածի կողմից կարգավորված զարթուցիչները և միջոցառումների ժամանակացույցները չեն աշխատի։"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ժամանակացույց, զարթուցիչ, հիշեցում, ժամացույց"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 9f7b1f06d3cc..4bb472417c1a 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Tampilkan batas klip, margin, dll."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Paksa arah tata letak RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Paksa arah tata letak layar RTL untuk semua lokal"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Izinkan buram level jendela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Paksa 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktifkan 4x MSAA dalam aplikasi OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Debug operasi klip non-kotak"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarm dan pengingat"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Izinkan menyetel alarm dan pengingat"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarm &amp; pengingat"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Izinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan lainnya. Aplikasi ini dapat digunakan saat Anda tidak menggunakan ponsel, sehingga mungkin memerlukan daya baterai lebih besar. Jika izin ini dinonaktifkan, aplikasi mungkin tidak berfungsi normal dan alarmnya tidak bekerja sesuai yang dijadwalkan."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Izinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan lainnya. Aplikasi ini dapat digunakan saat Anda tidak menggunakan tablet, sehingga mungkin memerlukan daya baterai lebih besar. Jika izin ini dinonaktifkan, aplikasi mungkin tidak berfungsi normal dan alarmnya tidak bekerja sesuai yang dijadwalkan."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Izinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan lainnya. Aplikasi ini dapat digunakan saat Anda tidak menggunakan perangkat, sehingga mungkin memerlukan daya baterai lebih besar. Jika izin ini dinonaktifkan, aplikasi mungkin tidak berfungsi normal dan alarmnya tidak bekerja sesuai yang dijadwalkan."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Izinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan berjangka waktu. Hal ini memungkinkan aplikasi berjalan di latar belakang, sehingga mungkin menggunakan lebih banyak daya baterai.\n\nJika izin ini dinonaktifkan, alarm dan acara berjangka waktu yang dijadwalkan oleh aplikasi ini tidak akan berfungsi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadwal, alarm, pengingat, jam"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktifkan"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktifkan mode Jangan Ganggu"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index c972a996fb5e..b224330064db 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Sýna skurðlínur, spássíur o.s.frv."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Þvinga umbrot frá hægri til vinstri"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Þvinga umbrot skjás frá hægri til vinstri fyrir alla tungumálskóða"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Leyfa að gera glugga ósk."</string>
<string name="force_msaa" msgid="4081288296137775550">"Þvinga 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Virkja 4x MSAA í OpenGL ES 2.0 forritum"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Villuleita klippt svæði sem ekki eru rétthyrnd"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Vekjarar og áminningar"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Leyfa stillingu vekjara og áminninga"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Vekjarar og áminningar"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Leyfa þessu forriti að stilla vekjara og tímasetja aðrar aðgerðir. Mögulegt er að þetta forrit verði notað þegar þú ert ekki að nota símann og því gæti rafhlaðan tæmst hraðar. Ef slökkt er á þessari heimild er óvíst að forritið starfi sem skyldi og vekjarar munu ekki fylgja áætlun."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Leyfa þessu forriti að stilla vekjara og tímasetja aðrar aðgerðir. Mögulegt er að þetta forrit verði notað þegar þú ert ekki að nota spjaldtölvuna og því gæti rafhlaðan tæmst hraðar. Ef slökkt er á þessari heimild er óvíst að forritið starfi sem skyldi og vekjarar munu ekki fylgja áætlun."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Leyfa þessu forriti að stilla vekjara og tímasetja aðrar aðgerðir. Mögulegt er að þetta forrit verði notað þegar þú ert ekki að nota tækið og því gæti rafhlaðan tæmst hraðar. Ef slökkt er á þessari heimild er óvíst að forritið starfi sem skyldi og vekjarar munu ekki fylgja áætlun."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"áætlun, vekjari, áminning, klukka"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Kveikja"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Kveikja á „Ónáðið ekki“"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 17b184a7f08c..1d2295c7a47a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -211,7 +211,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modalità debug in caso di connessione Wi-Fi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Errore"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Debug wireless"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Per trovare e utilizzare i dispositivi disponibili, attiva il debug wireless"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Per trovare e utilizzare i dispositivi disponibili, attiva il debug wireless."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Accoppia dispositivo con codice QR"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Accoppia i nuovi dispositivi utilizzando lo scanner di codici QR"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Accoppia dispositivo con codice di accoppiamento"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra limiti, margini dei clip e così via"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forza direzione layout RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Direzione layout schermo RTL per tutte le lingue"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Consenti sfocature finestre"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forza MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Attiva MSAA 4x in applicazioni OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Debug operazioni ritaglio non rettangolare"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Sveglie e promemoria"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Consenti l\'impostazione di sveglie e promemoria"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Sveglie e promemoria"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Consenti a questa app di impostare sveglie e programmare altre azioni. L\'app potrebbe essere in uso quando non utilizzi il telefono, comportando un consumo maggiore della batteria. Se questa autorizzazione è disattivata, l\'app potrebbe non funzionare normalmente e le relative sveglie potrebbero non avviarsi come programmato."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Consenti a questa app di impostare sveglie e programmare altre azioni. Utilizzare quest\'app quando non stai usando il tuo tablet potrebbe consumare più batteria. Se questa autorizzazione è disattivata, l\'app potrebbe non funzionare normalmente e le relative sveglie potrebbero non avviarsi come programmato."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Consenti a questa app di impostare sveglie e programmare altre azioni. Utilizzare quest\'app quando non stai usando il tuo dispositivo potrebbe consumare più batteria. Se questa autorizzazione è disattivata, l\'app potrebbe non funzionare normalmente e le relative sveglie potrebbero non avviarsi come programmato."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Consenti a questa app di impostare sveglie e programmare azioni per le quali il fattore temporale è decisivo. L\'app potrà essere eseguita in background, comportando un consumo maggiore della batteria.\n\nSe questa autorizzazione viene disattivata, le sveglie esistenti e gli eventi basati sull\'orario programmati da questa app non funzioneranno."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programmare, sveglia, promemoria, orologio"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Attiva"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Attiva Non disturbare"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 8e5649fbb6f4..5c894a1bab37 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"הצגת גבולות אזור, שוליים וכדומה"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"אילוץ כיוון פריסה מימין לשמאל"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"אילוץ של כיוון פריסת מסך מימין לשמאל עבור כל השפות בכל המקומות"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"אישור טשטושים ברמת החלון"</string>
<string name="force_msaa" msgid="4081288296137775550">"‏אילוץ הפעלת 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"‏הפעלת 4x MSAA ביישומי OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ניפוי באגים בפעולות באזור שאינו מלבני"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"שעונים מעוררים ותזכורות"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"אישור להגדיר שעונים מעוררים ותזכורות"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"שעונים מעוררים ותזכורות"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"ההגדרה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות אחרות. ייתכן שהאפליקציה תפעל גם כשלא נעשה שימוש בטלפון שלך, ולכן תגביר את צריכת הסוללה. אם ההרשאה הזו תושבת, יכול להיות שהאפליקציה לא תפעל כראוי ושהשעונים המעוררים לא יפעלו כפי שתוזמנו."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"ההגדרה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות אחרות. ייתכן שהאפליקציה תפעל גם כשלא נעשה שימוש בטאבלט שלך, ולכן תגביר את צריכת הסוללה. אם ההרשאה הזו תושבת, יכול להיות שהאפליקציה לא תפעל כראוי ושהשעונים המעוררים לא יפעלו כפי שתוזמנו."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"הגדרה זו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן אירועים אחרים. ייתכן שהאפליקציה תפעל גם כשלא נעשה שימוש במכשיר שלך, ולכן תגביר את צריכת הסוללה. אם ההרשאה הזו תושבת, ייתכן שהאפליקציה לא תפעל כראוי ושהשעונים המעוררים לא יפעלו כפי שתוזמנו."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ההגדרה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות דחופות. האפליקציה תוכל לפעול ברקע ובכך להגביר את צריכת הסוללה.\n\nאם ההרשאה מושבתת, ההתראות והאירועים מבוססי-הזמן שהוגדרו ותוזמנו על ידי האפליקציה לא יפעלו."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"תזמון, שעון מעורר, תזכורת, שעון"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"הפעלה"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"הפעלת מצב נא לא להפריע"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 62d887daf6b0..3f23c75eaf44 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -153,8 +153,8 @@
<string name="user_guest" msgid="6939192779649870792">"ゲスト"</string>
<string name="unknown" msgid="3544487229740637809">"不明"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"ユーザー: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
- <string name="launch_defaults_some" msgid="3631650616557252926">"一部デフォルトで設定"</string>
- <string name="launch_defaults_none" msgid="8049374306261262709">"デフォルトの設定なし"</string>
+ <string name="launch_defaults_some" msgid="3631650616557252926">"一部のリンクをデフォルトで開くよう設定済みです"</string>
+ <string name="launch_defaults_none" msgid="8049374306261262709">"デフォルトで開く対応リンクはありません"</string>
<string name="tts_settings" msgid="8130616705989351312">"テキスト読み上げの設定"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"テキスト読み上げの設定"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"音声の速度"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"クリップの境界線、マージンなどを表示"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTLレイアウト方向を使用"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"すべての言語/地域で画面レイアウト方向をRTLに設定"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ウィンドウ レベルでのぼかしを許可"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA を適用"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 アプリで 4x MSAA を有効にする"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"非矩形クリップ操作をデバッグ"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"アラームとリマインダー"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"アラームとリマインダーの設定を許可する"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"アラームとリマインダー"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"このアプリに、アラームの設定やその他のアクションのスケジュールを許可します。このアプリは、スマートフォンを使用していないときも使用される可能性があるため、バッテリーの使用量が増えることがあります。この権限が OFF の場合、このアプリは正常に機能しない可能性があり、アラームはスケジュールどおりに動作しません。"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"このアプリに、アラームの設定やその他のアクションのスケジュールを許可します。このアプリは、タブレットを使用していないときも使用される可能性があるため、バッテリーの使用量が増えることがあります。この権限が OFF の場合、このアプリは正常に機能しない可能性があり、アラームはスケジュールどおりに動作しません。"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"このアプリに、アラームの設定やその他のアクションのスケジュールを許可します。このアプリは、デバイスを使用していないときも使用される可能性があるため、バッテリーの使用量が増えることがあります。この権限が OFF の場合、このアプリは正常に機能しない可能性があり、アラームはスケジュールどおりに動作しません。"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"アラームの設定や時間の制約があるアクションのスケジュールを、このアプリに許可します。これによりアプリがバックグラウンドで実行できるようになるため、バッテリーの使用量が増えることがあります。\n\nこの権限が OFF の場合、このアプリで設定された既存のアラームと時間ベースのイベントは機能しなくなります。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"スケジュール, アラーム, リマインダー, 時計"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ON にする"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"サイレント モードを ON にする"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index f67d2b2521d5..472377196781 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"კლიპის საზღვრების, მინდვრების ჩვენება და ა.შ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"მარჯვნიდან მარცხნივ განლაგების მიმართულების იძულება"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ეკრანის RTL მიმართულებაზე იძულება ყველა ლოკალისათვის"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ფანჯრის დონეზე გაბუნდოვნების დაშვება"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA-ს ჩართვა"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA-ის ჩართვა OpenGL ES 2.0 აპში."</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"არა-მართკუთხა კლიპ-ოპერაციების გამართვა"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"მაღვიძარები და შეხსენებები"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"დაუშვით მაღვიძარების და შეხსენებების დაყენება"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"მაღვიძარები და შეხსენებები"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"საშუალება მიეცით ამ აპს, დააყენოს მაღვიძარა და დაგეგმოს სხვა მოქმედებები. ამ აპის გამოყენება შესაძლებელია მაშინაც, როცა ტელეფონს არ იყენებთ, რადგან ის მეტ ენერგიას ხარჯავს. თუ ეს ნებართვა გამორთულია, აპმა და მაღვიძარამ შეიძლება სათანადოდ ვერ იმუშაონ."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"საშუალება მიეცით ამ აპს, დააყენოს მაღვიძარა და დაგეგმოს სხვა მოქმედებები. ამ აპის გამოყენება შესაძლებელია მაშინაც, როცა ტაბლეტს არ იყენებთ, რადგან ის მეტ ენერგიას ხარჯავს. თუ ეს ნებართვა გამორთულია, აპმა და მაღვიძარამ შეიძლება სათანადოდ ვერ იმუშაონ."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"საშუალება მიეცით ამ აპს, დააყენოს მაღვიძარა და დაგეგმოს სხვა მოქმედებები. ამ აპის გამოყენება შესაძლებელია მაშინაც, როცა მოწყობილობას არ იყენებთ, რადგან ის მეტ ენერგიას ხარჯავს. თუ ეს ნებართვა გამორთულია, აპმა და მაღვიძარამ შეიძლება სათანადოდ ვერ იმუშაონ."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ნებას რთავს ამ აპს, დააყენოს მაღვიძარები და დაგეგმოს დროზე დამოკიდებული მოქმედებები. ეს საშუალებას აძლევს აპს, იმუშაოს ფონურად, რამაც შეიძლება ბატარეის ხარჯი გაზარდოს.\n\nთუ ეს ნებართვა გამორთულია, ამ აპით დაგეგმილი მაღვიძარები და დროზე დამოკიდებული მოვლენები არ იმუშავებს."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"განრიგი, მაღვიძარა, შეხსენება, საათი"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ჩართვა"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„არ შემაწუხოთ“ რეჟიმის ჩართვა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index be176cba4401..baae75b17073 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Қию шегін, шеттерді, т.б. көрсету"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Оңнан солға орналастыру"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Экранның орналасу бағытын барлық тілдер үшін оңнан солға қарату"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Терезе деңгейіндегі бұлдырлар"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA қолдану"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA функциясын OpenGL ES 2.0 қолданбаларында іске қосу"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Тіктөртбұрыштан басқа пішінге қиюды түзету"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Оятқыш және еске салғыш"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Оятқыштар мен еске салғыштарды орнатуға рұқсат беру"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Оятқыштар мен еске салғыштар"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Қолданбаға оятқыштарды орнатуға және басқа да әрекеттерді жоспарлауға рұқсат беру. Телефоныңыз қолданылмай тұрған кезде де бұл қолданба жұмыс істеуі және батарея шығынын арттыруы мүмкін. Егер бұл рұқсат өшірулі болса, қолданба дұрыс жұмыс істемеуі, оның оятқыштары жоспарланғандай іске қосылмауы мүмкін."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Қолданбаға оятқыштарды орнатуға және басқа да әрекеттерді жоспарлауға рұқсат беру. Планшетіңіз қолданылмай тұрған кезде де бұл қолданба жұмыс істеуі және батарея шығынын арттыруы мүмкін. Егер бұл рұқсат өшірулі болса, қолданба дұрыс жұмыс істемеуі, оның оятқыштары жоспарланғандай іске қосылмауы мүмкін."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Қолданбаға оятқыштарды орнатуға және басқа да әрекеттерді жоспарлауға рұқсат беру. Құрылғыңыз қолданылмай тұрған кезде де бұл қолданба жұмыс істеуі және батарея шығынын арттыруы мүмкін. Егер бұл рұқсат өшірулі болса, қолданба дұрыс жұмыс істемеуі, оның оятқыштары жоспарланғандай іске қосылмауы мүмкін."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бұл қолданбаға оятқыштарды орнатуға және уақытқа негізделген әрекеттерді жоспарлауға рұқсат береді. Мұндайда қолданба фондық режимде жұмыс істейді, сондықтан батарея шығыны артуы мүмкін.\n\nБұл рұқсат өшірулі болса, осы қолданбада жоспарланған ағымдағы оятқыштар мен уақытқа негізделген іс-шаралар жұмыс істемейді."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"кесте, оятқыш, еске салғыш, сағат"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Қосу"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Мазаламау режимін қосу"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 7e67b9b2b77f..fdbcba4aa1e7 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -156,7 +156,7 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"លំនាំដើមមួយចំនួនត្រូវបានកំណត់"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"គ្មានការកំណត់លំនាំដើម"</string>
<string name="tts_settings" msgid="8130616705989351312">"ការ​កំណត់​អត្ថបទ​ទៅ​ជា​កា​និយាយ"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"លទ្ធផល​នៃការបំប្លែងអត្ថបទទៅជាការនិយាយ"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"ធាតុចេញ​នៃការបំប្លែងអត្ថបទទៅជាការនិយាយ"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"អត្រា​និយាយ"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"ល្បឿន​ពេល​អាន​​អត្ថបទ"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"ឡើង​-ចុះ"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"បង្ហាញ​ការ​ភ្ជាប់​អត្ថបទ​សម្រង់ រឹម ។ល។"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"បង្ខំ​ទិស​ប្លង់ RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ប្តូរទិស​ប្លង់​អេក្រង់​ទៅជា RTL សម្រាប់​គ្រប់ភាសា​ទាំងអស់"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"អនុញ្ញាតភាពព្រាលកម្រិតវិនដូ"</string>
<string name="force_msaa" msgid="4081288296137775550">"បង្ខំ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"បើក 4x MSAA ក្នុង​កម្មវិធី OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"កែ​ប្រតិបត្តិការ​​​ផ្នែកដកចេញដែលមិនមាន​រាង​ចតុកោណកែង"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ម៉ោងរោទ៍ និងការរំលឹក"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"អនុញ្ញាតឱ្យ​កំណត់​ម៉ោងរោទ៍ និង​ការរំលឹក"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ម៉ោងរោទ៍ និង​ការរំលឹក"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និង​កំណត់កាលវិភាគ​សកម្មភាព​ផ្សេងទៀត​។ កម្មវិធីនេះ​អាចត្រូវបាន​ប្រើ នៅពេលដែល​អ្នកមិនកំពុងប្រើ​ទូរសព្ទ​របស់អ្នក។ សកម្មភាពនេះ​អាចនឹង​ប្រើប្រាស់ថ្ម​ច្រើនជាងមុន​។ ប្រសិនបើបិទ​ការអនុញ្ញាត​នេះ កម្មវិធីនេះ​មិនអាចដំណើរការ​តាមធម្មតា​ទេ ហើយម៉ោងរោទ៍​របស់វានឹង​មិនដំណើរការ​តាមកាលវិភាគឡើយ​។"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និង​កំណត់កាលវិភាគ​សកម្មភាព​ផ្សេងទៀត​។ កម្មវិធីនេះ​អាចត្រូវបាន​ប្រើ នៅពេលដែល​អ្នកមិនកំពុងប្រើ​ថេប្លេត​របស់អ្នក។ សកម្មភាពនេះ​អាចនឹង​ប្រើប្រាស់ថ្ម​ច្រើនជាងមុន​។ ប្រសិនបើបិទ​ការអនុញ្ញាត​នេះ កម្មវិធីនេះ​មិនអាចដំណើរការ​តាមធម្មតា​ទេ ហើយម៉ោងរោទ៍​របស់វានឹង​មិនដំណើរការ​តាមកាលវិភាគឡើយ​។"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និង​កំណត់កាលវិភាគ​សកម្មភាព​ផ្សេងទៀត​។ កម្មវិធីនេះ​អាចត្រូវបាន​ប្រើ នៅពេលដែល​អ្នកមិនកំពុងប្រើ​ឧបករណ៍​របស់អ្នក។ សកម្មភាពនេះ​អាចនឹង​ប្រើប្រាស់ថ្ម​ច្រើនជាងមុន​។ ប្រសិនបើបិទ​ការអនុញ្ញាត​នេះ កម្មវិធីនេះ​មិនអាចដំណើរការ​តាមធម្មតា​ទេ ហើយម៉ោងរោទ៍​របស់វានឹង​មិនដំណើរការ​តាមកាលវិភាគឡើយ​។"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ សកម្មភាពនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មច្រើន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកម្មវិធីនេះបានកំណត់កាលវិភាគនឹងមិនដំណើរការទេ។"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"កាលវិភាគ ម៉ោងរោទ៍ ការរំលឹក នាឡិកា"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"បើក"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"បើកមុខងារកុំរំខាន"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index fde4d7251004..21dce27988c6 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ಕ್ಲಿಪ್‌ನ ಗಡಿಗಳು, ಅಂಚುಗಳು, ಇತ್ಯಾದಿ ತೋರಿಸು."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL ಲೇಔಟ್‌ ಡೈರೆಕ್ಷನ್ ಫೋರ್ಸ್ ಮಾಡುವಿಕೆ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ಎಲ್ಲ ಭಾಷೆಗಳಿಗಾಗಿ, RTL ಗೆ ಸ್ಕ್ರೀನ್‌ ಲೇಔಟ್‌ ಡೈರೆಕ್ಷನ್ ಅನ್ನು ಫೋರ್ಸ್ ಮಾಡಿ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ವಿಂಡೋ-ಮಟ್ಟ ಬ್ಲರ್ ಅನುಮತಿಸಿ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ಫೋರ್ಸ್ ಮಾಡಿ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ 4x MSAA ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ಆಯತಾಕಾರವಲ್ಲದ ಕ್ಲಿಪ್ ಕಾರ್ಯಾಚರಣೆ ಡೀಬಗ್"</string>
@@ -390,7 +389,7 @@
<string name="loading_injected_setting_summary" msgid="8394446285689070348">"ಲೋಡ್ ಆಗುತ್ತಿದೆ…"</string>
<string-array name="color_mode_names">
<item msgid="3836559907767149216">"ಸ್ಪಂದನಾತ್ಮಕ (ಡೀಫಾಲ್ಟ್)"</item>
- <item msgid="9112200311983078311">"ಪ್ರಾಕೃತಿಕ"</item>
+ <item msgid="9112200311983078311">"ಸ್ವಾಭಾವಿಕ"</item>
<item msgid="6564241960833766170">"ಪ್ರಮಾಣಿತ"</item>
</string-array>
<string-array name="color_mode_descriptions">
@@ -467,8 +466,8 @@
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
<string name="disabled" msgid="8017887509554714950">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"ಅನುಮತಿಸಲಾಗಿದೆ"</string>
- <string name="external_source_untrusted" msgid="5037891688911672227">"ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
- <string name="install_other_apps" msgid="3232595082023199454">"ಅಪರಿಚಿತ ಆ್ಯಪ್‍‍ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
+ <string name="external_source_untrusted" msgid="5037891688911672227">"ಅನುಮತಿ ಇಲ್ಲ"</string>
+ <string name="install_other_apps" msgid="3232595082023199454">"ಅಪರಿಚಿತ ಆ್ಯಪ್‍‍ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
<string name="home" msgid="973834627243661438">"ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಮುಖಪುಟ"</string>
<string-array name="battery_labels">
<item msgid="7878690469765357158">"0%"</item>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ಅಲಾರಾಮ್‌ಗಳು ಮತ್ತು ರಿಮೈಂಡರ್‌ಗಳು"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ಅಲಾರಂಗಳು ಮತ್ತು ರಿಮೈಂಡರ್‌ಗಳನ್ನು ಹೊಂದಿಸಲು ಅನುಮತಿಸಿ"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ಅಲಾರಂಗಳು ಮತ್ತು ರಿಮೈಂಡರ್‌ಗಳು"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"ಅಲಾರಂ‌ಗಳನ್ನು ಹೊಂದಿಸಲು ಮತ್ತು ಇತರ ಕ್ರಿಯೆಗಳನ್ನು ನಿಗದಿಪಡಿಸಲು ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸಿ. ನಿಮ್ಮ ಫೋನ್ ಬಳಸದಿದ್ದಾಗ ಈ ಆ್ಯಪ್ ಅನ್ನು ಬಳಸಬಹುದು, ಅದು ಹೆಚ್ಚು ಬ್ಯಾಟರಿ ಬಳಸಬಹುದು. ಈ ಅನುಮತಿ ಆಫ್ ಆಗಿದ್ದರೆ, ಈ ಆ್ಯಪ್ ಸಾಮಾನ್ಯವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದೆ ಇರಬಹುದು ಮತ್ತು ಅದರ ಅಲಾರಂಗಳು ನಿಗದಿಯಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"ಅಲಾರಂ‌ಗಳನ್ನು ಹೊಂದಿಸಲು ಮತ್ತು ಇತರ ಕ್ರಿಯೆಗಳನ್ನು ನಿಗದಿಪಡಿಸಲು ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸಿ. ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಅನ್ನು ನೀವು ಬಳಸದಿದ್ದಾಗ ಈ ಆ್ಯಪ್ ಅನ್ನು ಬಳಸಬಹುದು, ಅದು ಹೆಚ್ಚಿನ ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸಬಹುದು. ಈ ಅನುಮತಿ ಆಫ್ ಆಗಿದ್ದರೆ, ಈ ಆ್ಯಪ್ ಸಾಮಾನ್ಯವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದೆ ಇರಬಹುದು ಮತ್ತು ಅದರ ಅಲಾರಂಗಳು ನಿಗದಿಯಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"ಅಲಾರಂ‌ಗಳನ್ನು ಹೊಂದಿಸಲು ಮತ್ತು ಇತರ ಕ್ರಿಯೆಗಳನ್ನು ನಿಗದಿಪಡಿಸಲು ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸಿ. ನಿಮ್ಮ ಸಾಧನವನ್ನು ನೀವು ಬಳಸದಿದ್ದಾಗ ಈ ಆ್ಯಪ್ ಅನ್ನು ಬಳಸಬಹುದು, ಅದು ಹೆಚ್ಚಿನ ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸಬಹುದು. ಈ ಅನುಮತಿ ಆಫ್ ಆಗಿದ್ದರೆ, ಈ ಆ್ಯಪ್ ಸಾಮಾನ್ಯವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದೆ ಇರಬಹುದು ಮತ್ತು ಅದರ ಅಲಾರಂಗಳು ನಿಗದಿಯಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ವೇಳಾಪಟ್ಟಿ, ಅಲಾರಂ, ರಿಮೈಂಡರ್, ಗಡಿಯಾರ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ಆನ್ ಮಾಡಿ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
@@ -579,7 +577,7 @@
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ಈ ಬದಲಾವಣೆ ಅನ್ವಯವಾಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕು. ಇದೀಗ ರೀಬೂಟ್ ಮಾಡಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಿ."</string>
<string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ವೈಯರ್ ಹೊಂದಿರುವ ಹೆಡ್‌ಫೋನ್"</string>
<string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ಆನ್ ಆಗಿದೆ"</string>
- <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"ಆಫ್ ಆಗಿದೆ"</string>
+ <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"ಆಫ್"</string>
<string name="carrier_network_change_mode" msgid="4257621815706644026">"ವಾಹಕ ನೆಟ್‌ವರ್ಕ್ ಬದಲಾಯಿಸುವಿಕೆ"</string>
<string name="data_connection_3g" msgid="931852552688157407">"3G"</string>
<string name="data_connection_edge" msgid="4625509456544797637">"EDGE"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 2bedaa2109f4..6e6a5a76d766 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"클립 경계, 여백 등을 표시"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL 레이아웃 방향 강제 적용"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"모든 언어에 대해 화면 레이아웃 방향을 RTL로 강제 적용"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"창 수준 블러 허용"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA 강제 사용"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 앱에서 4x MSAA 사용"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"사각형이 아닌 클립 작업 디버그"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"알람 및 리마인더"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"알람 및 리마인더 설정 허용"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"알람 및 리마인더"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"앱에서 알람을 설정하고 다른 작업의 일정을 예약할 수 있도록 허용합니다. 휴대전화를 사용하지 않을 때 앱이 사용될 수 있으며 이로 인해 배터리 사용량이 증가할 수 있습니다. 이 권한을 사용 중지하면 앱이 정상 작동하지 않고 알람이 일정대로 실행되지 않을 수 있습니다."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"앱에서 알람을 설정하고 다른 작업의 일정을 예약할 수 있도록 허용합니다. 태블릿을 사용하지 않을 때 앱이 사용될 수 있으며 이로 인해 배터리 사용량이 증가할 수 있습니다. 이 권한을 사용 중지하면 앱이 정상 작동하지 않고 알람이 일정대로 실행되지 않을 수 있습니다."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"앱에서 알람을 설정하고 다른 작업의 일정을 예약할 수 있도록 허용합니다. 기기를 사용하지 않을 때 앱이 사용될 수 있으며 이로 인해 배터리 사용량이 증가할 수 있습니다. 이 권한을 사용 중지하면 앱이 정상 작동하지 않고 알람이 일정대로 실행되지 않을 수 있습니다."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"이 앱이 알람을 설정하고 시간 기반 작업을 예약할 수 있도록 허용합니다. 이렇게 하면 백그라운드에서 앱 실행이 허용되어 배터리 사용량이 증가할 수 있습니다.\n\n이 권한을 사용 중지하면 이 앱에서 예약한 기존의 알람 및 시간 기반 일정이 작동하지 않습니다."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"일정 예약, 알람, 리마인더, 시계"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"사용 설정"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"방해 금지 모드 사용 설정"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index c6086ad21124..140eb3bb1a30 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Кесилген нерсенин чектери жана жээктери көрүнөт"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Интерфейсти чагылдыруу"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Интерфейстин элементтери бардык тилдерде оңдон солго карай жайгашат"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Терезенин деңгээлинде бүдөмүктөтүүгө уруксат берүү"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA иштетүү"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 колдонмолорунда 4x MSAA иштетилет"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Татаал формаларды кесүү операцияларынын мүчүлүштүктөрүн оңдоо"</string>
@@ -484,7 +483,7 @@
<string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"Эң чоң"</string>
<string name="screen_zoom_summary_custom" msgid="3468154096832912210">"Ыңгайлаштырылган (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="content_description_menu_button" msgid="6254844309171779931">"Меню"</string>
- <string name="retail_demo_reset_message" msgid="5392824901108195463">"Демо режиминде демейки жөндөөлөргө кайтаруу үчүн сырсөздү киргизиңиз"</string>
+ <string name="retail_demo_reset_message" msgid="5392824901108195463">"Демо режиминде баштапкы абалга кайтаруу үчүн сырсөздү киргизиңиз"</string>
<string name="retail_demo_reset_next" msgid="3688129033843885362">"Кийинки"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"Сырсөз талап кылынат"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"Жигердүү киргизүү ыкмалары"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ойготкучтар жана эстеткичтер"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Ойготкуч жана эстеткичтерди коюуга уруксат берүү"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ойготкучтар жана эстеткичтер"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат берүү. Бул колдонмо телефонуңуз колдонулбай турганда да иштей алат. Мында батареянын кубаты көбүрөөк керектелиши мүмкүн. Бул параметр өчүрүлгөн болсо, бул колдонмо жана анын ойготкучтары жакшы иштебеши мүмкүн."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат берүү. Бул колдонмо планшетиңиз колдонулбай турганда да иштей алат. Мында батареянын кубаты көбүрөөк керектелиши мүмкүн. Бул параметр өчүрүлгөн болсо, бул колдонмо жана анын ойготкучтары жакшы иштебеши мүмкүн."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат берүү. Бул колдонмо түзмөгүңүз колдонулбай турганда да иштей алат. Мында батареянын кубаты көбүрөөк керектелиши мүмкүн. Бул параметр өчүрүлгөн болсо, бул колдонмо жана анын ойготкучтары жакшы иштебеши мүмкүн."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат берүү. Ушуну менен колдонмо фондо иштеп, батареяны көбүрөөк сарпташы мүмкүн.\n\nЭгер бул уруксат өчүрүлсө, колдонмодогу ойготкучтар жана графикке киргизилген башка аракеттер иштебейт."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, ойготкуч, эстеткич, саат"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Күйгүзүү"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Тынчымды алба\" режимин күйгүзүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 7eea529d5df1..f4962f94a09f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ສະແດງໜ້າປົກຄລິບ, ຂອບ ແລະ ອື່ນໆ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"ບັງ​ຄັບ​ໃຫ້ຮູບຮ່າງຂຽນຈາກຂວາຫາຊ້າຍ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ບັງຄັບໃຫ້ຮູບຮ່າງໜ້າຈໍ ຂຽນຈາກຂວາໄປຊ້າຍ ສຳລັບທຸກພາສາ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ອະນຸຍາດການມົວໃນລະດັບໜ້າຈໍ"</string>
<string name="force_msaa" msgid="4081288296137775550">"ບັງຄັບໃຊ້ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"ເປິດໃຊ້ 4x MSAA ໃນແອັບ OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ດີບັກການເຮັດວຽກຂອງຄລິບທີ່ບໍ່ແມ່ນສີ່ຫຼ່ຽມ"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ໂມງປຸກ ແລະ ການແຈ້ງເຕືອນ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ອະນຸຍາດໃຫ້ຕັ້ງໂມງປຸກ ແລະ ການແຈ້ງເຕືອນ"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ໂມງປຸກ ແລະ ການແຈ້ງເຕືອນ"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"ອະນຸຍາດໃຫ້ແອັບນີ້ຕັ້ງໂມງປຸກ ແລະ ກຳນົດເວລາຄຳສັ່ງອື່ນໆ. ແອັບນີ້ອາດຖືກໃຊ້ເມື່ອທ່ານບໍ່ໄດ້ກຳລັງໃຊ້ໂທລະສັບຂອງທ່ານຢູ່, ເຊິ່ງອາດໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ. ຫາກການອະນຸຍາດນີ້ຖືກປິດໄວ້, ແອັບນີ້ອາດບໍ່ສາມາດເຮັດວຽກໄດ້ຕາມປົກກະຕິ ແລະ ໂມງປຸກຂອງມັນອາດບໍ່ປຸກຕາມທີ່ກຳນົດເວລາໄວ້."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"ອະນຸຍາດໃຫ້ແອັບນີ້ຕັ້ງໂມງປຸກ ແລະ ກຳນົດເວລາຄຳສັ່ງອື່ນໆ. ແອັບນີ້ອາດຖືກໃຊ້ເມື່ອທ່ານບໍ່ໄດ້ກຳລັງໃຊ້ແທັບເລັດຂອງທ່ານຢູ່, ເຊິ່ງອາດໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ. ຫາກການອະນຸຍາດນີ້ຖືກປິດໄວ້, ແອັບນີ້ອາດບໍ່ສາມາດເຮັດວຽກໄດ້ຕາມປົກກະຕິ ແລະ ໂມງປຸກຂອງມັນອາດບໍ່ປຸກຕາມທີ່ກຳນົດເວລາໄວ້."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"ອະນຸຍາດໃຫ້ແອັບນີ້ຕັ້ງໂມງປຸກ ແລະ ກຳນົດເວລາຄຳສັ່ງອື່ນໆ. ແອັບນີ້ອາດຖືກໃຊ້ເມື່ອທ່ານບໍ່ໄດ້ກຳລັງໃຊ້ອຸປະກອນຂອງທ່ານຢູ່, ເຊິ່ງອາດໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ. ຫາກການອະນຸຍາດນີ້ຖືກປິດໄວ້, ແອັບນີ້ອາດບໍ່ສາມາດເຮັດວຽກໄດ້ຕາມປົກກະຕິ ແລະ ໂມງປຸກຂອງມັນອາດບໍ່ປຸກຕາມທີ່ກຳນົດເວລາໄວ້."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ກຳນົດເວລາ, ໂມງປຸກ, ການແຈ້ງເຕືອນ, ໂມງ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ເປີດ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ເປີດໂໝດຫ້າມລົບກວນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 79e487037db8..e920b31ea633 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Rodyti iškarpų ribas, kraštines ir t. t."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Išdėst. iš dešin. į kairę"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nust. visų lokalių ekran. išdėst. iš deš. į kairę"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Leisti lango suliejimus"</string>
<string name="force_msaa" msgid="4081288296137775550">"Priverst. vykdyti 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Įgalinti 4x MSAA „OpenGL ES 2.0“ programose"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Derinti ne stačiakampio klipo operacijas"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Signalai ir priminimai"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Leisti nustatyti signalus ir priminimus"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signalai ir priminimai"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Leiskite šiai programai nustatyti signalus ir suplanuoti kitus veiksmus. Ši programa gali būti naudojama, kai nenaudojate telefono, todėl gali būti išeikvojama daugiau akumuliatoriaus energijos. Jei šis leidimas išjungtas, ši programa gali tinkamai neveikti ir jos signalai neveiks, kaip suplanuota."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Leiskite šiai programai nustatyti signalus ir suplanuoti kitus veiksmus. Ši programa gali būti naudojama, kai nenaudojate planšetinio kompiuterio, todėl gali būti išeikvojama daugiau akumuliatoriaus energijos. Jei šis leidimas išjungtas, ši programa gali tinkamai neveikti ir jos signalai neveiks, kaip suplanuota."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Leiskite šiai programai nustatyti signalus ir suplanuoti kitus veiksmus. Ši programa gali būti naudojama, kai nenaudojate įrenginio, todėl gali būti išeikvojama daugiau akumuliatoriaus energijos. Jei šis leidimas išjungtas, ši programa gali tinkamai neveikti ir jos signalai neveiks, kaip suplanuota."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leisti šiai programai nustatyti signalus ir suplanuoti veiksmus, kuriems svarbus laiko veiksnys. Dėl to programa gali veikti fone ir sunaudoti daugiau akumuliatoriaus energijos.\n\nJei šis leidimas išjungtas, šios programos suplanuoti esami signalai ir laiku pagrįsti įvykiai neveiks."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tvarkaraštis, signalas, priminimas, laikrodis"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Įjungti"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Netrukdymo režimo įjungimas"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 7f56aad98c17..c43d879a9d2c 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Rādīt klipu robežas, malas utt."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Virziens no labās uz kreiso (Obligāts) WL: 295"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Obl. izkārt. virz. no labās uz kr. pusi visām lok."</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Atļaut logu aizmiglošanu"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA piespiedu palaiš."</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Iespējot 4x MSAA OpenGL ES 2.0 lietotnēs"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Atkļūdot darbības daļā, kas nav taisnstūris."</string>
@@ -509,9 +508,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Signāli un atgādinājumi"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Atļaut iestatīt signālus un atgādinājumus"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signāli un atgādinājumi"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Atļaut šai lietotnei iestatīt signālus un ieplānot citas darbības. Šī lietotne var tikt izmantota, kamēr jūs neizmantojat tālruni, tāpēc var tikt patērēts vairāk akumulatora enerģijas. Ja šī atļauja ir izslēgta, šī lietotne var nedarboties, kā paredzēts, un tās signāli netiek rādīti ieplānotajā laikā."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Atļaut šai lietotnei iestatīt signālus un ieplānot citas darbības. Šī lietotne var tikt izmantota, kamēr jūs neizmantojat planšetdatoru, tāpēc var tikt patērēts vairāk akumulatora enerģijas. Ja šī atļauja ir izslēgta, šī lietotne var nedarboties, kā paredzēts, un tās signāli netiek rādīti ieplānotajā laikā."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Atļaut šai lietotnei iestatīt signālus un ieplānot citas darbības. Šī lietotne var tikt izmantota, kamēr jūs neizmantojat ierīci, tāpēc var tikt patērēts vairāk akumulatora enerģijas. Ja šī atļauja ir izslēgta, šī lietotne var nedarboties, kā paredzēts, un tās signāli netiek rādīti ieplānotajā laikā."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Atļaujiet šai lietotnei iestatīt signālus un ieplānot darbības, kas jāveic konkrētā laikā. Tādējādi lietotne darbosies fonā un, iespējams, patērēs vairāk akumulatora enerģijas.\n\nJa šī atļauja nav piešķirta, esošie signāli un šīs lietotnes ieplānotie notikumi, kas jāizpilda konkrētā laikā, nedarbosies."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ieplānot, signāls, atgādinājums, pulkstenis"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ieslēgt"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Režīma “Netraucēt” ieslēgšana"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index aee2e6103eb5..81f75c570b45 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Прикажи граници на клип, маргини, итн."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Принудно користи RTL за насока"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудно постави насока на распоред на екранот во RTL за сите локални стандарди"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Дозволи замаглување прозорец"</string>
<string name="force_msaa" msgid="4081288296137775550">"Принудно користи 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Овозможи 4x MSAA за апликации OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Отстрани грешка на неправоаголни клип операции"</string>
@@ -506,11 +505,9 @@
<string name="cancel" msgid="5665114069455378395">"Откажи"</string>
<string name="okay" msgid="949938843324579502">"Во ред"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Аларми и потсетници"</string>
- <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Дозволете поставување аларми и потсетници"</string>
+ <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Дозволи поставување аларми и потсетници"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и потсетници"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Дозволете ѝ на апликацијава да поставува аларми и да закажува други дејства. Апликацијава може да се користи кога не го користите телефонот, а тоа може да користи повеќе батерија. Ако дозволава е исклучена, апликацијава можеби нема да функционира нормално, а алармите нема да работат според закажаното."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Дозволете ѝ на апликацијава да поставува аларми и да закажува други дејства. Апликацијава може да се користи кога не го користите таблетот, а тоа може да користи повеќе батерија. Ако дозволава е исклучена, апликацијава можеби нема да функционира нормално, а алармите нема да работат според закажаното."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Дозволете ѝ на апликацијава да поставува аларми и да закажува други дејства. Апликацијава може да се користи кога не го користите уредот, а тоа може да користи повеќе батерија. Ако дозволава е исклучена, апликацијава можеби нема да функционира нормално, а алармите нема да работат според закажаното."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволете ѝ на апликацијава да поставува аларми и да закажува дејства со временски рокови. Ова овозможува апликацијата да работи во заднина и така може повеќе да ја троши батеријата.\n\nАко дозволава е исклучена, нема да функционираат постојните аларми и настаните според време закажани од апликацијава."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"закажување, аларм, потсетник, часовник"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Вклучи"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Исклучување на „Не вознемирувај“"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 5ff7d1b15814..9583b506cf14 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ക്ലിപ്പ് ബൗണ്ടുകൾ, മാർജിനുകൾ തുടങ്ങിയവ ദൃശ്യമാക്കുക"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL ലേഔട്ട് ഡയറക്ഷൻ നിർബന്ധമാക്കുക"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"എല്ലാ ഭാഷകൾക്കുമായി സ്‌ക്രീൻ ലേഔട്ട് ഡയറക്ഷൻ RTL-ലേക്ക് നിർബന്ധമാക്കുക"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"വിൻഡോ-ലെവൽ മങ്ങിക്കൽ അനുവദിക്കൂ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA നിർബന്ധമാക്കുക"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ആപ്പുകളിൽ 4x MSAA പ്രവർത്തനക്ഷമമാക്കൂ"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ചതുരമല്ലാത്ത ക്ലിപ്പ്‌ പ്രവർത്തനം ഡീബഗ്ഗ് ചെയ്യുക"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"അലാറങ്ങളും റിമെെൻഡറുകളും"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"അലാറവും റിമെെൻഡറും സജ്ജീകരിക്കാൻ അനുവദിക്കുക"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"അലാറങ്ങളും റിമെെൻഡറുകളും"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും മറ്റ് പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. നിങ്ങൾ ഫോൺ ഉപയോഗിക്കാത്തപ്പോൾ ഈ ആപ്പ് ഉപയോഗിച്ചേക്കാം, ഇത് കൂടുതൽ ബാറ്ററി ഉപയോഗിക്കും. ഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് സാധാരണ നിലയിൽ പ്രവർത്തിച്ചേക്കില്ല, ഷെഡ്യൂൾ ചെയ്ത പോലെ അതിന്റെ അലാറങ്ങളും പ്രവർത്തിക്കില്ല."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും മറ്റ് പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. കൂടുതൽ ബാറ്ററി ഉപയോഗിച്ചേക്കാവുന്ന നിങ്ങളുടെ ടാബ്‌ലെറ്റ് ഉപയോഗിക്കാത്തപ്പോൾ ഈ ആപ്പ് ഉപയോഗിച്ചേക്കാം. ഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് സ്വാഭാവികമായി പ്രവർത്തിച്ചേക്കില്ല, ഷെഡ്യൂൾ ചെയ്ത പോലെ അതിന്റെ അലാറങ്ങളും പ്രവർത്തിക്കില്ല."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും മറ്റ് പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. കൂടുതൽ ബാറ്ററി ഉപയോഗിച്ചേക്കാവുന്ന നിങ്ങളുടെ ഉപകരണം ഉപയോഗിക്കാത്തപ്പോൾ ഈ ആപ്പ് ഉപയോഗിച്ചേക്കാം. ഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് സ്വാഭാവികമായി പ്രവർത്തിച്ചേക്കില്ല, ഷെഡ്യൂൾ ചെയ്ത പോലെ അതിന്റെ അലാറങ്ങളും പ്രവർത്തിക്കില്ല."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും സമയപ്രാധാന്യമുള്ള പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. പശ്ചാത്തലത്തിൽ റൺ ചെയ്യാൻ ഇത് ഈ ആപ്പിന് അനുവാദം നൽകുന്നു, ഇതിന് കൂടുതൽ ബാറ്ററി ഉപയോഗിച്ചേക്കാം.\n\nഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് നിലവിൽ ഷെഡ്യൂൾ ചെയ്‌ത അലാറങ്ങളും സമയാധിഷ്‌ഠിത ഇവന്റുകളും പ്രവർത്തിക്കില്ല."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ഷെഡ്യൂൾ, അലാറം, റിമെെൻഡർ, ക്ലോക്ക്"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ഓണാക്കുക"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index a7d621350070..955937b93992 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Клипийн зах, хязгаар зэргийг харуулах"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL байрлалын чиглэлийг хүчээр тогтоох"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Бүх локалын хувьд дэлгэцийн байрлалын чиглэлийг хүчээр RTL болгох"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Цонхны түвшний бүдгэрүүлэлтийг зөвшөөрөх"</string>
<string name="force_msaa" msgid="4081288296137775550">"Хүчээр 4x MSAA ашиглах"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 апп-уудад 4x MSAA-г идэвхжүүлэх"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Тэгш өнцөгт бус клипийн үйлдлүүдийн согогийг засах"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Сэрүүлэг болон сануулагч"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Сэрүүлэг болон сануулагч тохируулахыг зөвшөөрөх"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Сэрүүлэг, сануулагч"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Энэ аппад сэрүүлэг тавих болон бусад үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Таныг утсаа ашиглаагүй үед энэ аппыг ашиглаж магадгүй бөгөөд үүнд илүү их батарей зарцуулж магадгүй. Энэ зөвшөөрлийг унтраасан үед энэ апп хэвийн ажиллахгүй байж магадгүй бөгөөд сэрүүлэг нь хуваарийн дагуу ажиллахгүй."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Энэ аппад сэрүүлэг тавих болон бусад үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Таныг таблетаа ашиглаагүй үед энэ аппыг ашиглаж магадгүй бөгөөд үүнд илүү их батарей зарцуулж магадгүй. Энэ зөвшөөрлийг унтраасан үед энэ апп хэвийн ажиллахгүй байж магадгүй бөгөөд сэрүүлэг нь хуваарийн дагуу ажиллахгүй."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Энэ аппад сэрүүлэг тавих болон бусад үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Таныг төхөөрөмжөө ашиглаагүй үед энэ аппыг ашиглаж магадгүй бөгөөд үүнд илүү их батарей зарцуулж магадгүй. Энэ зөвшөөрлийг унтраасан үед энэ апп хэвийн ажиллахгүй байж магадгүй бөгөөд сэрүүлэг нь хуваарийн дагуу ажиллахгүй."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Энэ аппад сэрүүлэг тавих болон хугацаанд мэдрэг үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Энэ нь аппад ард ажиллахыг зөвшөөрөх бөгөөд ингэснээр илүү их батарей ашиглаж магадгүй.\n\nХэрэв энэ зөвшөөрөл унтраалттай бол энэ аппын аль хэдийн тавьсан сэрүүлэг болон хуваарь гаргасан хугацаанд мэдрэг үйл явдал ажиллахгүй."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"хуваарь, сэрүүлэг, сануулагч, цаг"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Асаах"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Бүү саад бол горимыг асаах"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 667b3399dd62..8ddb2981e3fc 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमा, समास इत्यादी दर्शवा."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL लेआउट दिशानिर्देशाची सक्ती करा"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"सर्व लोकॅलसाठी RTL स्क्रीन लेआउट दिशानिर्देशाची सक्ती करा"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"विंडो पातळीवरील ब्लरना अनुमती द्या"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ची सक्ती करा"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ॲप्समध्ये 4x MSAA सुरू करा"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"आयताकृती नसलेले क्लिप ऑपरेशन डीबग करा"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म आणि रिमाइंडर"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म आणि रिमाइंडर सेट करण्याची अनुमती द्या"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म आणि रिमाइंडर"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"या ॲपला अलार्म सेट करण्याची आणि इतर कृती शेड्युल करण्याची अनुमती द्या. तुम्ही तुमचा फोन वापरत नसताना हे ॲप वापरले जाऊ शकते, ज्यामुळे जास्त बॅटरी वापरली जाऊ शकते. ही परवानगी नसल्यास, हे ॲप सामान्यपणे काम करू शकणार नाही आणि त्याचे अलार्म शेड्युल केल्याप्रमाणे काम करणार नाहीत."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"या ॲपला अलार्म सेट करण्याची आणि इतर कृती शेड्युल करण्याची अनुमती द्या. तुम्ही तुमचा टॅबलेट वापरत नसताना हे ॲप वापरले जाऊ शकते, ज्यामुळे जास्त बॅटरी वापरली जाऊ शकते. ही परवानगी नसल्यास, हे ॲप सामान्यपणे काम करू शकणार नाही आणि त्याचे अलार्म शेड्युल केल्याप्रमाणे काम करणार नाहीत."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"या ॲपला अलार्म सेट करण्याची आणि इतर कृती शेड्युल करण्याची अनुमती द्या. तुम्ही तुमचे डिव्हाइस वापरत नसताना हे ॲप वापरले जाऊ शकते, ज्यामुळे जास्त बॅटरी वापरली जाऊ शकते. ही परवानगी नसल्यास, हे ॲप सामान्यपणे काम करू शकणार नाही आणि त्याचे अलार्म शेड्युल केल्याप्रमाणे काम करणार नाहीत."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्युल, अलार्म, रिमाइंडर, घड्याळ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सुरू करा"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका सुरू करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 1011e330a48c..13788c43bea8 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Tunjukkan batas klip, margin dll."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Paksa arah reka letak RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Paksa arah reka letak skrin RTL bagi semua tempat peristiwa"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Benarkan kabur tahap tetingkap"</string>
<string name="force_msaa" msgid="4081288296137775550">"Paksa 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Dayakan 4x MSAA dalam apl OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Nyahpepijat operasi keratan bukan segi empat tepat"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Penggera dan peringatan"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Benarkan penetapan penggera dan peringatan"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Penggera &amp; peringatan"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan lain. Apl ini mungkin digunakan ketika anda tidak menggunakan telefon, apl mungkin menggunakan lebih banyak bateri. Jika kebenaran ini dimatikan, apl ini mungkin tidak berfungsi seperti biasa dan penggera tidak akan berfungsi seperti yang dijadualkan."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan lain. Apl ini mungkin digunakan ketika anda tidak menggunakan tablet, apl mungkin menggunakan lebih banyak bateri. Jika kebenaran ini dimatikan, apl ini mungkin tidak berfungsi seperti biasa dan penggera tidak akan berfungsi seperti yang dijadualkan."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan lain. Apl ini mungkin digunakan ketika anda tidak menggunakan peranti, apl mungkin menggunakan lebih banyak bateri. Jika kebenaran ini dimatikan, apl ini mungkin tidak berfungsi seperti biasa dan penggera tidak akan berfungsi seperti yang dijadualkan."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan yang sensitif masa. Ini membolehkan apl berjalan di latar, yang mungkin menggunakan lebih banyak bateri.\n\nJika kebenaran ini dimatikan, penggera sedia ada dan acara berdasarkan masa yang dijadualkan oleh apl ini tidak akan berfungsi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadual, penggera, peringatan, jam"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Hidupkan"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Hidupkan Jangan Ganggu"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index e01c123d9d78..dac55c5a5e3b 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ဖြတ်ပိုင်းအနားသတ်များ၊ အနားများ စသဖြင့် ပြပါ။"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL အပြင်အဆင်အတိုင်း ဖြစ်စေခြင်း"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ဘာသာစကားအားလုံးအတွက် RTL အပြင်အဆင်အတိုင်း ဖြစ်စေသည်"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ဝင်းဒိုးအဆင့် မှုန်ဝါးမှု ခွင့်ပြုရန်"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA မဖြစ်မနေဖွင့်ခြင်း"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 အက်ပ်များတွင် 4x MSAA ဖွင့်သည်"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"စတုဂံပုံမကျသောဖြတ်ပိုင်း လုပ်ဆောင်ချက်များကို အမှားဖယ်ရှားသည်"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"နှိုးစက်နှင့် သတိပေးချက်များ သတ်မှတ်ခွင့်ပြုရန်"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"နှိုးစက်များသတ်မှတ်ရန်နှင့် အခြားလုပ်ဆောင်ချက်များ အစီအစဉ်ဆွဲရန် ဤအက်ပ်အား ခွင့်ပြုပါ။ သင့်ဖုန်းကို အသုံးမပြုသောအခါ ဤအက်ပ်ကိုသုံးနိုင်ပြီး ၎င်းက ဘက်ထရီပိုသုံးနိုင်သည်။ ဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်သည် ပုံမှန်လုပ်ဆောင်နိုင်ခြင်းမရှိ၍ ၎င်း၏နှိုးစက်များလည်း သတ်မှတ်ထားသည့်အတိုင်း အလုပ်လုပ်တော့မည်မဟုတ်ပါ။"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"နှိုးစက်များသတ်မှတ်ရန်နှင့် အခြားလုပ်ဆောင်ချက်များ အစီအစဉ်ဆွဲရန် ဤအက်ပ်အား ခွင့်ပြုပါ။ သင့်တက်ဘလက်ကို အသုံးမပြုသောအခါ ဤအက်ပ်ကိုသုံးနိုင်ပြီး ၎င်းက ဘက်ထရီပိုသုံးနိုင်သည်။ ဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်သည် ပုံမှန်လုပ်ဆောင်နိုင်ခြင်းမရှိ၍ ၎င်း၏နှိုးစက်များလည်း သတ်မှတ်ထားသည့်အတိုင်း အလုပ်လုပ်တော့မည်မဟုတ်ပါ။"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"နှိုးစက်များသတ်မှတ်ရန်နှင့် အခြားလုပ်ဆောင်ချက်များ အစီအစဉ်ဆွဲရန် ဤအက်ပ်အား ခွင့်ပြုပါ။ သင့်စက်ကို အသုံးမပြုသောအခါ ဤအက်ပ်ကိုသုံးနိုင်ပြီး ၎င်းက ဘက်ထရီပိုသုံးနိုင်သည်။ ဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်သည် ပုံမှန်လုပ်ဆောင်နိုင်ခြင်းမရှိ၍ ၎င်း၏နှိုးစက်များလည်း သတ်မှတ်ထားသည့်အတိုင်း အလုပ်လုပ်တော့မည်မဟုတ်ပါ။"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"နှိုးစက်သတ်မှတ်ရန်နှင့် အချိန်တိကျရန် လိုအပ်သည့် လုပ်ဆောင်ချက်များ အစီအစဉ်ဆွဲရန် ဤအက်ပ်ကို ခွင့်ပြုပါ။ ၎င်းက အက်ပ်ကို နောက်ခံတွင် လုပ်ဆောင်ခွင့်ပေးပြီး ဘက်ထရီပိုသုံးနိုင်သည်။\n\nဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်ဖြင့် အစီအစဉ်ဆွဲထားသော လက်ရှိနှိုးစက်နှင့် အချိန်သတ်မှတ်ထားသည့် အစီအစဉ်များ အလုပ်လုပ်တော့မည် မဟုတ်ပါ။"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"အချိန်ဇယား၊ နှိုးစက်၊ သတိပေးချက်၊ နာရီ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ဖွင့်ရန်"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'မနှောင့်ယှက်ရ\' ဖွင့်ခြင်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index cde30ca98735..769b468df215 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Vis kanter, marger osv."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Tving layoutretning for RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Tving RTL-retning på skjermen for alle språk"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Tillat uskarphet i vindu"</string>
<string name="force_msaa" msgid="4081288296137775550">"Tving 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Slå på 4x MSAA i OpenGL ES 2.0-apper"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Feilsøk ikke-rektangulær klipping"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmer og påminnelser"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Tillat innstilling av alarmer og påminnelser"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmer og påminnelser"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Tillat at denne appen stiller inn alarmer og planlegger andre handlinger. Denne appen kan brukes når du ikke bruker telefonen, noe som kan bruke mer batteri. Hvis denne tillatelsen er av, fungerer appen muligens ikke som normalt, og alarmene i den fungerer ikke som planlagt."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Tillat at denne appen stiller inn alarmer og planlegger andre handlinger. Denne appen kan brukes når du ikke bruker nettbrettet, noe som kan bruke mer batteri. Hvis denne tillatelsen er av, fungerer appen muligens ikke som normalt, og alarmene i den fungerer ikke som planlagt."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Tillat at denne appen stiller inn alarmer og planlegger andre handlinger. Denne appen kan brukes når du ikke bruker enheten, noe som kan bruke mer batteri. Hvis denne tillatelsen er av, fungerer appen muligens ikke som normalt, og alarmene i den fungerer ikke som planlagt."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Gi denne appen tillatelse til å angi alarmer og planlegge tidssensitive handlinger. Dette gir appen tillatelse til å kjøre i bakgrunnen, noe som kan bruke mer batteri.\n\nHvis denne tillatelsen er av, fungerer ikke eksisterende alarmer og tidsbaserte hendelser som er planlagt av denne appen."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tidsplan, alarm, påminnelse, klokke"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Slå på"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Slå på Ikke forstyrr"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index aaf2c637a225..0bf1a7802a0c 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -162,7 +162,7 @@
<string name="tts_default_pitch_title" msgid="6988592215554485479">"पिच"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"संश्लेषित बोलीको टोनमा प्रभाव पार्छ"</string>
<string name="tts_default_lang_title" msgid="4698933575028098940">"भाषा"</string>
- <string name="tts_lang_use_system" msgid="6312945299804012406">"प्रणालीको भाषा प्रयोग गर्नुहोस्"</string>
+ <string name="tts_lang_use_system" msgid="6312945299804012406">"सिस्टमको भाषा प्रयोग गर्नुहोस्"</string>
<string name="tts_lang_not_selected" msgid="7927823081096056147">"भाषा चयन गरिएको छैन"</string>
<string name="tts_default_lang_summary" msgid="9042620014800063470">"बोली पाठका लागि भाषा-विशेष आवाज सेट गर्दछ"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"एउटा उदाहरण सुन्नुहोस्"</string>
@@ -223,9 +223,9 @@
<string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"डिभाइसको फिंगरप्रिन्ट: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
<string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"वायरलेसमा जोड्न सकिएन"</string>
<string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> सही नेटवर्कमा जोडिएको कुरा सुनिश्चित गर्नुहोस्"</string>
- <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"यन्त्रसँग जोडा बनाउनुहोस्"</string>
+ <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"यन्त्रसँग कनेक्ट गर्नुहोस्"</string>
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi मा कनेक्ट गर्ने कोड"</string>
- <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"जोडा बनाउने प्रक्रिया सफल भएन"</string>
+ <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"कनेक्ट गर्न सकिएन"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"यन्त्र उही नेटवर्कमा जोडिएको कुरा सुनिश्चित गर्नुहोस्।"</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR कोड स्क्यान गरेर Wi‑Fi प्रयोग गरी डिभाइस कनेक्ट गर्नुहोस्"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"डिभाइस कनेक्ट गर्दै…"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमा, मार्जिन, इत्यादि देखाइयोस्।"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL लेआउट बलपूर्वक प्रयोग गरियोस्"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"सबै लोकेलमा RTLमा स्क्रिन लेआउट बलपूर्वक प्रयोग गरियोस्"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"विन्डो ब्लर गरियोस्"</string>
<string name="force_msaa" msgid="4081288296137775550">"बलपूर्वक 4x MSAA प्रयोग गरियोस्"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES २.० एपमा ४x MSAA अन गरियोस्"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"गैर आयातकर क्लिप रहेका कार्यहरू डिबग गरियोस्"</string>
@@ -468,7 +467,7 @@
<string name="disabled" msgid="8017887509554714950">"असक्षम पारियो"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"अनुमति छ"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति छैन"</string>
- <string name="install_other_apps" msgid="3232595082023199454">"अज्ञात एपहरू इन्स्टल गर्नुहोस्"</string>
+ <string name="install_other_apps" msgid="3232595082023199454">"अज्ञात एप इन्स्टल गर्ने अनुमति"</string>
<string name="home" msgid="973834627243661438">"सेटिङहरूको गृहपृष्ठ"</string>
<string-array name="battery_labels">
<item msgid="7878690469765357158">"०%"</item>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म र रिमाइन्डरहरू"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म तथा रिमाइन्डर सेट गर्न दिइयोस्"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"घडी तथा रिमाइन्डरहरू"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"यो एपलाई अलार्म सेट गर्न तथा अन्य कार्यको समयतालिका तोक्न दिनुहोस्। तपाईंले आफ्नो फोन नचलाएका बेला पनि यो एप प्रयोग गरिन सक्छ। यसले गर्दा थप ब्याट्री खपत हुन सक्छ। यो अनुमति नदिइएका खण्डमा यो एप राम्ररी नचल्न सक्छ र यो एपका अलार्म पनि तोकिएको समयमा बज्ने छैनन्।"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"यो एपलाई अलार्म सेट गर्न तथा अन्य कार्यको समयतालिका तोक्न दिनुहोस्। तपाईंले आफ्नो ट्याब्लेट नचलाएका बेला पनि यो एप प्रयोग गरिन सक्छ। यसले गर्दा थप ब्याट्री खपत हुन सक्छ। यो अनुमति नदिइएका खण्डमा यो एप राम्ररी नचल्न सक्छ र यो एपका अलार्म पनि तोकिएको समयमा बज्ने छैनन्।"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"यो एपलाई अलार्म सेट गर्न तथा अन्य कार्यको समयतालिका तोक्न दिनुहोस्। तपाईंले आफ्नो डिभाइस नचलाएका बेला पनि यो एप प्रयोग गरिन सक्छ। यसले गर्दा थप ब्याट्री खपत हुन सक्छ। यो अनुमति नदिइएका खण्डमा यो एप राम्ररी नचल्न सक्छ र यो एपका अलार्म पनि तोकिएको समयमा बज्ने छैनन्।"</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"समयतालिका, अलार्म, रिमाइन्डर, घडी"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सक्रिय गर्नुहोस्"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"बाधा नपुऱ्याउनुहोस् नामक मोडलाई सक्रिय गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 806d87b8d89f..ca4308c6c92e 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Toon clipgrenzen, marges en meer"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"V.r.n.l.-indelingsrichting afdwingen"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Stel de schermindelingsrichting geforceerd in op v.r.n.l. voor alle talen"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Vervagen op vensterniveau toestaan"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA forceren"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Zet 4x MSAA aan in OpenGL ES 2.0-apps"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Foutopsporing niet-rechthoekig bijsnijden"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Wekkers en herinneringen"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Wekkers en herinneringen laten instellen"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wekkers en herinneringen"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Sta deze app toe om wekkers te zetten en andere acties te plannen. Deze app kan actief zijn als je je telefoon niet gebruikt, waardoor je meer batterijlading verbruikt. Als dit recht uitstaat, werkt deze app mogelijk niet naar behoren en de wekkers niet zoals gepland."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Sta deze app toe om wekkers te zetten en andere acties te plannen. Deze app kan worden gebruikt als je je tablet niet gebruikt, waardoor er meer batterijlading wordt verbruikt. Als deze toestemming uit staat, werkt deze app mogelijk niet naar behoren en werken de wekkers niet zoals gepland."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Sta deze app toe om wekkers te zetten en andere acties te plannen. Deze app kan worden gebruikt als je je apparaat niet gebruikt, waardoor er meer batterijlading wordt verbruikt. Als deze toestemming uit staat, werkt deze app mogelijk niet naar behoren en werken de wekkers niet zoals gepland."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Sta toe dat deze app wekkers zet en tijdgevoelige acties plant. De app kan hierdoor op de achtergrond worden uitgevoerd, waardoor je misschien meer batterijlading verbruikt.\n\nAls dit recht uitstaat, werken door deze app geplande bestaande wekkers en tijdgebaseerde afspraken niet."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plannen, schema, wekker, alarm, herinnering, klok"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aanzetten"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zet Niet storen aan."</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 8c86031fce79..21bd1ad4a0e8 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"କ୍ଲିପ୍‌ ବାଉଣ୍ଡ, ମାର୍ଜିନ୍‌ ଆଦି ଦେଖନ୍ତୁ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL ଲେଆଉଟ୍ ଦିଗ ବାଧ୍ୟ କରନ୍ତୁ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ସମସ୍ତ ଲୋକେଲ୍‌ ସକାଶେ ସ୍କ୍ରୀନ୍‌ ଲେଆଉଟ୍‌ ଦିଗ RTL ପାଇଁ ବାଧ୍ୟ କରନ୍ତୁ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ୱିଣ୍ଡୋ-ଲେଭେଲରେ ବ୍ଲରକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ବାଧ୍ୟ କରନ୍ତୁ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ଆପ୍‌ରେ 4x MSAA ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ଅଣ-ଆୟତାକାର କ୍ଲିପ୍‌ କାର୍ଯ୍ୟକୁ ଡିବଗ୍‌ କରନ୍ତୁ"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ଆଲାରାମ ଓ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ ସେଟ କରିବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"ଆଲାରାମଗୁଡ଼ିକୁ ସେଟ୍ କରିବା ଏବଂ ଅନ୍ୟ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ସିଡୁଲ୍ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଆପଣ ଆପଣଙ୍କ ଟାବଲେଟ୍ ବ୍ୟବହାର କରୁନଥିବା ସମୟରେ ଏହି ଆପକୁ ବ୍ୟବହାର କରାଯାଇପାରେ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରିପାରେ। ଯଦି ଏହି ଅନୁମତି ବନ୍ଦ ଥାଏ, ଏହି ଆପ୍ ସାମାନ୍ୟ ରୂପେ କାର୍ଯ୍ୟ କରିନପାରେ ଏବଂ ଏହାର ଆଲାରାମଗୁଡ଼ିକ ସିଡୁଲ୍ କରାଯାଇଥିବା ଅନୁସାରେ କାମ କରିବ ନାହିଁ।"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"ଆଲାରାମଗୁଡ଼ିକୁ ସେଟ୍ କରିବା ଏବଂ ଅନ୍ୟ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ସିଡୁଲ୍ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଆପଣ ଆପଣଙ୍କ ଟାବଲେଟ୍ ବ୍ୟବହାର କରୁନଥିବା ସମୟରେ ଏହି ଆପକୁ ବ୍ୟବହାର କରାଯାଇପାରେ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରିପାରେ। ଯଦି ଏହି ଅନୁମତି ବନ୍ଦ ଥାଏ, ଏହି ଆପ୍ ସାମାନ୍ୟ ରୂପେ କାର୍ଯ୍ୟ କରିନପାରେ ଏବଂ ଏହାର ଆଲାରାମଗୁଡ଼ିକ ସିଡୁଲ୍ କରାଯାଇଥିବା ଅନୁସାରେ କାମ କରିବ ନାହିଁ।"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"ଆଲାରାମଗୁଡ଼ିକୁ ସେଟ୍ କରିବା ଏବଂ ଅନ୍ୟ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ସିଡୁଲ୍ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଆପଣ ଆପଣଙ୍କ ଟାବଲେଟ୍ ବ୍ୟବହାର କରୁନଥିବା ସମୟରେ ଏହି ଆପକୁ ବ୍ୟବହାର କରାଯାଇପାରେ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରିପାରେ। ଯଦି ଏହି ଅନୁମତି ବନ୍ଦ ଥାଏ, ଏହି ଆପ୍ ସାମାନ୍ୟ ରୂପେ କାର୍ଯ୍ୟ କରିନପାରେ ଏବଂ ଏହାର ଆଲାରାମଗୁଡ଼ିକ ସିଡୁଲ୍ କରାଯାଇଥିବା ଅନୁସାରେ କାମ କରିବ ନାହିଁ।"</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ସିଡୁଲ୍, ଆଲାରାମ୍, ରିମାଇଣ୍ଡର୍, ଘଣ୍ଟା"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ଚାଲୁ କରନ୍ତୁ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 635f0a81ae15..aaa892a4969b 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -156,7 +156,7 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"ਕੁਝ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈੱਟ ਕੀਤੇ"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"ਕੋਈ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਸੈੱਟ ਨਹੀਂ ਕੀਤੇ"</string>
<string name="tts_settings" msgid="8130616705989351312">"ਲਿਖਤ ਤੋਂ ਬੋਲੀ ਸੈਟਿੰਗਾਂ"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"ਲਿਖਤ ਤੋਂ ਬੋਲੀ ਆਊਟਪੁੱਟ"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"ਲਿਖਤ-ਤੋਂ-ਬੋਲੀ ਆਊਟਪੁੱਟ"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"ਬੋਲਣ ਦੀ ਗਤੀ"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"ਸਪੀਡ ਜਿਸਤੇ ਟੈਕਸਟ ਬੋਲਿਆ ਜਾਂਦਾ ਹੈ"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"ਪਿਚ"</string>
@@ -196,7 +196,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string>
<string name="category_personal" msgid="6236798763159385225">"ਨਿੱਜੀ"</string>
- <string name="category_work" msgid="4014193632325996115">"ਕਾਰਜ-ਸਥਾਨ"</string>
+ <string name="category_work" msgid="4014193632325996115">"ਕੰਮ ਸੰਬੰਧੀ"</string>
<string name="development_settings_title" msgid="140296922921597393">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ਐਪ ਵਿਕਾਸ ਲਈ ਚੋਣਾਂ ਸੈੱਟ ਕਰੋ"</string>
@@ -214,7 +214,7 @@
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ਉਪਲਬਧ ਡੀਵਾਈਸਾਂ ਨੂੰ ਦੇਖਣ ਅਤੇ ਵਰਤਣ ਲਈ, ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR ਕੋਡ ਨਾਲ ਡੀਵਾਈਸ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR ਕੋਡ ਸਕੈਨਰ ਵਰਤ ਕੇ ਨਵੇਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
- <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ਜੋੜਾਬੱਧਕਰਨ ਕੋਡ ਨਾਲ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
+ <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ਜੋੜਾਬੱਧਕਰਨ ਕੋਡ ਨਾਲ ਡੀਵਾਈਸ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ਛੇ ਅੰਕਾਂ ਵਾਲਾ ਕੋਡ ਵਰਤ ਕੇ ਨਵੇਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸ"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"ਇਸ ਵੇਲੇ ਕਨੈਕਟ ਹੈ"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ਕਲਿੱਪ ਸੀਮਾਵਾਂ, ਹਾਸ਼ੀਏ ਆਦਿ ਦਿਖਾਓ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"ਸੱਜੇ ਤੋਂ ਖੱਬੇ ਵਾਲਾ ਖਾਕਾ ਲਾਗੂ ਕਰੋ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ਸਾਰੀਆਂ ਭਾਸ਼ਾਵਾਂ ਲਈ ਸਕ੍ਰੀਨ \'ਤੇ ਸੱਜੇ ਤੋਂ ਖੱਬੇ ਵਾਲਾ ਖਾਕਾ ਲਾਗੂ ਕਰੋ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ਵਿੰਡੋ-ਪੱਧਰ \'ਤੇ ਧੁੰਦਲਾ ਕਰਨ ਦਿਓ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ਐਪਾਂ ਵਿੱਚ 4x MSAA ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ਗੈਰ-ਆਇਤਾਕਾਰ ਕਲਿੱਪ ਓਪਰੇਸ਼ਨ ਡੀਬੱਗ ਕਰੋ"</string>
@@ -427,7 +426,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (ਲਾਲ-ਹਰਾ)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ਨੀਲਾ-ਪੀਲਾ)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ਰੰਗ ਸੁਧਾਈ"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਰੰਗਾਂ ਨੂੰ ਦਿਖਾਉਣ ਦੇ ਤਰੀਕੇ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰੋ। ਇਹ ਉਦੋਂ ਲਾਹੇਵੰਦ ਹੋ ਸਕਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ ਇਹ ਕਰਨਾ ਚਾਹੋਗੇ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ਰੰਗਾਂ ਨੂੰ ਹੋਰ ਸਟੀਕਤਾ ਨਾਲ ਦੇਖਣਾ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਲਈ ਰੰਗਾਂ ਨੂੰ ਹਟਾਉਣਾ&lt;/li&gt; &lt;/ol&gt;"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਰੰਗਾਂ ਨੂੰ ਦਿਖਾਉਣ ਦੇ ਤਰੀਕੇ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰੋ। ਇਹ ਉਦੋਂ ਲਾਹੇਵੰਦ ਹੋ ਸਕਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ਰੰਗਾਂ ਨੂੰ ਹੋਰ ਸਟੀਕਤਾ ਨਾਲ ਦੇਖਣਾ ਚਾਹੋ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਨ ਲਈ ਰੰਗਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੋ&lt;/li&gt; &lt;/ol&gt;"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ ਸੈੱਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਅਤੇ ਹੋਰ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। ਇਸ ਐਪ ਦੀ ਵਰਤੋਂ ਉਦੋਂ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੇ ਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ ਹੋ, ਜਿਸ ਕਾਰਨ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵਧੇਰੇ ਹੋ ਸਕਦੀ ਹੈ। ਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ, ਤਾਂ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਐਪ ਆਮ ਵਾਂਗ ਕੰਮ ਨਾ ਕਰੇ ਅਤੇ ਇਸਦੇ ਅਲਾਰਮ ਨਿਯਤ ਸਮੇਂ ਅਨੁਸਾਰ ਕੰਮ ਨਾ ਕਰਨ।"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਅਤੇ ਹੋਰ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। ਇਸ ਐਪ ਦੀ ਵਰਤੋਂ ਉਦੋਂ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੇ ਟੈਬਲੈੱਟ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ ਹੋ, ਜਿਸ ਕਾਰਨ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵਧੇਰੇ ਹੋ ਸਕਦੀ ਹੈ। ਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ, ਤਾਂ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਐਪ ਆਮ ਵਾਂਗ ਕੰਮ ਨਾ ਕਰੇ ਅਤੇ ਇਸਦੇ ਅਲਾਰਮ ਨਿਯਤ ਸਮੇਂ ਅਨੁਸਾਰ ਕੰਮ ਨਾ ਕਰਨ।"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਅਤੇ ਹੋਰ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। ਇਸ ਐਪ ਦੀ ਵਰਤੋਂ ਉਦੋਂ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੇ ਡੀਵਾਈਸ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ ਹੋ, ਜਿਸ ਕਾਰਨ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵਧੇਰੇ ਹੋ ਸਕਦੀ ਹੈ। ਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ, ਤਾਂ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਹ ਐਪ ਆਮ ਵਾਂਗ ਕੰਮ ਨਾ ਕਰੇ ਅਤੇ ਇਸਦੇ ਅਲਾਰਮ ਨਿਯਤ ਸਮੇਂ ਅਨੁਸਾਰ ਕੰਮ ਨਾ ਕਰਨ।"</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ਸਮਾਂ-ਸੂਚੀ, ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਘੜੀ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ਚਾਲੂ ਕਰੋ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 7e8a5714a00f..99faea7afc10 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Pokaż granice przycięcia, marginesy itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Układ od prawej do lewej"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Wymuś wszędzie układ ekranu od prawej do lewej"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Zezwól na rozmycie na poziomie okna"</string>
<string name="force_msaa" msgid="4081288296137775550">"Wymuś 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Włącz 4x MSAA w aplikacjach OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Debuguj operacje przycinania nieprostokątnego"</string>
@@ -508,11 +507,9 @@
<string name="cancel" msgid="5665114069455378395">"Anuluj"</string>
<string name="okay" msgid="949938843324579502">"OK"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmy i przypomnienia"</string>
- <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Zezwól na ustawianie alarmów i przypomnień"</string>
+ <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Zezwalaj na ustawianie alarmów i przypomnień"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmy i przypomnienia"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Zezwól na ustawianie alarmów i planowanie innych działań przez tę aplikację. Ta aplikacja może być używana, gdy nie korzystasz z telefonu. Może to zwiększyć wykorzystanie baterii. Jeśli nie włączysz tych uprawnień, ta aplikacja może nie działać prawidłowo, a jej alarmy nie będą uruchamiane zgodnie z harmonogramem."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Zezwól na ustawianie alarmów i planowanie innych działań przez tę aplikację. Ta aplikacja może być używana, gdy nie korzystasz z tabletu. Może to zwiększyć wykorzystanie baterii. Jeśli nie włączysz tych uprawnień, ta aplikacja może nie działać prawidłowo, a jej alarmy nie będą uruchamiane zgodnie z harmonogramem."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Zezwól na ustawianie alarmów i planowanie innych działań przez tę aplikację. Ta aplikacja może być używana, gdy nie korzystasz z urządzenia. Może to zwiększyć wykorzystanie baterii. Jeśli nie włączysz tych uprawnień, ta aplikacja może nie działać prawidłowo, a jej alarmy nie będą uruchamiane zgodnie z harmonogramem."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Zezwól na ustawianie alarmów i planowanie innych działań, w przypadku których czas jest istotny. Dzięki temu aplikacja będzie mogła działać w tle, co może zwiększyć wykorzystanie baterii.\n\nJeśli nie włączysz tych uprawnień, istniejące alarmy i zaplanowane wydarzenia z tej aplikacji nie będą działać."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"harmonogram, alarm, przypomnienie, zegar"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Włącz"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Włącz tryb Nie przeszkadzać"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index d6f6da3f8591..021a75e724bb 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -211,7 +211,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuração quando a rede Wi‑Fi estiver conectada"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Erro"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Depuração por Wi-Fi"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar dispositivos disponíveis, ative a depuração por Wi-Fi"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar dispositivos disponíveis, ative a depuração por Wi-Fi."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parear o dispositivo com um código QR"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parear novos dispositivos usando um leitor de código QR"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parear o dispositivo com um código de pareamento"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostrar limites de corte, margens, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forçar layout da direita p/ esquerda"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forçar a direção do layout da direita para a esquerda para todas as localidades"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permitir desfoques de janela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forçar 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ativar 4x MSAA em apps OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operações de corte não retangulares"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes e lembretes"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autorizar a definição de alarmes e lembretes"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permitir que esse app defina alarmes e programe outras ações. Ele poderá ser usado quando você não estiver usando o smartphone, o que consumirá mais bateria. Se essa permissão for desativada, o app e os alarmes dele poderão não funcionar como planejado."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permitir que esse app defina alarmes e programe outras ações. Ele poderá ser usado quando você não estiver usando o tablet, o que consumirá mais bateria. Se essa permissão for desativada, o app e os alarmes dele poderão não funcionar como planejado."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permitir que esse app defina alarmes e programe outras ações. Ele poderá ser usado quando você não estiver usando o dispositivo, o que consumirá mais bateria. Se essa permissão for desativada, o app e os alarmes dele poderão não funcionar como planejado."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações mais imediatas. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 294f61a32365..cdea8b2a4512 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Apresentar limites de clipes, margens, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forçar direção do esquema RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forçar dir. do esq. do ecrã p. RTL tds os locais"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permitir esbater janelas"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forçar 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ativar o 4x MSAA em aplicações OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operações de clipe não retangulares"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes e lembretes"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permitir a definição de alarmes e lembretes"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permita que esta app defina alarmes e agende outras ações. Esta app pode ser utilizada quando não estiver a utilizar o seu telemóvel, o que pode consumir mais bateria. Se esta autorização estiver desativada, esta app pode não funcionar normalmente e os respetivos alarmes não irão funcionar conforme agendado."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permita que esta app defina alarmes e agende outras ações. Esta app pode ser utilizada quando não estiver a utilizar o seu tablet, o que pode consumir mais bateria. Se esta autorização estiver desativada, esta app pode não funcionar normalmente e os respetivos alarmes não irão funcionar conforme agendado."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permita que esta app defina alarmes e agende outras ações. Esta app pode ser utilizada quando não estiver a utilizar o seu dispositivo, o que pode consumir mais bateria. Se esta autorização estiver desativada, esta app pode não funcionar normalmente e os respetivos alarmes não irão funcionar conforme agendado."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permita que esta app defina alarmes e agende outras ações com base no tempo. Esta ação permite que a app seja executada em segundo plano, o que pode utilizar mais bateria.\n\nSe esta autorização estiver desativada, os alarmes existentes e os eventos com base no tempo agendados por esta app não funcionam."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"agendar, alarme, lembrete, relógio"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o modo Não incomodar"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index d6f6da3f8591..021a75e724bb 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -211,7 +211,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuração quando a rede Wi‑Fi estiver conectada"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Erro"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Depuração por Wi-Fi"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar dispositivos disponíveis, ative a depuração por Wi-Fi"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar dispositivos disponíveis, ative a depuração por Wi-Fi."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parear o dispositivo com um código QR"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parear novos dispositivos usando um leitor de código QR"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parear o dispositivo com um código de pareamento"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostrar limites de corte, margens, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forçar layout da direita p/ esquerda"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forçar a direção do layout da direita para a esquerda para todas as localidades"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permitir desfoques de janela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forçar 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ativar 4x MSAA em apps OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operações de corte não retangulares"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes e lembretes"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autorizar a definição de alarmes e lembretes"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permitir que esse app defina alarmes e programe outras ações. Ele poderá ser usado quando você não estiver usando o smartphone, o que consumirá mais bateria. Se essa permissão for desativada, o app e os alarmes dele poderão não funcionar como planejado."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permitir que esse app defina alarmes e programe outras ações. Ele poderá ser usado quando você não estiver usando o tablet, o que consumirá mais bateria. Se essa permissão for desativada, o app e os alarmes dele poderão não funcionar como planejado."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permitir que esse app defina alarmes e programe outras ações. Ele poderá ser usado quando você não estiver usando o dispositivo, o que consumirá mais bateria. Se essa permissão for desativada, o app e os alarmes dele poderão não funcionar como planejado."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações mais imediatas. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index c922684abfb0..e02bada35233 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Afișați limitele clipului, marginile etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Direcție aspect dreapta - stânga"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Direcție obligatorie aspect ecran dreapta - stânga"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Permiteți estompări la nivel de fereastră"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forțați MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activați MSAA 4x în aplicațiile OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Remediați decupări nerectangulare"</string>
@@ -509,9 +508,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarme și mementouri"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permiteți setarea pentru alarme și mementouri"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarme și mementouri"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Permiteți ca aplicația să seteze alarme și să programeze alte acțiuni. Aplicația poate rula când nu folosiți telefonul, ceea ce poate consuma mai multă baterie. Dacă permisiunea este dezactivată, este posibil ca aplicația să nu funcționeze normal, iar alarmele nu vor funcționa conform planului."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Permiteți ca aplicația să seteze alarme și să programeze alte acțiuni. Aplicația poate rula când nu folosiți tableta, ceea ce poate consuma mai multă baterie. Dacă permisiunea este dezactivată, este posibil ca aplicația să nu funcționeze normal, iar alarmele nu vor funcționa conform planului."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Permiteți ca aplicația să seteze alarme și să programeze alte acțiuni. Aplicația poate rula când nu folosiți dispozitivul, ceea ce poate consuma mai multă baterie. Dacă permisiunea este dezactivată, este posibil ca aplicația să nu funcționeze normal, iar alarmele nu vor funcționa conform planului."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permiteți acestei aplicații să stabilească alarme și să planifice acțiuni dependente de timp. Astfel, aplicația poate să ruleze în fundal, fapt care ar putea consuma mai multă baterie.\n\nDacă permisiunea este dezactivată, alarmele și evenimentele dependente de timp planificate de aplicație nu vor funcționa."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programare, alarmă, memento, ceas"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activați"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activați Nu deranja"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 24a5039221f5..923917b0eeba 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -179,7 +179,7 @@
<string name="tts_status_checking" msgid="8026559918948285013">"Проверка…"</string>
<string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
<string name="tts_engine_settings_button" msgid="477155276199968948">"Настройки синтеза речи"</string>
- <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Система по умолчанию"</string>
+ <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Синтезатор речи по умолчанию"</string>
<string name="tts_general_section_title" msgid="8919671529502364567">"Общие"</string>
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Тон по умолчанию"</string>
<string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Установить стандартный тон при озвучивании текста."</string>
@@ -213,9 +213,9 @@
<string name="adb_wireless_settings" msgid="2295017847215680229">"Отладка по Wi-Fi"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Чтобы увидеть и использовать доступные устройства, включите отладку по Wi-Fi."</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Подключить устройство с помощью QR-кода"</string>
- <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Подключение новых устройств с помощью сканера QR-кодов"</string>
+ <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Отсканировать QR-код для подключения устройства"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Подключить устройство с помощью кода подключения"</string>
- <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Подключение новых устройств с помощью шестизначного кода"</string>
+ <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Ввести шестизначный код для подключения устройства"</string>
<string name="adb_paired_devices_title" msgid="5268997341526217362">"Подключенные устройства"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Текущие подключения"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Сведения об устройстве"</string>
@@ -226,13 +226,13 @@
<string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Подключение к устройству"</string>
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код подключения по сети Wi‑Fi"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Не удалось подключить устройство"</string>
- <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Устройство должно быть подключено к той же самой сети."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Подключение устройства через Wi‑Fi с использованием QR-кода"</string>
+ <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Оба устройства должны быть подключены к одной и той же сети."</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Отсканируйте QR-код, чтобы подключить устройство через Wi‑Fi."</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Подключение устройства…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Не удалось подключить устройство. QR-код неверный, или устройство находится в другой сети."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адрес и порт"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Отсканируйте QR-код"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Подключение устройства через Wi‑Fi с использованием QR-кода"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Отсканируйте QR-код, чтобы подключить устройство через Wi‑Fi."</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Подключите устройство к сети Wi-Fi."</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отладка, разработчик"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Отчет об ошибке"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Показывать границы обрезки, поля и т. п."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Отразить интерфейс"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудительно расположить элементы интерфейса справа налево во всех локалях"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Размытие на уровне окон"</string>
<string name="force_msaa" msgid="4081288296137775550">"Включить 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Включить 4x MSAA в приложениях OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Отладка операций усечения сложной формы"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будильники и напоминания"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Разрешить установку будильников и напоминаний"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будильники и напоминания"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Если вы разрешите этому приложению устанавливать будильники и создавать напоминания, оно сможет работать, даже когда вы не пользуетесь телефоном. Правда, в результате заряд батареи будет расходоваться быстрее. Если отключить эту настройку, в работе приложения могут возникать сбои, а будильники не будут запускаться вовремя."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Если вы разрешите этому приложению устанавливать будильники и создавать напоминания, оно сможет работать, даже когда вы не пользуетесь планшетом. Правда, в результате заряд батареи будет расходоваться быстрее. Если отключить эту настройку, в работе приложения могут возникать сбои, а будильники не будут запускаться вовремя."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Если вы разрешите этому приложению устанавливать будильники и создавать напоминания, оно сможет работать, даже когда вы не пользуетесь устройством. Правда, в результате заряд батареи будет расходоваться быстрее. Если отключить эту настройку, в работе приложения могут возникать сбои, а будильники не будут запускаться вовремя."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Если вы разрешите этому приложению устанавливать будильники и планировать на определенное время действия, оно будет работать в фоновом режиме. В таком случае заряд батареи может расходоваться быстрее.\n\nЕсли отключить эту настройку, текущие будильники и созданные приложением мероприятия перестанут запускаться."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"установить, будильник, напоминание, часы"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включить"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включите режим \"Не беспокоить\""</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index ddfa1c5f17bb..3c79bf38ccd8 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ක්ලිප් සීමා, මායිම්, ආදිය පෙන්වන්න."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"බල RTL පිරිසැලසුම් දිශාව"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"සියලු පෙදෙසි සඳහා RTL වෙත බල තිර පිරිසැලසුම"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"කවුළු මට්. බොඳ කි. ඉඩ දෙ."</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA බල කරන්න"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 යෙදුම්හි 4x MSAA සබල කරන්න"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"සෘජුකෝණාස්‍ර-නොවන ක්ලිප් මෙහෙයුම් නිදොස් කරන්න"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"එලාම සහ සිහිකැඳවීම්"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"එලාම සහ සිහිකැඳවීම් සැකසීමට ඉඩ දෙන්න"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"එලාම සහ සිහිකැඳවීම්"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"එලාම සැකසීමට සහ වෙනත් ක්‍රියා කාල සටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. ඔබ ඔබගේ දුරකථනය භාවිත නොකරන විට මෙම යෙදුම භාවිත කළ හැකිය, එය බැටරිය වැඩියෙන් භාවිත කළ හැකිය. මෙම අවසරය ක්‍රියාවිරහිත නම්, මෙම යෙදුම සාමාන්‍ය ආකාරයට ක්‍රියා නොකළ හැකි අතර, එහි එලාම කාල සටහන්ගත කර ඇති පරිදි ක්‍රියා නොකරනු ඇත."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"එලාම සැකසීමට සහ වෙනත් ක්‍රියා කාල සටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. ඔබ ඔබගේ ටැබ්ලටය භාවිත නොකරන විට මෙම යෙදුම භාවිත කළ හැකිය, එය බැටරිය වැඩියෙන් භාවිත කළ හැකිය. මෙම අවසරය ක්‍රියාවිරහිත නම්, මෙම යෙදුම සාමාන්‍ය ආකාරයට ක්‍රියා නොකළ හැකි අතර, එහි එලාම කාල සටහන්ගත කර ඇති පරිදි ක්‍රියා නොකරනු ඇත."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"එලාම සැකසීමට සහ වෙනත් ක්‍රියා කාල සටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. ඔබ ඔබගේ උපාංගය භාවිත නොකරන විට මෙම යෙදුම භාවිත කළ හැකිය, එය බැටරිය වැඩියෙන් භාවිත කළ හැකිය. මෙම අවසරය ක්‍රියාවිරහිත නම්, මෙම යෙදුම සාමාන්‍ය ආකාරයට ක්‍රියා නොකළ හැකි අතර, එහි එලාම කාල සටහන්ගත කර ඇති පරිදි ක්‍රියා නොකරනු ඇත."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"එලාම සැකසීමට සහ කාල සංවේදී ක්‍රියා කාලසටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. මෙය පසුබිමේ ධාවනය වීමට යෙදුමට ඉඩ දෙයි, එය වැඩි බැටරිය වැඩියෙන් භාවිත කළ හැකිය.\n\nමෙම අවසරය ක්‍රියාවිරහිත නම්, මෙම යෙදුම මඟින් සැලසුම් කර ඇති තිබෙන එලාම සහ වේලාව පදනම් කර ගත් සිදුවීම් ක්‍රියා නොකරනු ඇත."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"කාල සටහන, එලාමය, සිහිකැඳවීම, ඔරලෝසුව"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ක්‍රියාත්මක කරන්න"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"බාධා නොකරන්න ක්‍රියාත්මක කරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 0d04d69c0702..5be0d993e7ce 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Zobraziť vo výstrižku ohraničenie, okraje a pod."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Rozloženie sprava doľava"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vynútiť pre všetky jazyky rozloženie obrazovky sprava doľava"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Povolenie rozmazania na úrovni okna"</string>
<string name="force_msaa" msgid="4081288296137775550">"Vynútiť 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Povoliť 4x MSAA v aplikáciách OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Ladiť operácie s neobdĺžnikovými výstrižkami"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Budíky a pripomenutia"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Povoliť nastavovanie budíkov a pripomenutí"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a pripomenutia"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Povoľte tejto aplikácii nastavovať budíky a plánovať ďalšie akcie. Táto aplikácia môže byť spustená, keď nepoužívate telefón, čo môže zvýšiť spotrebu batérie. Ak je toto povolenie vypnuté, daná aplikácia nemusí správne fungovať a jej budíky nebudú aktivované podľa plánu."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Povoľte tejto aplikácii nastavovať budíky a plánovať ďalšie akcie. Táto aplikácia môže byť spustená, keď nepoužívate tablet, čo môže zvýšiť spotrebu batérie. Ak je toto povolenie vypnuté, daná aplikácia nemusí správne fungovať a jej budíky nebudú aktivované podľa plánu."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Povoľte tejto aplikácii nastavovať budíky a plánovať ďalšie akcie. Táto aplikácia môže byť spustená, keď nepoužívate zariadenie, čo môže zvýšiť spotrebu batérie. Ak je toto povolenie vypnuté, daná aplikácia nemusí správne fungovať a jej budíky nebudú aktivované podľa plánu."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povoľte tejto aplikácii nastavovať budíky a plánovať akcie s časovým obmedzením. Aplikácii to umožní pracovať na pozadí, čo môže zvýšiť spotrebu batérie.\n\nAk je toto povolenie vypnuté, súčasné budíky a udalosti s časovým obmedzením naplánované touto aplikáciu nebudú fungovať."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, pripomenutie, hodiny"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnúť"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapnite režim bez vyrušení"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 796b9386bfec..07e367bab045 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Pokaži meje obrezovanja, obrobe ipd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Vsili od desne proti levi"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vsili smer postavitve na zaslonu od desne proti levi za vse jezike."</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Dovoli zameglitve na ravni okna"</string>
<string name="force_msaa" msgid="4081288296137775550">"Vsili 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"V aplikacijah OpenGL ES 2.0 omogoči 4x MSAA."</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Odpravljanje težav s postopki nepravokotnega izrezovanja"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi in opomniki"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Dovoli nastavljanje alarmov in opomnikov"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi in opomniki"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje drugih dejanj. Ta aplikacija je lahko v uporabi, ko ne uporabljate telefona, kar lahko povzroči večjo porabo energije baterije. Če je to dovoljenje izklopljeno, ta aplikacija morda ne bo normalno delovala in se zato alarmi ne bodo sprožili po urniku."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje drugih dejanj. Ta aplikacija je lahko v uporabi, ko ne uporabljate tabličnega računalnika, kar lahko povzroči večjo porabo energije baterije. Če je to dovoljenje izklopljeno, ta aplikacija morda ne bo normalno delovala in se zato alarmi ne bodo sprožili po urniku."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje drugih dejanj. Ta aplikacija je lahko v uporabi, ko ne uporabljate naprave, kar lahko povzroči večjo porabo energije baterije. Če je to dovoljenje izklopljeno, ta aplikacija morda ne bo normalno delovala in se zato alarmi ne bodo sprožili po urniku."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje časovno občutljivih dejanj. S tem aplikaciji omogočite izvajanje v ozadju, kar bo morda povečalo porabo energije baterije.\n\nČe je to dovoljenje izklopljeno, obstoječi alarmi in časovno občutljivi dogodki, ki jih nastavi ta aplikacija, ne bodo delovali."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"načrtovanje, urnik, alarm, opomnik, ura"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vklopi"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vklop načina »Ne moti«"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 99d5c7123a4e..1f30a02eb155 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Shfaq konturet e klipit, hapësirat etj."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Detyro drejtimin e shkrimit nga e djathta në të majtë"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Ndrysho me detyrim drejtimin e planit të ekranit nga e djathta në të majtë për të gjitha vendet"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Lejo turbullimet në nivel dritareje"</string>
<string name="force_msaa" msgid="4081288296137775550">"Detyro 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktivizo 4x MSAA në aplikacionet OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Korrigjo veprimet mbi klipet jodrejtkëndore"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmet dhe alarmet rikujtuese"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Lejo caktimin e alarmeve dhe alarmeve rikujtuese"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmet dhe alarmet rikujtuese"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Lejo që ky aplikacion të caktojë alarme dhe të planifikojë veprime të tjera. Ky aplikacion mund të përdoret kur ti nuk e përdor telefonin, gjë që mund të përdorë më shumë bateri. Nëse leja është joaktive, ky aplikacion mund të mos funksionojë në mënyrë normale dhe alarmet e tij nuk do të punojnë siç janë planifikuar."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Lejo që ky aplikacion të caktojë alarme dhe të planifikojë veprime të tjera. Ky aplikacion mund të përdoret kur ti nuk e përdor tabletin, gjë që mund të përdorë më shumë bateri. Nëse leja është joaktive, ky aplikacion mund të mos funksionojë në mënyrë normale dhe alarmet e tij nuk do të punojnë siç janë planifikuar."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Lejo që ky aplikacion të caktojë alarme dhe të planifikojë veprime të tjera. Ky aplikacion mund të përdoret kur ti nuk e përdor pajisjen, gjë që mund të përdorë më shumë bateri. Nëse leja është joaktive, ky aplikacion mund të mos funksionojë në mënyrë normale dhe alarmet e tij nuk do të punojnë siç janë planifikuar."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planifiko, alarm, alarm rikujtues, ora"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivizo"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivizo \"Mos shqetëso\""</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 9830ddb5f2ab..11adbe529ff4 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -236,7 +236,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Повежите се на WiFi мрежу"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отклањање грешака, програмер"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Пречица за извештај о грешкама"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Приказује дугме у менију напајања за прављење извештаја о грешкама"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Приказује дугме у менију дугмета за укључивање за прављење извештаја о грешкама"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Не закључавај"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Екран неће бити у режиму спавања током пуњења"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Омогући snoop евид. за Bluetooth HCI"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Приказује границе клипа, маргине итд."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Наметни смер распореда здесна налево"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Намеће смер распореда екрана здесна налево за све локалитете"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Дозволи замагљења прозора"</string>
<string name="force_msaa" msgid="4081288296137775550">"Наметни 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Омогућава 4x MSAA у OpenGL ES 2.0 апликацијама"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Отклони грешке исецања области неправоугаоног облика"</string>
@@ -509,9 +508,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Аларми и подсетници"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Омогући подешавање аларма и подсетника"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и подсетници"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Омогућите овој апликацији да подешава аларме и заказује друге радње. Ова апликација може да се користи када не користите телефон, што може да додатно троши батерију. Ако је ова дозвола искључена, ова апликација можда неће радити нормално и њени аларми неће радити по распореду."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Омогућите овој апликацији да подешава аларме и заказује друге радње. Ова апликација може да се користи када не користите таблет, што може да додатно троши батерију. Ако је ова дозвола искључена, ова апликација можда неће радити нормално и њени аларми неће радити по распореду."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Омогућите овој апликацији да подешава аларме и заказује друге радње. Ова апликација може да се користи када не користите уређај, што може да додатно троши батерију. Ако је ова дозвола искључена, ова апликација можда неће радити нормално и њени аларми неће радити по распореду."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Омогућите овој апликацији да подешава аларме и заказује временски осетљиве радње. То омогућава да апликација буде покренута у позадини, што може да троши више батерије.\n\nАко је ова дозвола искључена, постојећи аларми и догађаји засновани на времену заказани помоћу ове апликације неће радити."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"заказати, аларм, подсетник, сат"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Укључи"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Укључите режим Не узнемиравај"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 12080222b30f..f4b92afa216e 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Visa gränser för videoklipp, marginaler m.m."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Tvinga fram RTL-layout"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Tvinga fram RTL-skärmlayout (hö–vä) för alla språk"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Tillåt oskärpa på fönsternivå"</string>
<string name="force_msaa" msgid="4081288296137775550">"Tvinga 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktivera 4x MSAA i OpenGL ES 2.0-appar"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Felsök icke-rektangulära urklippsåtgärder"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarm och påminnelser"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Tillåt att alarm och påminnelser ställs in"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarm och påminnelser"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Tillåt att den här appen ställer in alarm och schemalägger andra åtgärder. Appen kan användas när du inte använder telefonen, vilket drar mer batteri. Om behörigheten är inaktiverad kanske appen inte fungerar som den ska och dess alarm fungerar inte enligt schemat."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Tillåt att den här appen ställer in alarm och schemalägger andra åtgärder. Appen kan användas när du inte använder surfplattan, vilket drar mer batteri. Om behörigheten är inaktiverad kanske appen inte fungerar som den ska och dess alarm fungerar inte enligt schemat."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Tillåt att den här appen ställer in alarm och schemalägger andra åtgärder. Appen kan användas när du inte använder enheten, vilket drar mer batteri. Om behörigheten är inaktiverad kanske appen inte fungerar som den ska och dess alarm fungerar inte enligt schemat."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillåt att den här appen ställer in alarm och schemalägger tidskänsliga åtgärder. Om du tillåter detta kan appen köras i bakgrunden, vilket kan dra mer batteri.\n\nOm behörigheten är inaktiverad fungerar inte befintliga alarm och tidsbaserade händelser som schemalagts av den här appen."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schema, alarm, påminnelse, klocka"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivera"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivera Stör ej."</string>
@@ -525,7 +522,7 @@
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Fråga varje gång"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Tills du inaktiverar funktionen"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Nyss"</string>
- <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Telefonens högtalare"</string>
+ <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Telefonhögtalare"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Den här telefonen"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 0b49cf57ee33..2625a414ebbf 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Onyesha mipaka ya picha, kingo, nk."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Lazimisha uelekezaji wa muundo wa RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Lazimisha mkao wa skrini uwe wa kulia kwenda kushoto kwa lugha zote"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Ruhusu ukungu wa kiwango cha dirisha"</string>
<string name="force_msaa" msgid="4081288296137775550">"Lazimisha 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Wezesha 4x MSAA katika programu za OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Tatua uendeshaji wa klipu usio mstatili"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ving\'ora na vikumbusho"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Ruhusu iweke kengele na vikumbusho"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Kengele na vikumbusho"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine. Programu hii inaweza kutumika wakati hutumii simu yako, hali inayoweza kutumia chaji nyingi ya betri. Ikiwa ruhusa hii itazimwa, huenda programu hii isifanye kazi ipasavyo, na kengele zake hazitafanya kazi kama zilivyoratibiwa."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine. Programu hii inaweza kutumika wakati hutumii kompyuta yako kibao, hali inayoweza kutumia chaji nyingi ya betri. Ikiwa ruhusa hii itazimwa, huenda programu hii isifanye kazi ipasavyo, na kengele zake hazitafanya kazi kama zilivyoratibiwa."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine. Programu hii inaweza kutumika wakati hutumii kifaa chako, hali inayoweza kutumia chaji nyingi ya betri. Ikiwa ruhusa hii itazimwa, huenda programu hii isifanye kazi ipasavyo, na kengele zake hazitafanya kazi kama zilivyoratibiwa."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine vinavyotegemea wakati. Hatua hii inairuhusu programu itumike chinichini, hali inayoweza kutumia chaji nyingi ya betri.\n\nIkiwa ruhusa hii itazimwa, kengele zilizopo na ratiba za vitendo vinavyotegemea wakati zilizowekwa na programu hii hazitafanya kazi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ratiba, kengele, kikumbusho, saa"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Washa"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Washa kipengele cha Usinisumbue"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index a829ab214c88..612fd700031e 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"கிளிப் எல்லைகள், ஓரங்கள், மேலும் பலவற்றைக் காட்டு"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL தளவமைப்பின் திசையை வலியுறுத்து"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"எல்லா மொழிகளுக்கும் திரையின் தளவமைப்பு திசையை RTL க்கு மாற்று"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"திரை-நிலை மங்கலை அனுமதி"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ஐ வலியுறுத்து"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 பயன்பாடுகளில் 4x MSAA ஐ இயக்கு"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"செவ்வகம் அல்லாத கிளிப் செயல்பாடுகளைப் பிழைத்திருத்து"</string>
@@ -509,9 +508,7 @@
<!-- unknown quoting pattern: original -1, translation 1 -->
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"அலாரங்கள் &amp;amp; நினைவூட்டல்களை அமைக்க அனுமதித்தல்"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"அலாரங்கள் &amp; நினைவூட்டல்கள்"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"அலாரங்களை அமைக்கவும் பிற செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். உங்கள் மொபைலை உபயோகிக்காதபோதும் இந்த ஆப்ஸ் பயன்படுத்தப்படக்கூடும், இதனால் பேட்டரி அதிகமாகப் பயன்படுத்தப்படலாம். ஆப்ஸுக்கான அனுமதி முடக்கப்பட்டிருந்தால், அது இயல்பாகச் செயல்படாமல் போகலாம். மேலும் இதன் அலாரங்களும் திட்டமிட்டபடி இயங்காது."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"அலாரங்களை அமைக்கவும் பிற செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். உங்கள் டேப்லெட்டை உபயோகிக்காதபோதும் இந்த ஆப்ஸ் பயன்படுத்தப்படக்கூடும், இதனால் பேட்டரி அதிகமாகப் பயன்படுத்தப்படலாம். ஆப்ஸுக்கான அனுமதி முடக்கப்பட்டிருந்தால், அது இயல்பாகச் செயல்படாமல் போகலாம். மேலும் இதன் அலாரங்களும் திட்டமிட்டபடி இயங்காது."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"அலாரங்களை அமைக்கவும் பிற செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். உங்கள் சாதனத்தை உபயோகிக்காதபோதும் இந்த ஆப்ஸ் பயன்படுத்தப்படக்கூடும், இதனால் பேட்டரி அதிகமாகப் பயன்படுத்தப்படலாம். ஆப்ஸுக்கான அனுமதி முடக்கப்பட்டிருந்தால், அது இயல்பாகச் செயல்படாமல் போகலாம். மேலும் இதன் அலாரங்களும் திட்டமிட்டபடி இயங்காது."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"அலாரங்களை அமைக்கவும் குறிப்பிட்ட கால இடைவெளியில் செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். இது ஆப்ஸ் பின்னணியில் இயங்குவதை அனுமதிக்கும், இதற்காக அதிக பேட்டரியைப் பயன்படுத்தக்கூடும்.\n\nஇந்த அனுமதி முடக்கப்பட்டிருந்தால் இந்த ஆப்ஸ் மூலம் திட்டமிடப்பட்ட ஏற்கெனவே அமைத்த அலாரங்களும் நேர அடிப்படையிலான நிகழ்வுகளும் வேலை செய்யாது."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"திட்டமிடல், அலாரம், நினைவூட்டல், கடிகாரம்"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ஆன் செய்"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"தொந்தரவு செய்ய வேண்டாம் என்பதை ஆன் செய்யும்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 83ff62044aca..7f596e301b05 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -211,7 +211,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi-Fi కనెక్ట్ అయి ఉన్నప్పుడు, డీబగ్ మోడ్‌లో ఉంచు"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"ఎర్రర్"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"వైర్‌లెస్ డీబగ్గింగ్"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"అందుబాటులో వున్న పరికరాలను చూడటానికి, ఉపయోగించడానికి, వైర్‌లెస్ డీబగ్గింగ్‌ను ఆన్ చేయండి"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"అందుబాటులో ఉన్న పరికరాలను చూడటానికి, ఉపయోగించడానికి, వైర్‌లెస్ డీబగ్గింగ్‌ను ఆన్ చేయండి"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR కోడ్‌తో పరికరాన్ని పెయిర్ చేయండి"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR కోడ్ స్కానర్‌ను ఉపయోగించి కొత్త పరికరాలను పెయిర్ చేయండి"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"పెయిరింగ్ కోడ్‌తో పరికరాన్ని పెయిర్ చేయండి"</string>
@@ -226,7 +226,7 @@
<string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"పరికరంతో పెయిర్ చేయండి"</string>
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi పెయిరింగ్ కోడ్"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"పెయిరింగ్ విఫలమైంది"</string>
- <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"పరికరం అదే నెట్‌వర్క్‌కు కనెక్ట్ అయి వుందో లేదో సరి చూసుకోండి."</string>
+ <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"పరికరం అదే నెట్‌వర్క్‌కు కనెక్ట్ చేయబడి ఉందని నిర్ధారించుకోండి."</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR కోడ్‌ను స్కాన్ చేయడం ద్వారా Wi-Fiని ఉపయోగించి పరికరాన్ని పెయిర్ చెయ్యండి"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"పరికరం పెయిర్ చేయబడుతోంది…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"పరికరాన్ని పెయిర్ చేయడం విఫలమైంది. QR కోడ్ తప్పుగా ఉండడం గాని, లేదా పరికరం అదే నెట్‌వర్క్‌కు కనెక్ట్ అయి లేకపోవడం గాని జరిగింది."</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"క్లిప్ సరిహద్దులు, అంచులు మొ. చూపు"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL లేఅవుట్ దిశను నిర్బంధం చేయండి"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"అన్ని లొకేల్‌ల కోసం RTLకి స్క్రీన్ లేఅవుట్ దిశను నిర్భందించు"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించు"</string>
<string name="force_msaa" msgid="4081288296137775550">"నిర్భందం 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్‌లలో 4x MSAAను ప్రారంభించండి"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"దీర్ఘ చతురస్రం కాని క్లిప్ చర్యలను డీబగ్ చేయండి"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"అలారాలు, రిమైండర్‌లు"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"అలారాలు, రిమైండర్‌లను సెట్ చేయడానికి అనుమతించండి"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"అలారాలు &amp; రిమైండర్‌లు"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"అలారాలను సెట్ చేయడానికి, ఇతర చర్యలను షెడ్యూల్ చేయడానికి ఈ యాప్‌ను అనుమతించండి. మీ ఫోన్‌ను మీరు ఉపయోగించనప్పుడు కూడా ఈ యాప్ ఉపయోగించబడవచ్చు, తద్వారా ఎక్కువ బ్యాటరీని ఉపయోగించవచ్చు. ఈ అనుమతిని ఆఫ్ చేస్తే, ఈ యాప్ సాధారణ రీతిలో పనిచేయకపోవచ్చు, దాని అలారాలు షెడ్యూల్ ప్రకారం పనిచేయవు."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"అలారాలను సెట్ చేయడానికి, ఇతర చర్యలను షెడ్యూల్ చేయడానికి ఈ యాప్‌ను అనుమతించండి. మీరు మీ టాబ్లెట్‌ను ఉపయోగించనప్పుడు ఈ యాప్ ఉపయోగించబడవచ్చు, ఇది ఎక్కువ బ్యాటరీని ఉపయోగించవచ్చు. ఈ అనుమతిని ఆఫ్ చేసినట్లైతే, ఈ యాప్ సాధారణంగా పనిచేయకపోవచ్చు అలాగే దాని అలారాలు షెడ్యూల్ ప్రకారం పనిచేయవు."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"అలారాలను సెట్ చేయడానికి, ఇతర చర్యలను షెడ్యూల్ చేయడానికి ఈ యాప్‌ను అనుమతించండి. మీరు మీ పరికరాన్ని ఉపయోగించనప్పుడు ఈ యాప్ ఉపయోగించబడవచ్చు, ఇది ఎక్కువ బ్యాటరీని ఉపయోగించవచ్చు. ఈ అనుమతిని ఆఫ్ చేసినట్లైతే, ఈ యాప్ సాధారణంగా పనిచేయకపోవచ్చు అలాగే దాని అలారాలు షెడ్యూల్ ప్రకారం పనిచేయవు."</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"షెడ్యూల్, అలారం, రిమైండర్, గడియారం"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ఆన్ చేయండి"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"అంతరాయం కలిగించవద్దును ఆన్ చేయండి"</string>
@@ -563,7 +561,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="add_user_failed" msgid="4809887794313944872">"కొత్త యూజర్‌ను క్రియేట్ చేయడం విఫలమైంది"</string>
<string name="user_nickname" msgid="262624187455825083">"మారుపేరు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index f721f1514a2b..3851ccb0c8a2 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"แสดงหน้าปกคลิป ขอบ ฯลฯ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"บังคับทิศทางการจัดวาง RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"บังคับทิศทางการจัดวางหน้าจอเป็น RTL สำหรับทุกภาษา"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"อนุญาตการเบลอระดับหน้าต่าง"</string>
<string name="force_msaa" msgid="4081288296137775550">"บังคับใช้ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"เปิดใช้งาน 4x MSAA ในแอปพลิเคชัน OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"แก้ไขการทำงานของคลิปที่ไม่ใช่สี่เหลี่ยม"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"การปลุกและการช่วยเตือน"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"อนุญาตให้ตั้งปลุกและการช่วยเตือน"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"การปลุกและการช่วยเตือน"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"อนุญาตให้แอปตั้งปลุกและกำหนดเวลาการดำเนินการอื่นๆ ระบบอาจใช้แอปนี้แม้คุณจะไม่ได้ใช้โทรศัพท์อยู่ จึงอาจทำให้เปลืองแบตเตอรี่มากขึ้น การปิดสิทธิ์นี้จะทำให้แอปทำงานไม่ปกติและการปลุกไม่ทำงานตามกำหนดเวลา"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"อนุญาตให้แอปตั้งปลุกและกำหนดเวลาการดำเนินการอื่นๆ ระบบอาจใช้แอปนี้แม้คุณจะไม่ได้ใช้แท็บเล็ตอยู่ จึงอาจทำให้เปลืองแบตเตอรี่มากขึ้น การปิดสิทธิ์นี้จะทำให้แอปทำงานไม่ปกติและการปลุกไม่ทำงานตามกำหนดเวลา"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"อนุญาตให้แอปตั้งปลุกและกำหนดเวลาการดำเนินการอื่นๆ ระบบอาจใช้แอปนี้แม้คุณจะไม่ได้ใช้อุปกรณ์อยู่ จึงอาจทำให้เปลืองแบตเตอรี่มากขึ้น การปิดสิทธิ์นี้จะทำให้แอปทำงานไม่ปกติและการปลุกไม่ทำงานตามกำหนดเวลา"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"อนุญาตให้แอปนี้ตั้งปลุกและกำหนดเวลาการดำเนินการที่ต้องคำนึงถึงเวลาเป็นสำคัญ สิทธิ์นี้ช่วยให้แอปทำงานในเบื้องหลังได้ จึงอาจทำให้ใช้แบตเตอรี่มากขึ้น\n\nหากปิดใช้สิทธิ์นี้ การปลุกที่มีอยู่และกิจกรรมที่ต้องคำนึงถึงเวลาเป็นสำคัญซึ่งแอปนี้กำหนดเวลาไว้จะไม่ทำงาน"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"กำหนดเวลา การปลุก การช่วยเตือน นาฬิกา"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"เปิด"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"เปิด \"ห้ามรบกวน\""</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 57f01a3c57df..a381c351c98c 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Ipakita ang mga hangganan ng clip, margin, atbp."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Ipilit ang RTL na dir. ng layout"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Ipilit ang RTL na direksyon ng screen layout sa lahat ng lokal"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Payagan ang pag-blur sa antas ng window"</string>
<string name="force_msaa" msgid="4081288296137775550">"Puwersahin ang 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Paganahin ang 4x MSAA sa OpenGL ES 2.0 na apps"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"I-debug ang di-parihabang mga clip operation"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Mga alarm at paalala"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Payagan ang pagtakda ng mga alarm at paalala"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Mga alarm at paalala"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng iba pang aksyon. Posibleng gamitin ang app na ito kapag hindi mo ginagamit ang iyong telepono, na posibleng gumamit ng mas maraming baterya. Kung naka-off ang pahintulot na ito, posibleng hindi gumana nang normal ang app na ito, at hindi gagana ang mga alarm nito gaya ng nakaiskedyul."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng iba pang aksyon. Posibleng gamitin ang app na ito kapag hindi mo ginagamit ang iyong tablet, na posibleng gumamit ng mas maraming baterya. Kung naka-off ang pahintulot na ito, posibleng hindi gumana nang normal ang app na ito, at hindi gagana ang mga alarm nito gaya ng nakaiskedyul."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng iba pang aksyon. Posibleng gamitin ang app na ito kapag hindi mo ginagamit ang iyong device, na posibleng gumamit ng mas maraming baterya. Kung naka-off ang pahintulot na ito, posibleng hindi gumana nang normal ang app na ito, at hindi gagana ang mga alarm nito gaya ng nakaiskedyul."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng mga pagkilos na may limitadong oras. Papayagan nitong tumakbo ang app sa background, na posibleng gumamit ng mas maraming baterya.\n\nKung naka-off ang pahintulot na ito, hindi gagana ang mga kasalukuyang alarm at event na nakabatay sa oras na naiskedyul ng app na ito."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"iskedyul, alarm, paalala, orasan"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"I-on"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"I-on ang Huwag Istorbohin"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 50679902c5ee..03efe82b0c93 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Klip sınırlarını, kenar boşluklarını vb. göster"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Sağdan sola düzenini zorla"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Tüm yerel ayarlar için sağdan sola ekran düzenini zorlar"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Pencere bulanıklaştırmaya izin ver"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA\'yı zorla"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 uygulamalarda 4x MSAA\'yı etkinleştir"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Dikdörtgen olmayan kırpma işlemlerinde hata ayıkla"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmlar ve hatırlatıcılar"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Alarm ve hatırlatıcı ayarlanmasına izin ver"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmlar ve hatırlatıcılar"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Bu uygulamanın, alarmlar kurup başka işlemler programlamasına izin verir. Telefonunuzu kullanmadığınız sırada bu uygulama kullanılabilir. Bu da daha fazla pil kullanımına neden olabilir. Bu izin kapatılırsa hem bu uygulama işlevini normal şekilde yerine getirmeyebilir hem de alarmları programladığı gibi çalışmayabilir."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Bu uygulamanın, alarmlar kurup başka işlemler programlamasına izin verir. Tabletinizi kullanmadığınız sırada bu uygulama kullanılabilir. Bu da daha fazla pil kullanımına neden olabilir. Bu izin kapatılırsa hem bu uygulama işlevini normal şekilde yerine getirmeyebilir hem de alarmları programladığı gibi çalışmayabilir."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Bu uygulamanın, alarmlar kurup başka işlemler programlamasına izin verir. Cihazınızı kullanmadığınız sırada bu uygulama kullanılabilir. Bu da daha fazla pil kullanımına neden olabilir. Bu izin kapatılırsa hem bu uygulama işlevini normal şekilde yerine getirmeyebilir hem de alarmları programladığı gibi çalışmayabilir."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu uygulamanın alarmlar kurmasına ve zamana bağlı işlemler programlamasına izin verin. Bu izin, uygulamanın arka planda çalışmasına olanak sağlayarak daha fazla pil harcanmasına neden olabilir.\n\nBu izin verilmezse bu uygulama tarafından programlanmış mevcut alarmlar ve zamana bağlı etkinlikler çalışmaz."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"program, alarm, hatırlatıcı, saat"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aç"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Rahatsız Etmeyin\'i açın"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 061cacea775c..e737c7dc7089 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Показувати межі роликів, поля тощо"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Макет письма справа наліво"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Застосовувати макет письма справа наліво для всіх мов"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Дозволити розмиття вікон"</string>
<string name="force_msaa" msgid="4081288296137775550">"Примус. запустити 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Увімкнути 4x MSAA в програмах OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Налагодити непрямокутну обрізку"</string>
@@ -510,9 +509,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будильники й нагадування"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Дозволити встановлювати будильники й нагадування"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будильники й нагадування"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Дозвольте цьому додатку встановлювати будильники й планувати інші події. Цей додаток може працювати, коли ви не користуєтеся телефоном. Через це акумулятор може розряджатися швидше. Якщо цей дозвіл не надано, додаток не зможе працювати належно й будильники не спрацьовуватимуть за графіком."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Дозвольте цьому додатку встановлювати будильники й планувати інші події. Цей додаток може працювати, коли ви не користуєтеся планшетом. Через це акумулятор може розряджатися швидше. Якщо цей дозвіл не надано, додаток не зможе працювати належно й будильники не спрацьовуватимуть за графіком."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Дозвольте цьому додатку встановлювати будильники й планувати інші події. Цей додаток може працювати, коли ви не користуєтеся пристроєм. Через це акумулятор може розряджатися швидше. Якщо цей дозвіл не надано, додаток не зможе працювати належно й будильники не спрацьовуватимуть за графіком."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволити цьому додатку налаштовувати будильники й створювати розклад дій. Додаток зможе працювати у фоновому режимі й використовувати більше заряду акумулятора.\n\nЯкщо вимкнути такий дозвіл, наявні будильники й дії, створені цим додатком, не працюватимуть."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"запланувати, будильник, нагадування, годинник"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Увімкнути"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Увімкнути режим \"Не турбувати\""</string>
@@ -527,7 +524,7 @@
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Запитувати щоразу"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"Доки не вимкнути"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Щойно"</string>
- <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Динамік телефона"</string>
+ <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Динамік"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Цей телефон"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Не вдається підключитися. Перезавантажте пристрій."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Дротовий аудіопристрій"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 6eb3c400bbf4..45e9f4f91a4a 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"کلپ باؤنڈز، حاشیے وغیرہ دکھائیں"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"‏RTL لے آؤٹ سمت زبردستی نافذ کریں"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"‏سبھی زبانوں کیلئے اسکرین لے آؤٹ کی سمت کو RTL پر مجبور کریں"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"ونڈو کی سطح پر دھندلاپن کی اجازت دیں"</string>
<string name="force_msaa" msgid="4081288296137775550">"‏4x MSAA زبردستی نافذ کریں"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"‏OpenGL ES 2.0 ایپس میں 4x MSAA فعال کریں"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"غیر مستطیل نما کلپ آپریشنز ڈیبگ کریں"</string>
@@ -508,9 +507,8 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"الارمز اور یاد دہانیاں"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"الارمز اور یاد دہانیاں سیٹ کرنے کی اجازت دیں"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"الارمز اور یاد دہانیاں"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"اس ایپ کو الارمز سیٹ کرنے اور دیگر کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ اس ایپ کا استعمال اس وقت کیا جا سکتا ہے جب آپ اپنا آلہ استعمال نہ کر رہے ہوں جس میں زیادہ بیٹری کا استعمال ہو سکتا ہے۔ اجازت غیر فعال ہونے کی صورت میں ہو سکتا ہے یہ ایپ عام طور پر کام نہ کرے اور اس کے الارمز شیڈول کے مطابق کام نہیں کریں گے۔"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"اس ایپ کو الارمز سیٹ کرنے اور دیگر کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ اس ایپ کا استعمال اس وقت کیا جا سکتا ہے جب آپ اپنا آلہ استعمال نہ کر رہے ہوں جس میں زیادہ بیٹری کا استعمال ہو سکتا ہے۔ اجازت غیر فعال ہونے کی صورت میں ہو سکتا ہے یہ ایپ عام طور پر کام نہ کرے اور اس کے الارمز شیڈول کے مطابق کام نہیں کریں گے۔"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"اس ایپ کو الارمز سیٹ کرنے اور دیگر کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ اس ایپ کا استعمال اس وقت کیا جا سکتا ہے جب آپ اپنا آلہ استعمال نہ کر رہے ہوں جس میں زیادہ بیٹری کا استعمال ہو سکتا ہے۔ اجازت غیر فعال ہونے کی صورت میں ہو سکتا ہے یہ ایپ عام طور پر کام نہ کرے اور اس کے الارمز شیڈول کے مطابق کام نہیں کریں گے۔"</string>
+ <!-- no translation found for alarms_and_reminders_footer_title (6302587438389079695) -->
+ <skip />
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"شیڈول، الارم، یاد دہانی، گھڑی"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"آن کریں"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ڈسٹرب نہ کریں\' کو آن کریں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index ad1a91755254..96b8853dce8f 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -179,7 +179,7 @@
<string name="tts_status_checking" msgid="8026559918948285013">"Tekshirilmoqda…"</string>
<string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> sozlamalari"</string>
<string name="tts_engine_settings_button" msgid="477155276199968948">"Mexanizm sozlamalarini ishga tushirish"</string>
- <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Standart tizim"</string>
+ <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Asosiy vosita"</string>
<string name="tts_general_section_title" msgid="8919671529502364567">"Umumiy"</string>
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Standart ohang"</string>
<string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Matnni o‘qish ohangini standart holatga qaytarish."</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Klip, maydon va h.k. chegaralarini ko‘rsatish"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"O‘ngdan chapga qarab yozish"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Barcha tillarda o‘ngdan chapga qarab yozish"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Oyna xiralashga ruxsat"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAAni yoqish"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ilovasidan 4x MSAAni yoqish"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"To‘g‘ri burchakli bo‘lmagan kesishma amallarini tuzatish"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Signal va eslatmalar"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Signal va eslatmalarni sozlashga ruxsat berish"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signal va eslatmalar"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Bu ilovaga signal oʻrnatish va boshqa amallarni rejalashtirishga ruxsat berish Bu ilova telefon qoʻlingizda emasligida ham ishlaydi va batareya quvvatini koʻproq sarflaydi. Agar ruxsat berilmasa, bu ilova odatiy ishlaydi va uning signallari rejalashtirilmaydi."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Bu ilovaga signal oʻrnatish va boshqa amallarni rejalashtirishga ruxsat berish Bu ilova planshet qoʻlingizda emasligida ham ishlaydi va batareya quvvatini koʻproq sarflaydi. Agar ruxsat berilmasa, bu ilova odatiy ishlaydi va uning signallari rejalashtirilmaydi."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Bu ilovaga signal oʻrnatish va boshqa amallarni rejalashtirishga ruxsat berish Bu ilova qurilma qoʻlingizda emasligida ham ishlaydi va batareya quvvatini koʻproq sarflaydi. Agar ruxsat berilmasa, bu ilova odatiy ishlaydi va uning signallari rejalashtirilmaydi."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu ilovaga signal oʻrnatish va vaqtga asoslangan amallarni rejalashtirishga ruxsat berish. Bunda ilovaga orqa fonda ishlashiga imkon beriladi, shu sababli batareya ortiqcha sarflanishi mumkin.\n\nAgar bu ruxsat oʻchirilsa, ushbu ilova tomonidan rejalashtirilgan mavjud signallar va vaqtga asoslangan tadbirlar ishlamaydi."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"reja, signal, eslatma, soat"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Yoqish"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bezovta qilinmasin rejimini yoqing"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 2c4e97f42a4d..4509430f00e9 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -150,7 +150,7 @@
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Chia sẻ Internet"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Chia sẻ Internet và điểm phát sóng di động"</string>
<string name="managed_user_title" msgid="449081789742645723">"Tất cả ứng dụng làm việc"</string>
- <string name="user_guest" msgid="6939192779649870792">"Khách"</string>
+ <string name="user_guest" msgid="6939192779649870792">"Chế độ khách"</string>
<string name="unknown" msgid="3544487229740637809">"Không xác định"</string>
<string name="running_process_item_user_label" msgid="3988506293099805796">"Người dùng: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"Đã đặt một số ứng dụng chạy mặc định"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Hiện viền của đoạn video, lề, v.v.."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Buộc hướng bố cục phải sang trái"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Buộc hướng bố cục màn hình phải sang trái cho tất cả ngôn ngữ"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Cho phép làm mờ cửa sổ"</string>
<string name="force_msaa" msgid="4081288296137775550">"Bắt buộc 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Bật 4x MSAA trong ứng dụng OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Gỡ lỗi hoạt động của clip không phải là hình chữ nhật"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Chuông báo và lời nhắc"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Cho phép đặt chuông báo và lời nhắc"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Chuông báo và lời nhắc"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Cho phép ứng dụng này đặt chuông báo và lên lịch thực hiện các thao tác khác. Ứng dụng này có thể được sử dụng khi bạn đang không dùng điện thoại. Việc này có thể làm tiêu hao nhiều pin hơn. Nếu quyền này tắt, ứng dụng có thể hoạt động không bình thường và các chuông báo của ứng dụng sẽ không hoạt động đúng như theo lịch."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Cho phép ứng dụng này đặt chuông báo và lên lịch thực hiện các thao tác khác. Ứng dụng này có thể được sử dụng khi bạn đang không dùng máy tính bảng. Việc này có thể làm tiêu hao nhiều pin hơn. Nếu quyền này tắt, ứng dụng có thể hoạt động không bình thường và các chuông báo của ứng dụng sẽ không hoạt động đúng như theo lịch."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Cho phép ứng dụng này đặt chuông báo và lên lịch thực hiện các thao tác khác. Ứng dụng này có thể được sử dụng khi bạn đang không dùng thiết bị. Việc này có thể làm tiêu hao nhiều pin hơn. Nếu quyền này tắt, ứng dụng có thể hoạt động không bình thường và các chuông báo của ứng dụng sẽ không hoạt động đúng như theo lịch."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Cho phép ứng dụng này đặt chuông báo và lên lịch các hành động cần chính xác về thời gian. Tùy chọn này cho phép ứng dụng chạy ở chế độ nền và có thể làm tiêu hao nhiều pin.\n\nNếu không cấp quyền này, các chuông báo và sự kiện theo thời gian do ứng dụng này lên lịch sẽ không hoạt động."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"lịch biểu, chuông báo, lời nhắc, đồng hồ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bật"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bật chế độ Không làm phiền"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index d0cbcd4b1874..3e6b3c2b4afe 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"显示剪辑边界、边距等。"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"强制使用从右到左的布局方向"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"强制将所有语言区域的屏幕布局方向改为从右到左"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"允许窗口级模糊处理"</string>
<string name="force_msaa" msgid="4081288296137775550">"强制启用 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"在 OpenGL ES 2.0 应用中启用 4x MSAA"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"调试非矩形剪裁操作"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"闹钟和提醒"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"允许设置闹钟和提醒"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"闹钟和提醒"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"允许该应用设置闹钟及安排其他操作的执行时间。该应用可能会在您未使用手机时运行,以致手机的电源消耗更快。如果您关闭此权限,该应用可能无法正常运行,已设置的闹钟也无法在排定的时间响起。"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"允许该应用设置闹钟及安排其他操作的执行时间。该应用可能会在您未使用平板电脑时运行,以致平板电脑的电源消耗更快。如果您关闭此权限,该应用可能无法正常运行,已设置的闹钟也无法在排定的时间响起。"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"允许该应用设置闹钟及安排其他操作的执行时间。该应用可能会在您未使用设备时运行,以致设备电源消耗更快。如果您关闭此权限,该应用可能无法正常运行,已设置的闹钟也无法在排定的时间响起。"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允许该应用设置闹钟以及安排在特定时间执行某些操作。如此一来,该应用将在后台运行,而这可能会消耗更多电池电量。\n\n如果您关闭了此权限,该应用设置的现有闹钟将不会响起,而且该应用安排在特定时间执行的现有活动也不会执行。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"设置, 闹钟, 提醒, 时钟, schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"开启"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"开启勿扰模式"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 734a9a5d27ae..42d95b7ffeae 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"顯示剪輯範圍、邊界等"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"強制使用從右至左的版面配置方向"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"強制將所有語言代碼的畫面配置方向改為從右至左"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"允許視窗層級模糊處理"</string>
<string name="force_msaa" msgid="4081288296137775550">"強制 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"在 OpenGL ES 2.0 應用程式中啟用 4x MSAA"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"對非矩形裁剪操作進行偵錯"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"鬧鐘和提醒"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"允許設定鬧鐘和提醒"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"鬧鐘和提醒"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"允許此應用程式設定鬧鐘並安排其他操作。此應用程式可能會在您未使用手機時執行,裝置或會較耗電。如果關閉此權限,此應用程式可能無法正常運作,已設定的鬧鐘亦不會在預定的時間響起。"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"允許此應用程式設定鬧鐘並安排其他操作。此應用程式可能會在您未使用平板電腦時執行,裝置或會較耗電。如果關閉此權限,此應用程式可能無法正常運作,已設定的鬧鐘亦不會在預定的時間響起。"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"允許此應用程式設定鬧鐘並安排其他操作。此應用程式可能會在您未使用裝置時執行,裝置或會較耗電。如果關閉此權限,此應用程式可能無法正常運作,已設定的鬧鐘亦不會在預定的時間響起。"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許此應用程式設定鬧鐘及安排具時效性的操作。這讓應用程式在背景中執行,因此可能會較耗電。\n\n如果關閉此權限,此應用程式將不會在預定時間響起已設定的鬧鐘,亦不會就特定時間的活動傳送通知。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"日程表, 鬧鐘, 提醒, 時鐘"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「請勿騷擾」模式"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 17b0a92fe18f..20fa1876ef24 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -211,7 +211,7 @@
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"連上 Wi-Fi 時啟用偵錯模式"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"錯誤"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"無線偵錯"</string>
- <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"如要查看並使用可用的裝置,請開啟無線偵錯"</string>
+ <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"如要查看並使用可用的裝置,請開啟無線偵錯功能"</string>
<string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"使用 QR 圖碼配對裝置"</string>
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"使用 QR 圖碼掃描器配對新裝置"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"使用配對碼配對裝置"</string>
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"顯示剪輯範圍、邊界等"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"強制使用從右至左版面配置方向"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"強制將所有語言代碼的畫面配置方向改為從右至左"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"允許視窗層級模糊處理"</string>
<string name="force_msaa" msgid="4081288296137775550">"強制 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"在 OpenGL ES 2.0 應用程式中啟用 4x MSAA"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"針對非矩形裁剪操作進行偵錯"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"鬧鐘與提醒"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"允許設定鬧鐘和提醒"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"鬧鐘和提醒"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"允許這個應用程式設定鬧鐘及安排其他操作的執行時間。這個應用程式可能會在你未使用手機時執行,手機也許會比較耗電。如果關閉這項權限,這個應用程式可能無法正常運作,已設定的鬧鐘也不會在排定的時間響起。"</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"允許這個應用程式設定鬧鐘及安排其他操作的執行時間。這個應用程式可能會在你未使用平板電腦時執行,平板電腦也許會比較耗電。如果關閉這項權限,這個應用程式可能無法正常運作,已設定的鬧鐘也不會在排定的時間響起。"</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"允許這個應用程式設定鬧鐘及安排其他操作的執行時間。這個應用程式可能會在你未使用裝置時執行,裝置也許會比較耗電。如果關閉這項權限,這個應用程式可能無法正常運作,已設定的鬧鐘也不會在排定的時間響起。"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許這個應用程式設定鬧鐘及安排有時效性的動作。這麼做會讓用程式在背景執行,可能比較耗電。\n\n如果關閉這項權限,這個應用程式設定的現有鬧鐘將不會響起,而且應用程式也無法在預定的時間發出活動提醒。"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"時間表, 鬧鐘, 提醒, 時鐘"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「零打擾」模式"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 3236fd0415ad..f49d3cc9ba2d 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -353,8 +353,7 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Bonisa imikhawulo, imiphetho, njll, yesiqeshana."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Phoqelela isikhombisi-ndlela sesakhiwo se-RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Phoqelela isikhombisi-ndlela sesikrini ku-RTL kuzo zonke izifunda"</string>
- <!-- no translation found for window_blurs (6831008984828425106) -->
- <skip />
+ <string name="window_blurs" msgid="6831008984828425106">"Vumela ukufiphala kweleveli yewindi"</string>
<string name="force_msaa" msgid="4081288296137775550">"Phoqelela i-4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Nika amandla i-4x MSAA ezinhlelweni zokusebenza ze-OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Susa iphutha ekusebenzeniokungekhona unxantathu kwesiqeshana"</string>
@@ -508,9 +507,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ama-alamu nezikhumbuzi"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Vumela ukusetha ama-alamu nezikhumbuzi"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ama-alamu nezikhumbuzi"</string>
- <string name="alarms_and_reminders_footer_title" product="default" msgid="1122213569699233612">"Vumela le app isethe ama-alamu futhi ishejule nezinye izinyathelo. Le app ingasetshenziswa uma ungasebenzisi ifoni yakho, okungasebenzisa ibhethri eliningi. Uma le mvume ivaliwe, le app ingahle ingasebenzi ngokuvamile, futhi ama-alamu ayo ngeke asebenze njengokuhleliwe."</string>
- <string name="alarms_and_reminders_footer_title" product="tablet" msgid="4596201244991057839">"Vumela le app isethe ama-alamu futhi ishejule nezinye izinyathelo. Le app ingasetshenziswa uma ungasebenzisi ithebulethi yakho, okungasebenzisa ibhethri eliningi. Uma le mvume ivaliwe, le app ingahle ingasebenzi ngokuvamile, futhi ama-alamu ayo ngeke asebenze njengokuhleliwe."</string>
- <string name="alarms_and_reminders_footer_title" product="device" msgid="349578867821273761">"Vumela le app isethe ama-alamu futhi ishejule nezinye izinyathelo. Le app ingasetshenziswa uma ungasebenzisi idivayisi yakho, okungasebenzisa ibhethri eliningi. Uma le mvume ivaliwe, le app ingahle ingasebenzi ngokuvamile, futhi ama-alamu ayo ngeke asebenze njengokuhleliwe."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Vumela le app isethe ama-alamu futhi ushejule izenzo zesikhathi esizwelayo. Lokhu kuvumela i-app iqhubeke ngemuva okungasebenzisa ibhethri lakho eliningi.\n\nUma le mvume ivaliwe, ama-alamu asele nemicimbi esekelwe esikhathini ehlelwe yile app ngeke kusebenze."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ishejuli, i-alamu, isikhumbuzi, iwashi"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vula"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vula ukungaphazamisi"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java
index a5373944474c..0b3a519cd919 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java
@@ -16,8 +16,10 @@
package com.android.settingslib.enterprise;
+import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.Context;
+import android.content.DialogInterface;
import androidx.annotation.Nullable;
@@ -54,4 +56,13 @@ public interface ActionDisabledByAdminController {
* Updates the enforced admin
*/
void updateEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin, @UserIdInt int adminUserId);
+
+ /**
+ * Returns a listener for handling positive button clicks
+ */
+ @Nullable
+ default DialogInterface.OnClickListener getPositiveButtonListener(@NonNull Context context,
+ @NonNull RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
+ return null;
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
index da42e330b8b4..44cafb17e1d8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
@@ -20,6 +20,11 @@ import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.ParentalControlsUtilsInternal;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.text.TextUtils;
/**
* A factory that returns the relevant instance of {@link ActionDisabledByAdminController}.
@@ -30,10 +35,28 @@ public final class ActionDisabledByAdminControllerFactory {
* Returns the relevant instance of {@link ActionDisabledByAdminController}.
*/
public static ActionDisabledByAdminController createInstance(Context context,
- DeviceAdminStringProvider stringProvider) {
- return isFinancedDevice(context)
- ? new FinancedDeviceActionDisabledByAdminController(stringProvider)
- : new ManagedDeviceActionDisabledByAdminController(stringProvider);
+ String restriction, DeviceAdminStringProvider stringProvider) {
+ if (doesBiometricRequireParentalConsent(context, restriction)) {
+ return new BiometricActionDisabledByAdminController(stringProvider);
+ } else if (isFinancedDevice(context)) {
+ return new FinancedDeviceActionDisabledByAdminController(stringProvider);
+ } else {
+ return new ManagedDeviceActionDisabledByAdminController(stringProvider);
+ }
+ }
+
+ /**
+ * @return true if the restriction == UserManager.DISALLOW_BIOMETRIC and parental consent
+ * is required.
+ */
+ private static boolean doesBiometricRequireParentalConsent(Context context,
+ String restriction) {
+ if (!TextUtils.equals(UserManager.DISALLOW_BIOMETRIC, restriction)) {
+ return false;
+ }
+ DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+ return ParentalControlsUtilsInternal.parentConsentRequired(context, dpm,
+ BiometricAuthenticator.TYPE_ANY_BIOMETRIC, new UserHandle(UserHandle.myUserId()));
}
private static boolean isFinancedDevice(Context context) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
new file mode 100644
index 000000000000..814d5d23f458
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.enterprise;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+public class BiometricActionDisabledByAdminController extends BaseActionDisabledByAdminController {
+
+ private static final String TAG = "BiometricActionDisabledByAdminController";
+
+ // These MUST not change, as they are the stable API between here and device admin specified
+ // by the component below.
+ private static final String ACTION_LEARN_MORE = "android.settings.LEARN_MORE";
+ private static final String EXTRA_FROM_BIOMETRIC_SETUP = "from_biometric_setup";
+
+ BiometricActionDisabledByAdminController(
+ DeviceAdminStringProvider stringProvider) {
+ super(stringProvider);
+ }
+
+ @Override
+ public void setupLearnMoreButton(Context context) {
+
+ }
+
+ @Override
+ public String getAdminSupportTitle(@Nullable String restriction) {
+ return mStringProvider.getDisabledBiometricsParentConsentTitle();
+ }
+
+ @Override
+ public CharSequence getAdminSupportContentString(Context context,
+ @Nullable CharSequence supportMessage) {
+ return mStringProvider.getDisabledBiometricsParentConsentContent();
+ }
+
+ @Override
+ public DialogInterface.OnClickListener getPositiveButtonListener(@NonNull Context context,
+ @NonNull RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
+ return (dialog, which) -> {
+ Log.d(TAG, "Positive button clicked, component: " + enforcedAdmin.component);
+ final Intent intent = new Intent(ACTION_LEARN_MORE)
+ .setComponent(enforcedAdmin.component)
+ .putExtra(EXTRA_FROM_BIOMETRIC_SETUP, true)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ };
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/DeviceAdminStringProvider.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/DeviceAdminStringProvider.java
index c47d789a514d..b83837e6caf6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/DeviceAdminStringProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/DeviceAdminStringProvider.java
@@ -72,4 +72,14 @@ public interface DeviceAdminStringProvider {
* a financed device.
*/
String getDisabledByPolicyTitleForFinancedDevice();
+
+ /**
+ * Returns the dialog title for when biometrics require parental consent.
+ */
+ String getDisabledBiometricsParentConsentTitle();
+
+ /**
+ * Returns the dialog contents for when biometrics require parental consent.
+ */
+ String getDisabledBiometricsParentConsentContent();
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java
new file mode 100644
index 000000000000..766c2f5f9872
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.enterprise;
+
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCED_ADMIN;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCEMENT_ADMIN_USER_ID;
+import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DEFAULT_DEVICE_ADMIN_STRING_PROVIDER;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.UserHandle;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class BiometricActionDisabledByAdminControllerTest {
+
+ private final ActionDisabledByAdminControllerTestUtils mTestUtils =
+ new ActionDisabledByAdminControllerTestUtils();
+ private final BiometricActionDisabledByAdminController mController =
+ new BiometricActionDisabledByAdminController(DEFAULT_DEVICE_ADMIN_STRING_PROVIDER);
+
+ @Before
+ public void setUp() {
+ mController.initialize(mTestUtils.createLearnMoreButtonLauncher());
+ mController.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID);
+ }
+
+ @Test
+ public void buttonClicked() {
+ Context context = mock(Context.class);
+ ComponentName componentName = mock(ComponentName.class);
+ RestrictedLockUtils.EnforcedAdmin enforcedAdmin = new RestrictedLockUtils.EnforcedAdmin(
+ componentName, new UserHandle(UserHandle.myUserId()));
+
+ DialogInterface.OnClickListener listener =
+ mController.getPositiveButtonListener(context, enforcedAdmin);
+ assertNotNull("Biometric Controller must supply a non-null listener", listener);
+ listener.onClick(mock(DialogInterface.class), 0 /* which */);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(context).startActivity(intentCaptor.capture());
+ assertEquals("android.settings.LEARN_MORE",
+ intentCaptor.getValue().getAction());
+ assertTrue("from_biometric_setup", intentCaptor.getValue()
+ .getBooleanExtra("from_biometric_setup", false));
+ assertEquals(componentName, intentCaptor.getValue().getComponent());
+ }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java
index be3e9fcf45ea..99e13c325472 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java
@@ -30,6 +30,8 @@ class FakeDeviceAdminStringProvider implements DeviceAdminStringProvider {
static final String DEFAULT_DISABLED_BY_POLICY_CONTENT = "default_disabled_by_policy_content";
static final String DEFAULT_DISABLED_BY_POLICY_TITLE_FINANCED_DEVICE =
"default_disabled_by_policy_title_financed_device";
+ static final String DEFAULT_BIOMETRIC_TITLE = "biometric_title";
+ static final String DEFAULT_BIOMETRIC_CONTENTS = "biometric_contents";
static final DeviceAdminStringProvider DEFAULT_DEVICE_ADMIN_STRING_PROVIDER =
new FakeDeviceAdminStringProvider(/* url = */ null);
@@ -88,4 +90,15 @@ class FakeDeviceAdminStringProvider implements DeviceAdminStringProvider {
public String getDisabledByPolicyTitleForFinancedDevice() {
return DEFAULT_DISABLED_BY_POLICY_TITLE_FINANCED_DEVICE;
}
+
+ @Override
+ public String getDisabledBiometricsParentConsentTitle() {
+ return DEFAULT_BIOMETRIC_TITLE;
+ }
+
+ @Override
+ public String getDisabledBiometricsParentConsentContent() {
+ return DEFAULT_BIOMETRIC_CONTENTS;
+ }
+
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
index f197cbb2ac70..89b0fe72ca16 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
@@ -18,8 +18,6 @@ package com.android.settingslib.widget;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.when;
-
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
@@ -57,20 +55,6 @@ public class IllustrationPreferenceTest {
}
@Test
- public void isAnimating_lottieAnimationViewIsNotAnimating_shouldReturnFalse() {
- when(mAnimationView.isAnimating()).thenReturn(false);
-
- assertThat(mPreference.isAnimating()).isFalse();
- }
-
- @Test
- public void isAnimating_lottieAnimationViewIsAnimating_shouldReturnTrue() {
- when(mAnimationView.isAnimating()).thenReturn(true);
-
- assertThat(mPreference.isAnimating()).isTrue();
- }
-
- @Test
public void setMiddleGroundView_middleGroundView_shouldVisible() {
final View view = new View(mContext);
final FrameLayout layout = new FrameLayout(mContext);
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 8bc3d228f7a8..2579e7084e08 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -238,7 +238,9 @@ class ActivityLaunchAnimator(
* during the animation.
*/
@JvmStatic
- fun fromView(view: View): Controller = GhostedViewLaunchAnimatorController(view)
+ fun fromView(view: View, cujType: Int? = null): Controller {
+ return GhostedViewLaunchAnimatorController(view, cujType)
+ }
}
/**
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 4b655a1a1b02..ffb7ab4eff7c 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -14,6 +14,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroupOverlay
import android.widget.FrameLayout
+import com.android.internal.jank.InteractionJankMonitor
import kotlin.math.min
/**
@@ -29,7 +30,10 @@ import kotlin.math.min
*/
open class GhostedViewLaunchAnimatorController(
/** The view that will be ghosted and from which the background will be extracted. */
- private val ghostedView: View
+ private val ghostedView: View,
+
+ /** The [InteractionJankMonitor.CujType] associated to this animation. */
+ private val cujType: Int? = null
) : ActivityLaunchAnimator.Controller {
/** The container to which we will add the ghost view and expanding background. */
override var launchContainer = ghostedView.rootView as ViewGroup
@@ -125,6 +129,8 @@ open class GhostedViewLaunchAnimatorController(
val matrix = ghostView?.animationMatrix ?: Matrix.IDENTITY_MATRIX
matrix.getValues(initialGhostViewMatrixValues)
+
+ cujType?.let { InteractionJankMonitor.getInstance().begin(ghostedView, it) }
}
override fun onLaunchAnimationProgress(
@@ -167,6 +173,8 @@ open class GhostedViewLaunchAnimatorController(
}
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+ cujType?.let { InteractionJankMonitor.getInstance().end(it) }
+
backgroundDrawable?.wrapped?.alpha = startBackgroundAlpha
GhostView.removeGhost(ghostedView)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 298b7c38066b..7c81325d685f 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -92,5 +92,12 @@ public interface ActivityStarter {
* *after* returning to start hiding the keyguard.
*/
boolean onDismiss();
+
+ /**
+ * Whether running this action when we are locked will start an animation on the keyguard.
+ */
+ default boolean willRunAnimationOnKeyguard() {
+ return false;
+ }
}
}
diff --git a/packages/SystemUI/res/drawable/rounded_bg_full_large_radius.xml b/packages/SystemUI/res/drawable/rounded_bg_full_large_radius.xml
index aa940bde7e0d..29a014a713f7 100644
--- a/packages/SystemUI/res/drawable/rounded_bg_full_large_radius.xml
+++ b/packages/SystemUI/res/drawable/rounded_bg_full_large_radius.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?android:attr/colorBackgroundFloating" />
+ <solid android:color="?androidprv:attr/colorAccentPrimary" />
<corners android:radius="40dp" />
</shape>
diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml b/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml
index 4f97ca47513c..21b177bead11 100644
--- a/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml
+++ b/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml
@@ -32,7 +32,7 @@
android:gravity="center_vertical|right"
android:height="@dimen/rounded_slider_icon_size"
android:width="@dimen/rounded_slider_icon_size"
- android:right="@dimen/rounded_slider_icon_inset">
+ android:right="@dimen/volume_slider_icon_inset">
<rotate
android:fromDegrees="-270"
android:toDegrees="-270">
diff --git a/packages/SystemUI/res/layout/global_actions_change_panel.xml b/packages/SystemUI/res/layout/global_actions_change_panel.xml
index dffb0f011bb5..bc9c203b299a 100644
--- a/packages/SystemUI/res/layout/global_actions_change_panel.xml
+++ b/packages/SystemUI/res/layout/global_actions_change_panel.xml
@@ -14,8 +14,18 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<ImageView
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/global_actions_change_button"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/global_actions_change_message"
+ android:layout_width="wrap_content"
+ android:visibility="gone"
+ android:layout_height="wrap_content"
+ android:text="@string/global_actions_change_description" />
+ <ImageView
+ android:id="@+id/global_actions_change_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 4765b44d78c8..3f4baaf27b84 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -99,6 +99,7 @@
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
app:handleColor="?androidprv:attr/colorAccentPrimary"
app:scrimColor="@color/screenshot_crop_scrim"
+ app:containerBackgroundColor="?android:colorBackgroundFloating"
tools:background="?android:colorBackground"
tools:minHeight="100dp"
tools:minWidth="100dp" />
diff --git a/packages/SystemUI/res/layout/people_space_activity.xml b/packages/SystemUI/res/layout/people_space_activity.xml
index fa199439ec69..7102375a89bf 100644
--- a/packages/SystemUI/res/layout/people_space_activity.xml
+++ b/packages/SystemUI/res/layout/people_space_activity.xml
@@ -15,6 +15,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/top_level"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -41,7 +42,8 @@
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp"
- android:padding="24dp" />
+ android:paddingVertical="24dp"
+ android:paddingHorizontal="48dp"/>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
@@ -65,8 +67,8 @@
android:id="@+id/priority_header"
android:text="@string/priority_conversations"
android:layout_width="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
- android:textColor="?android:attr/colorAccent"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+ android:textColor="?androidprv:attr/colorAccentPrimaryVariant"
android:textSize="14sp"
android:paddingStart="16dp"
android:layout_height="wrap_content"/>
@@ -92,8 +94,8 @@
android:gravity="start"
android:text="@string/recent_conversations"
android:layout_width="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
- android:textColor="?android:attr/colorAccent"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+ android:textColor="?androidprv:attr/colorAccentPrimaryVariant"
android:textSize="14sp"
android:paddingStart="16dp"
android:layout_height="wrap_content"/>
diff --git a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
index 232cd7236113..2a4a21f5f1ab 100644
--- a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
+++ b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml
@@ -55,6 +55,7 @@
android:background="@drawable/rounded_bg_full_large_radius"
android:onClick="dismissActivity"
android:text="@string/okay"
+ android:textColor="?android:attr/textColorPrimary"
android:layout_marginBottom="60dp"
android:layout_alignParentBottom="true" />
diff --git a/packages/SystemUI/res/layout/people_space_tile_view.xml b/packages/SystemUI/res/layout/people_space_tile_view.xml
index 3e901808e66a..2a2c35dde841 100644
--- a/packages/SystemUI/res/layout/people_space_tile_view.xml
+++ b/packages/SystemUI/res/layout/people_space_tile_view.xml
@@ -13,7 +13,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/tile_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -21,7 +23,7 @@
<LinearLayout
android:orientation="vertical"
- android:background="@drawable/people_space_activity_card"
+ android:background="?androidprv:attr/colorSurface"
android:padding="12dp"
android:elevation="4dp"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 1d93f5d69da8..536b0423ce16 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -33,6 +33,7 @@
android:gravity="start"
android:textDirection="locale"
android:ellipsize="marquee"
+ android:marqueeRepeatLimit="1"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.QS.TileLabel"/>
@@ -43,6 +44,7 @@
android:gravity="start"
android:textDirection="locale"
android:ellipsize="marquee"
+ android:marqueeRepeatLimit="1"
android:singleLine="true"
android:visibility="gone"
android:textAppearance="@style/TextAppearance.QS.TileLabel.Secondary"
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
index c88703dabeea..5b9ca1b26158 100644
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
@@ -59,11 +59,16 @@
android:visibility="gone"
/>
- <LinearLayout
+ <FrameLayout
android:id="@+id/rightLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:gravity="center_vertical|end"
+ android:gravity="end"
+ >
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical|end"
>
<com.android.systemui.statusbar.phone.StatusIconContainer
android:id="@+id/statusIcons"
@@ -80,4 +85,6 @@
android:paddingEnd="2dp" />
</LinearLayout>
+ </FrameLayout>
+
</LinearLayout>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index d1c613894b8c..9784d534a163 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -381,7 +381,7 @@
<string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi qoşulu deyil"</string>
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Parlaqlıq"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"AVTO"</string>
- <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Rəngləri çevirin"</string>
+ <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Rəng inversiyası"</string>
<string name="quick_settings_color_space_label" msgid="537528291083575559">"Rəng korreksiyası rejimi"</string>
<string name="quick_settings_more_settings" msgid="2878235926753776694">"Digər ayarlar"</string>
<string name="quick_settings_more_user_settings" msgid="1064187451100861954">"İstifadəçi ayarları"</string>
@@ -968,7 +968,7 @@
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> işləyir"</string>
<string name="instant_apps_message" msgid="6112428971833011754">"Quraşdırılmadan açılan tətbiq."</string>
<string name="instant_apps_message_with_help" msgid="1816952263531203932">"Quraşdırılmadan açılan tətbiq. Ətraflı məlumat üçün klikləyin."</string>
- <string name="app_info" msgid="5153758994129963243">"Tətbiq infosu"</string>
+ <string name="app_info" msgid="5153758994129963243">"Tətbiq haqqında"</string>
<string name="go_to_web" msgid="636673528981366511">"Brauzerə daxil edin"</string>
<string name="mobile_data" msgid="4564407557775397216">"Mobil data"</string>
<string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 75593a8c5d90..d51bc7b21318 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -117,7 +117,7 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Отказ"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Споделяне"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Записването на екрана е анулирано"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Записът на екрана е запазен"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Записът е запазен"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Докоснете за преглед"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"При изтриването на записа на екрана възникна грешка"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Извличането на разрешенията не бе успешно."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 802794177445..b402402e7de4 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1085,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"খারিজ করুন"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"চালান"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> অ্যাপ খুলুন"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চালান"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%2$s</xliff:g> অ্যাপে চালান"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"সমস্যা, আবার চেষ্টা করা হচ্ছে…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index b6bfe7883906..f3d64ab56a39 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -101,7 +101,7 @@
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Spustit nahrávání?"</string>
<string name="screenrecord_description" msgid="1123231719680353736">"Při nahrávání může systém Android zaznamenávat citlivé údaje, které jsou viditelné na obrazovce nebo které jsou přehrávány na zařízení. Týká se to hesel, údajů o platbě, fotek, zpráv a zvuků."</string>
- <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrát zvuk"</string>
+ <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrávat zvuk"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk zařízení"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk ze zařízení, například hudba, hovory a vyzvánění"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
@@ -117,8 +117,8 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušit"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Nahrávání obrazovky bylo zrušeno"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky byla uložena"</string>
- <string name="screenrecord_save_text" msgid="3008973099800840163">"Nahrávku zobrazíte klepnutím"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky se uložila"</string>
+ <string name="screenrecord_save_text" msgid="3008973099800840163">"Klepnutím nahrávku zobrazíte"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Při mazání záznamu obrazovky došlo k chybě"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodařilo se načíst oprávnění"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
@@ -617,9 +617,9 @@
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítka Plocha."</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Může mít přístup k soukromým datům (například kontaktům a obsahu e-mailů)."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Připnutá aplikace může otevírat další aplikace."</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"Chcete-li tuto aplikaci odepnout, podržte tlačítka Zpět a Přehled"</string>
- <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Chcete-li tuto aplikaci odepnout, podržte tlačítka Zpět a Plocha"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Chcete-li tuto aplikaci odepnout, přejeďte prstem nahoru a podržte"</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"Aplikaci odepnete podržením tlačítek Zpět a Přehled"</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Aplikaci odepnete podržením tlačítek Zpět a Plocha"</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Aplikaci odepnete přejetím prstem nahoru a podržením"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"Rozumím"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"Ne, děkuji"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"Aplikace byla připnuta"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index e5ca0ac01cd9..0c7a7439a784 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -609,7 +609,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Dette fastholder appen på skærmen, indtil du frigør den. Stryg opad, og hold fingeren nede for at frigøre den."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Dette fastholder skærmen i visningen, indtil du frigør den. Tryk på Tilbage, og hold fingeren nede for at frigøre skærmen."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Dette fastholder skærmen i visningen, indtil du frigør den. Hold Startskærm nede for at frigøre skærmen."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Der kan stadig være adgang til personoplysninger (f.eks. kontakter og mailindhold)."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personoplysninger kan muligvis tilgås (f.eks. kontakter og mailindhold)."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"En fastgjort app kan åbne andre apps."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"Du kan frigøre denne app ved at holde knapperne Tilbage og Oversigt nede"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Du kan frigøre denne app ved at holde knapperne Tilbage og Hjem nede"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 806a33236f68..0f18757975fd 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -105,7 +105,7 @@
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio des Geräts"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Audioinhalte auf deinem Gerät, wie Musik, Anrufe und Klingeltöne"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
- <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio des Geräts und über externes Mikrofon aufnehmen"</string>
+ <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio des Geräts und über Mikrofon"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Start"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Bildschirm wird aufgezeichnet"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Bildschirm und Ton werden aufgezeichnet"</string>
@@ -616,7 +616,7 @@
<string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Zum Loslösen der App nach oben wischen und halten"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"Ok"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"Nein danke"</string>
- <string name="screen_pinning_start" msgid="7483998671383371313">"App angepinnt"</string>
+ <string name="screen_pinning_start" msgid="7483998671383371313">"Bildschirm wurde fixiert"</string>
<string name="screen_pinning_exit" msgid="4553787518387346893">"App vom Bildschirm losgelöst"</string>
<string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"Sie wird wieder eingeblendet, wenn du sie in den Einstellungen erneut aktivierst."</string>
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Weckruf"</string>
<string name="wallet_title" msgid="5369767670735827105">"Geldbörse"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Füge eine Zahlungsmethode hinzu, um noch schneller und sicherer mit deinem Smartphone zu bezahlen"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"Alle anzeigen"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"Zum Bezahlen entsperren"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"Nicht eingerichtet"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index c69f5c0e3b2a..c346bbe68438 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -609,7 +609,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up and hold to unpin."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible (such as contacts and email content)."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible, such as contacts and email content."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Pinned app may open other apps."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch and hold Back and Overview buttons"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch and hold Back and Home buttons"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 2f96c42c6bf9..b588e861639a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -609,7 +609,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up and hold to unpin."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible (such as contacts and email content)."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible, such as contacts and email content."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Pinned app may open other apps."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch and hold Back and Overview buttons"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch and hold Back and Home buttons"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index c69f5c0e3b2a..c346bbe68438 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -609,7 +609,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up and hold to unpin."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible (such as contacts and email content)."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible, such as contacts and email content."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Pinned app may open other apps."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch and hold Back and Overview buttons"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch and hold Back and Home buttons"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index c69f5c0e3b2a..c346bbe68438 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -609,7 +609,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up and hold to unpin."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible (such as contacts and email content)."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible, such as contacts and email content."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Pinned app may open other apps."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch and hold Back and Overview buttons"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch and hold Back and Home buttons"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 87f3ccd3c2d6..78eb7289c786 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -722,7 +722,7 @@
<string name="inline_block_button" msgid="479892866568378793">"Blokeatu"</string>
<string name="inline_keep_button" msgid="299631874103662170">"Jarraitu erakusten"</string>
<string name="inline_minimize_button" msgid="1474436209299333445">"Minimizatu"</string>
- <string name="inline_silent_button_silent" msgid="525243786649275816">"Soinurik gabe"</string>
+ <string name="inline_silent_button_silent" msgid="525243786649275816">"Isila"</string>
<string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Jarraitu isilik"</string>
<string name="inline_silent_button_alert" msgid="5705343216858250354">"Alertak"</string>
<string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Jarraitu jakinarazpenak bidaltzen"</string>
@@ -1006,7 +1006,7 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" eta "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> erabiltzen ari da"</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> aplikazioak darabil"</string>
<string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> aplikazioak erabili du azkenaldian"</string>
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(lanekoa)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono-deia"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 58a52fff089f..e657308da857 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Préparez-vous à faire des achats plus rapidement et de façon plus sûre avec votre téléphone"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"Tout afficher"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"Déverrouiller pour payer"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"Non configuré"</string>
@@ -767,7 +766,7 @@
<string name="feedback_silenced" msgid="9116540317466126457">"La notification a été automatiquement &lt;b&gt;abaissée à la catégorie Silencieux&lt;/b&gt; par le système."</string>
<string name="feedback_promoted" msgid="2125562787759780807">"La notification a été automatiquement &lt;b&gt;élevée d\'un niveau&lt;/b&gt; dans votre volet."</string>
<string name="feedback_demoted" msgid="951884763467110604">"La notification a été automatiquement &lt;b&gt;abaissée d\'un niveau&lt;/b&gt; dans votre volet."</string>
- <string name="feedback_prompt" msgid="3656728972307896379">"Faites part de vos commentaires au concepteur. Était-ce correct?"</string>
+ <string name="feedback_prompt" msgid="3656728972307896379">"Faites part de vos commentaires au développeur. Était-ce correct?"</string>
<string name="feedback_response" msgid="4671729244976641339">"Merci de vos commentaires!"</string>
<string name="feedback_ok" msgid="6481426753298857144">"OK"</string>
<string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Les paramètres des notifications pour <xliff:g id="APP_NAME">%1$s</xliff:g> sont ouverts"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 7e2e59163749..52c6e3360cf2 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -342,7 +342,7 @@
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Audiófonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"Brillo"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automaticamente"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automat."</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Xirar pantalla automaticamente"</string>
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"Modo <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"Rotación bloqueada"</string>
@@ -423,7 +423,7 @@
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"A opción NFC está desactivada"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"A opción NFC está activada"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Gravación da pantalla"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Gravar pant."</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Deter"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string>
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarma"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configura un método de pago para comprar de xeito máis rápido e seguro co teléfono"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"Amosar todo"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"Desbloquear para pagar"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"Sen configurar"</string>
@@ -734,8 +733,8 @@
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"Sen son nin vibración"</string>
<string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sen son nin vibración, e aparecen máis abaixo na sección de conversas"</string>
- <string name="notification_channel_summary_default" msgid="3282930979307248890">"Poderían soar ou vibrar en función da configuración do teléfono"</string>
- <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Podería soar ou vibrar en función da configuración do teléfono. Conversas desde a burbulla da aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> de forma predeterminada."</string>
+ <string name="notification_channel_summary_default" msgid="3282930979307248890">"Poderían facer que o teléfono soe ou vibre en función da súa configuración"</string>
+ <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Poderían facer que o teléfono soe ou vibre en función da súa configuración. Conversas desde a burbulla da aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> de forma predeterminada."</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantén a túa atención cun atallo flotante a este contido."</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fai que o sistema determine se a notificación debe emitir un son ou unha vibración"</string>
<string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Estado:&lt;/b&gt; ascendeuse a Predeterminada"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d7d5290d55b2..c06826ba65c4 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ઇથરનેટ"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"અલાર્મ"</string>
<string name="wallet_title" msgid="5369767670735827105">"વૉલેટ"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"તમારા ફોન વડે વધુ ઝડપી તેમજ સુરક્ષિત ખરીદીઓ કરવાની રીત સેટઅપ કરી લો"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"બધું બતાવો"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"ચુકવણી કરવા માટે અનલૉક કરો"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"કોઈ સેટઅપ કર્યું નથી"</string>
@@ -1086,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"છોડી દો"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ચલાવો"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ખોલો"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> પર <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ભૂલ, ફરી પ્રયાસ કરી રહ્યા છીએ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3f9a53e2399b..cdead4108f1c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -666,7 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ईथरनेट"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
<string name="wallet_title" msgid="5369767670735827105">"वॉलेट"</string>
- <string name="wallet_empty_state_label" msgid="7776761245237530394">"फ़ोन पर तेज़ी से और सुरक्षित तरीके से खरीदारी करने के लिए सेट अप करें"</string>
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"फ़ोन के ज़रिए तेज़ी से और सुरक्षित तरीके से खरीदारी करने के लिए सेट अप करें"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"सभी दिखाएं"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"पैसे चुकाने के लिए, डिवाइस अनलॉक करें"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"सेट अप नहीं किया गया है"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 42c522771b7f..2022281c890e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Ébresztés"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Végezze el a beállítást a telefonjával való gyorsabb és biztonságosabb vásárláshoz"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"Összes mutatása"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"Feloldás a fizetéshez"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"Nincs beállítva"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index e5ffbd3f0689..4fb191f93035 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -605,10 +605,10 @@
<string name="accessibility_output_chooser" msgid="7807898688967194183">"Փոխել արտածման սարքը"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"Հավելվածն ամրացված է"</string>
<string name="screen_pinning_description" msgid="8699395373875667743">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները:"</string>
- <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև չապամրացնեք այն: Ապամրացնելու համար հպեք և պահեք «Հետ» և «Գլխավոր էկրան» կոճակները"</string>
- <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև որ չապամրացնեք այն: Ապամրացնելու համար մատը սահեցրեք վեր և պահեք։"</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև չեղարկեք ամրացումը: Չեղարկելու համար հպեք և պահեք «Հետ» և «Գլխավոր էկրան» կոճակները"</string>
+ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Էկրանը կցուցադրվի, մինչև չեղարկեք ամրացումը: Չեղարկելու համար մատը սահեցրեք վեր և պահեք։"</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Համատեսք կոճակը:"</string>
- <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև որ չապամրացնեք այն: Ապամրացնելու համար հպեք և պահեք գլխավոր էկրանի կոճակը:"</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Էկրանը կցուցադրվի, մինչև չեղարկեք ամրացումը: Չեղարկելու համար հպեք և պահեք գլխավոր էկրանի կոճակը:"</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Ձեր անձնական տվյալները (օր․՝ կոնտակտները և նամակների բովանդակությունը) կարող են հասանելի դառնալ։"</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Ամրացված հավելվածը կարող է այլ հավելվածներ գործարկել։"</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"Հավելվածն ապամրացնելու համար հպեք և պահեք «Հետ» և «Համատեսք» կոճակները"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index d5dbf4f9b622..6c1ef8aa7294 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -100,7 +100,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Avviare la registrazione?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può acquisire informazioni sensibili visibili sullo schermo o riprodotti sul tuo dispositivo, tra cui password, dati di pagamento, foto, messaggi e audio."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può acquisire informazioni sensibili visibili sullo schermo o riprodotte sul tuo dispositivo, tra cui password, dati di pagamento, foto, messaggi e audio."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Registra audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio del dispositivo"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Suoni del dispositivo, come musica, chiamate e suonerie"</string>
@@ -117,7 +117,7 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Annulla"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Condividi"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Registrazione dello schermo annullata"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Registrazione dello schermo salvata"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Registrazione schermo salvata"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tocca per visualizzare"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Impossibile ottenere le autorizzazioni"</string>
@@ -646,7 +646,7 @@
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrazione"</string>
<string name="volume_dialog_title" msgid="6502703403483577940">"Controlli del volume %s"</string>
- <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Chiamate e notifiche faranno suonare il dispositivo (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
+ <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"La suoneria sarà attiva per chiamate e notifiche (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
<string name="output_title" msgid="3938776561655668350">"Uscita contenuti multimediali"</string>
<string name="output_calls_title" msgid="7085583034267889109">"Uscita telefonate"</string>
<string name="output_none_found" msgid="5488087293120982770">"Nessun dispositivo trovato"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index acfaef68350d..2ba73b365036 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -731,7 +731,7 @@
<string name="notification_silence_title" msgid="8608090968400832335">"サイレント"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
- <string name="notification_channel_summary_low" msgid="4860617986908931158">"着信音もバイブレーションも無効です"</string>
+ <string name="notification_channel_summary_low" msgid="4860617986908931158">"着信音もバイブレーションも無効になります"</string>
<string name="notification_conversation_summary_low" msgid="1734433426085468009">"着信音もバイブレーションも無効になり会話セクションの下に表示されます"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"スマートフォンの設定を基に着信音またはバイブレーションが有効になります"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"スマートフォンの設定を基に着信音またはバイブレーションが有効になります。デフォルトでは <xliff:g id="APP_NAME">%1$s</xliff:g> からの会話がバブルとして表示されます。"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 935bcacef383..9ab5d80b1900 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -107,17 +107,17 @@
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Микрофон"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Құрылғыдан шығатын дыбыс және микрофон"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Бастау"</string>
- <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Экрандағы бейне жазылуда."</string>
+ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Экран жазылып жатыр."</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Экрандағы бейне және аудио жазылуда."</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Экранды түрткенде көрсету"</string>
- <string name="screenrecord_stop_text" msgid="6549288689506057686">"Тоқтату үшін түртіңіз"</string>
+ <string name="screenrecord_stop_text" msgid="6549288689506057686">"Тоқтату үшін түртіңіз."</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Тоқтату"</string>
<string name="screenrecord_pause_label" msgid="6004054907104549857">"Тоқтата тұру"</string>
<string name="screenrecord_resume_label" msgid="4972223043729555575">"Жалғастыру"</string>
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Бас тарту"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлісу"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Экранды бейнеге жазудан бас тартылды"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Экран жазғыш бейнесі сақталды."</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Экран жазбасы сақталды."</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Көру үшін түртіңіз."</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Экран бейне жазбасын жою кезінде қате кетті"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Рұқсаттар алынбады"</string>
@@ -326,7 +326,7 @@
<string name="dessert_case" msgid="9104973640704357717">"Десерт жағдайы"</string>
<string name="start_dreams" msgid="9131802557946276718">"Скринсейвер"</string>
<string name="ethernet_label" msgid="2203544727007463351">"Этернет"</string>
- <string name="quick_settings_header_onboarding_text" msgid="1918085351115504765">"Басқа опцияларды көру үшін белгішелерді түртіп ұстап тұрыңыз"</string>
+ <string name="quick_settings_header_onboarding_text" msgid="1918085351115504765">"Басқа опцияларды көру үшін белгішелерді басып тұрыңыз"</string>
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Мазаламау"</string>
<string name="quick_settings_dnd_priority_label" msgid="6251076422352664571">"Маңыздылары ғана"</string>
<string name="quick_settings_dnd_alarms_label" msgid="1241780970469630835">"Оятқыштар ғана"</string>
@@ -604,16 +604,16 @@
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"өшіру"</string>
<string name="accessibility_output_chooser" msgid="7807898688967194183">"Шығыс құрылғыны ауыстыру"</string>
<string name="screen_pinning_title" msgid="9058007390337841305">"Қолданба бекітілді"</string>
- <string name="screen_pinning_description" msgid="8699395373875667743">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Артқа\" және \"Шолу\" түймелерін басып тұрыңыз."</string>
- <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін түртіп, ұстап тұрыңыз"</string>
- <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Экран босатылғанға дейін көрсетіліп тұрады. Экранды босату үшін жоғары сырғытып, ұстап тұрыңыз."</string>
- <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Кері\" түймесін басып тұрыңыз."</string>
- <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Негізгі бет\" түймесін түртіп, ұстап тұрыңыз."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Жеке деректер (мысалы, контактілер мен электрондық хаттар) ашық болуы мүмкін."</string>
+ <string name="screen_pinning_description" msgid="8699395373875667743">"Өзіңіз босатқаша ашық тұрады. Босату үшін \"Артқа\" және \"Шолу\" түймелерін басып тұрыңыз."</string>
+ <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Өзіңіз босатқаша ашық тұрады. Босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін басып тұрыңыз"</string>
+ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Өзіңіз босатқанша ашық тұрады. Босату үшін экранды жоғары сырғытып, ұстап тұрыңыз."</string>
+ <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Өзіңіз босатқаша ашық тұрады. Босату үшін \"Шолу\" түймесін басып тұрыңыз."</string>
+ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Өзіңіз босатқаша ашық тұрады. Босату үшін \"Негізгі бет\" түймесін басып тұрыңыз."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Жеке деректер (мысалы, контактілер мен электрондық хаттар) көрінуі мүмкін."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Бекітілген қолданба басқа қолданбаларды ашуы мүмкін."</string>
- <string name="screen_pinning_toast" msgid="8177286912533744328">"Бұл қолданбаны босату үшін \"Артқа\" және \"Шолу\" түймелерін түртіп, ұстап тұрыңыз."</string>
- <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Бұл қолданбаны босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін түртіп, ұстап тұрыңыз."</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Бұл қолданбаны босату үшін жоғары сырғытып, ұстап тұрыңыз."</string>
+ <string name="screen_pinning_toast" msgid="8177286912533744328">"Бұл қолданбаны босату үшін \"Артқа\" және \"Шолу\" түймелерін басып тұрыңыз."</string>
+ <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Бұл қолданбаны босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін басып тұрыңыз."</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Бұл қолданбаны босату үшін экранды жоғары сырғытып, ұстап тұрыңыз."</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"Түсінікті"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"Жоқ, рақмет"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"Қолданба бекітілді."</string>
@@ -1006,8 +1006,8 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" және "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> қолданбасы пайдаланып жатыр."</string>
- <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Соңғы рет <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> қолданбасы пайдаланды."</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> пайдаланып жатыр."</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Соңғы рет <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> пайдаланды."</string>
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(жұмыс)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефон қоңырауы"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> арқылы)"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 4d8d4063f196..6ce7300f4a73 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -751,7 +751,7 @@
<string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
<string name="notification_multichannel_desc" msgid="7414593090056236179">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
<string name="notification_delegate_header" msgid="1264510071031479920">"ការជូនដំណឹង​ជា​ប្រូកស៊ី"</string>
- <string name="notification_channel_dialog_title" msgid="6856514143093200019">"ការជូន​ដំណឹងទាំងអស់​របស់ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="notification_channel_dialog_title" msgid="6856514143093200019">"ការជូន​ដំណឹងទាំងអស់​ពី <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="see_more_title" msgid="7409317011708185729">"មើលច្រើនទៀត"</string>
<string name="appops_camera" msgid="5215967620896725715">"កម្មវិធីនេះ​កំពុងប្រើ​កាមេរ៉ា។"</string>
<string name="appops_microphone" msgid="8805468338613070149">"កម្មវិធីនេះ​កំពុងប្រើ​មីក្រូហ្វូន។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index a47271af0ea4..78d086f3ab24 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1085,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ವಜಾಗೊಳಿಸಿ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ಪ್ಲೇ ಮಾಡಿ"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%2$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ದೋಷ, ಮರುಪ್ರಯತ್ನಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5016fb68761a..65a41bb5cf65 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -748,7 +748,7 @@
<string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Būsenos:&lt;/b&gt; reitingas padidintas"</string>
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Būsenos:&lt;/b&gt; reitingas sumažintas"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane"</string>
- <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, debesėlyje"</string>
+ <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, burbule"</string>
<string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, pertraukia netrukdymo režimą"</string>
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Rodoma pokalbių pranešimų viršuje ir kaip profilio nuotrauka užrakinimo ekrane, debesėlyje, pertraukia netrukdymo režimą"</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nustatymai"</string>
@@ -1016,8 +1016,8 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programos naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ir "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Naudojama <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Neseniai naudota <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Naudoja <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Neseniai naudojo <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(darbas)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefono skambutis"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(naud. <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index b11c85c2c3ce..cc7f74055054 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1085,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"डिसमिस करा"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले होत आहे"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"प्ले करणे"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> उघडा"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> मध्ये <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"एरर, पुन्हा प्रयत्न करत आहे…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 283bc40d6ec8..a69be5d76035 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -103,11 +103,11 @@
<string name="screenrecord_description" msgid="1123231719680353736">"रेकर्ड गर्दा, Android सिस्टमले तपाईंको स्क्रिनमा देखिने वा तपाईंको डिभाइसमा प्ले गरिने सबै संवेदनशील जानकारी रेकर्ड गर्न सक्छ। यो जानकारीमा पासवर्ड, भुक्तानीसम्बन्धी जानकारी, फोटो, सन्देश र अडियो समावेश हुन्छ।"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"अडियो रेकर्ड गरियोस्"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"डिभाइसको अडियो"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"तपाईंको डिभाइसका सङ्गीत, कल र रिङटोन जस्ता आवाज"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"तपाईंको डिभाइसका सङ्गीत, कल र रिङटोन जस्ता साउन्ड"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"माइक्रोफोन"</string>
- <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"डिभाइसको अडियो र माइक्रोफोनको आवाज"</string>
+ <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"डिभाइस र माइक्रोफोनको अडियो"</string>
<string name="screenrecord_start" msgid="330991441575775004">"सुरु गर्नुहोस्"</string>
- <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रिन रेकर्ड गर्दै"</string>
+ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रिन रेकर्ड गरिँदै छ"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रिन र अडियो रेकर्ड गरिँदै छ"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"स्पर्श गरिएका स्थानहरू देखाइयोस्"</string>
<string name="screenrecord_stop_text" msgid="6549288689506057686">"रोक्न ट्याप गर्नुहोस्"</string>
@@ -400,7 +400,7 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="3379631363952582758">"अधिसूचनाहरू"</string>
<string name="quick_settings_flashlight_label" msgid="4904634272006284185">"फ्ल्यासलाइट"</string>
- <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"क्यामेरा प्रयोगमा छ"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"क्यामेरा प्रयोग भइरहेको छ"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"मोबाइल डेटा"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"डेटाको प्रयोग"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"बाँकी डेटा"</string>
@@ -609,7 +609,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"तपाईंले यो एप अनपिन नगरेसम्म यो एप यहाँ देखिइरहने छ। अनपिन गर्न माथितिर स्वाइप गरी होल्ड गर्नुहोस्।"</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न परिदृश्य बटनलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न गृह नामक बटनलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"स्क्रिनमा व्यक्तिगत डेटा (जस्तै सम्पर्क ठेगाना र इमेलको सामग्री) देखिन सक्छ।"</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"स्क्रिनमा सम्पर्क ठेगाना र इमेलको सामग्री जस्ता व्यक्तिगत जानकारी देखिन सक्छ।"</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"पिन गरिएको एपले अन्य एप खोल्न सक्छ।"</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"यो एप अनपनि गर्न पछाडि र विवरण नामक बटनहरूलाई टच एण्ड होल्ड गर्नुहोस्"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"यो एप अनपनि गर्न पछाडि र होम बटनलाई टच एण्ड होल्ड गर्नुहोस्"</string>
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string>
<string name="wallet_title" msgid="5369767670735827105">"वालेट"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"फोनमार्फत अझ छिटो र थप सुरक्षित तरिकाले खरिद गर्न भुक्तानी विधि सेटअप गर्नुहोस्"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"सबै देखाइयोस्"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"भुक्तानी गर्न अनलक गर्नुहोस्"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"सेटअप गरिएको छैन"</string>
@@ -1007,8 +1006,8 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"एपहरूले तपाईंको <xliff:g id="TYPES_LIST">%s</xliff:g> प्रयोग गर्दै छन्‌।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" र "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ले प्रयोग गरिरहेको छ"</string>
- <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ले हालसालै प्रयोग गरेको थियो"</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>ले प्रयोग गरिरहेको छ"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>ले हालसालै प्रयोग गरेको थियो"</string>
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(कार्यालय)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"फोन कल"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> मार्फत)"</string>
@@ -1086,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"हटाउनुहोस्"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बज्दै छ"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"प्ले गर्नुहोस्"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> खोल्नुहोस्"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बजाउनुहोस्"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%2$s</xliff:g> मा बजाउनुहोस्"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"त्रुटि भयो, फेरि प्रयास गर्दै…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index bbec6ddf2291..739885d4dbc8 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ଇଥରନେଟ୍‌"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ଆଲାର୍ମ"</string>
<string name="wallet_title" msgid="5369767670735827105">"ୱାଲେଟ୍"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"ଆପଣଙ୍କ ଫୋନ୍ ମାଧ୍ୟମରେ ଆହୁରି ଶୀଘ୍ର, ଅଧିକ ସୁରକ୍ଷିତ କ୍ରୟ କରିବା ପାଇଁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"ସବୁ ଦେଖାନ୍ତୁ"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"ପେମେଣ୍ଟ କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"ସେଟ୍ ଅପ୍ କରାଯାଇନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 16dce8b2ebea..deca3ff30559 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ਈਥਰਨੈਟ"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"ਅਲਾਰਮ"</string>
<string name="wallet_title" msgid="5369767670735827105">"ਵਾਲੇਟ"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"ਆਪਣੇ ਫ਼ੋਨ ਨਾਲ ਜ਼ਿਆਦਾ ਤੇਜ਼ ਅਤੇ ਜ਼ਿਆਦਾ ਸੁਰੱਖਿਅਤ ਖਰੀਦਾਂ ਕਰਨ ਲਈ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"ਸਭ ਦਿਖਾਓ"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"ਭੁਗਤਾਨ ਕਰਨ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
@@ -1086,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ਖਾਰਜ ਕਰੋ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ਚਲਾਓ"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ਤੋਂ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ਗੜਬੜ, ਮੁੜ ਕੋਸ਼ਿਸ਼ ਹੋ ਰਹੀ ਹੈ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 1461fa64c582..217b2f2fa971 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -102,7 +102,7 @@
<string name="screenrecord_start_label" msgid="1750350278888217473">"Rozpocząć nagrywanie?"</string>
<string name="screenrecord_description" msgid="1123231719680353736">"Podczas nagrywania system Android może rejestrować wszelkie informacje poufne wyświetlane na ekranie lub odtwarzane na urządzeniu. Dotyczy to m.in. haseł, szczegółów płatności, zdjęć, wiadomości i odtwarzanych dźwięków."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagraj dźwięk"</string>
- <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki odtwarzane na urządzeniu"</string>
+ <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki z urządzenia"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Dźwięki odtwarzane na urządzeniu, na przykład muzyka, połączenia i dzwonki"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Mikrofon i dźwięki odtwarzane na urządzeniu"</string>
@@ -615,7 +615,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Ekran będzie widoczny, dopóki go nie odepniesz. Przesuń palcem w górę i przytrzymaj, by odpiąć."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj Przegląd."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Ekran główny."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Dane osobowe (np. kontakty czy treść e-maili) mogą być dostępne."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Dostępne mogą być dane osobiste (np. kontakty czy treść e-maili)."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Przypięta aplikacja może otwierać inne aplikacje."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"Aby odpiąć tę aplikację, naciśnij i przytrzymaj przyciski Wstecz oraz Przegląd"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Aby odpiąć tę aplikację, naciśnij i przytrzymaj przyciski Wstecz oraz Ekran główny"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 666b595e1a46..2e7c629b3849 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -342,7 +342,7 @@
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"A ativar..."</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"Brilho"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação automática"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string>
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"Modo <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"Rotação bloqueada"</string>
@@ -352,7 +352,7 @@
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"Localização Desativada"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso câmara"</string>
- <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso microfone"</string>
+ <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ac. microfone"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloqueado"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Dispositivo multimédia"</string>
@@ -373,7 +373,7 @@
<string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi ligado"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Não estão disponíveis redes Wi-Fi"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"A ativar..."</string>
- <string name="quick_settings_cast_title" msgid="2279220930629235211">"Transm. do ecrã"</string>
+ <string name="quick_settings_cast_title" msgid="2279220930629235211">"Transm. ecrã"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"Transmissão"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Dispositivo sem nome"</string>
<string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"Pronto para transmitir"</string>
@@ -408,14 +408,14 @@
<string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> MB utiliz."</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Limite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Apps de trabalho"</string>
+ <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Apps trabalho"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Luz noturna"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Ativ. ao pôr-do-sol"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Até ao amanhecer"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Ativada à(s) <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Até à(s) <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tema escuro"</string>
- <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Poupança de bateria"</string>
+ <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Poup. bateria"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Ativ. ao pôr do sol"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até ao amanhecer"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativado à(s) <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -423,7 +423,7 @@
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"O NFC está desativado"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"O NFC está ativado"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Gravação do ecrã"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Gravação ecrã"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Parar"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Pretende desbloquear o microfone do dispositivo?"</string>
@@ -856,7 +856,7 @@
<string name="accessibility_long_click_tile" msgid="210472753156768705">"Abrir as definições"</string>
<string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Auscultadores ligados"</string>
<string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Auscultadores com microfone integrado ligados"</string>
- <string name="data_saver" msgid="3484013368530820763">"Poupança de dados"</string>
+ <string name="data_saver" msgid="3484013368530820763">"Poup. dados"</string>
<string name="accessibility_data_saver_on" msgid="5394743820189757731">"Poupança de dados ativada"</string>
<string name="accessibility_data_saver_off" msgid="58339669022107171">"Poupança de dados desativada"</string>
<string name="switch_bar_on" msgid="1770868129120096114">"Ativado"</string>
@@ -1042,7 +1042,7 @@
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover p/ extremidade e ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Retirar extremidade e mostrar"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ativar/desativar"</string>
- <string name="quick_controls_title" msgid="7095074621086860062">"Controlos domésticos"</string>
+ <string name="quick_controls_title" msgid="7095074621086860062">"Controlo casa"</string>
<string name="controls_providers_title" msgid="6879775889857085056">"Escolha uma app para adicionar controlos"</string>
<plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
<item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controlos adicionados.</item>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0c67115be325..33f47de80868 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -100,14 +100,14 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Начать запись?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"Во время записи система Android может получить доступ к конфиденциальной информации, которая видна на экране или воспроизводится на устройстве, в том числе к паролям, сведениям о платежах, фотографиям, сообщениям и аудиозаписям."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"В записи может появиться конфиденциальная информация, которая видна на экране или воспроизводится на устройстве, например пароли, сведения о платежах, фотографии, сообщения и аудиозаписи."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Записывать аудио"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Звук с устройства"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук с вашего устройства, например музыка, звонки и рингтоны"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Микрофон"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук с устройства и микрофон"</string>
<string name="screenrecord_start" msgid="330991441575775004">"Начать"</string>
- <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Идет запись видео с экрана."</string>
+ <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Идет запись видео с экрана"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Идет запись видео с экрана и звука"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Показывать прикосновения к экрану"</string>
<string name="screenrecord_stop_text" msgid="6549288689506057686">"Нажмите, чтобы остановить"</string>
@@ -737,10 +737,10 @@
<string name="notification_silence_title" msgid="8608090968400832335">"Без звука"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"По умолчанию"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Автоматически"</string>
- <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука или вибрации"</string>
+ <string name="notification_channel_summary_low" msgid="4860617986908931158">"Без звука и вибрации"</string>
<string name="notification_conversation_summary_low" msgid="1734433426085468009">"Без звука или вибрации, появляется в нижней части списка разговоров"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"Звонок или вибрация в зависимости от настроек телефона"</string>
- <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Звонок или вибрация в зависимости от настроек телефона. Разговоры из приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" по умолчанию появляются в виде всплывающего чата."</string>
+ <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Звонок или вибрация в зависимости от настроек телефона. Разговоры из приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" по умолчанию появляются в виде всплывающего чата"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Привлекает ваше внимание к контенту с помощью плавающего ярлыка"</string>
<string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Система будет сама определять, включать ли звуковой сигнал или вибрацию для уведомления"</string>
<string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Статус:&lt;/b&gt; повышено до уровня \"По умолчанию\""</string>
@@ -900,8 +900,8 @@
<string name="right_keycode" msgid="2480715509844798438">"Код клавиши \"Вправо\""</string>
<string name="left_icon" msgid="5036278531966897006">"Значок \"Влево\""</string>
<string name="right_icon" msgid="1103955040645237425">"Значок \"Вправо\""</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Перетащите нужные элементы"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Чтобы изменить порядок элементов, перетащите их"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Чтобы добавить элементы, перетащите их."</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Чтобы изменить порядок элементов, перетащите их."</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Чтобы удалить, перетащите сюда"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Должно остаться не менее <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> элементов"</string>
<string name="qs_edit" msgid="5583565172803472437">"Изменить"</string>
@@ -1016,8 +1016,8 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"В приложениях используется <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Используется в приложении \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\""</string>
- <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Недавно использовалось в приложении \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\""</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Используется приложением \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\""</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Недавно использовалось приложением \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\""</string>
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(работа)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Телефонный звонок"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(через приложение \"<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>\")"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 63b1e0bb0d94..0b74313dcf89 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -117,7 +117,7 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Zrušiť"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Zdieľať"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Záznam obrazovky bol zrušený"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky bola uložená"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka bola uložená"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Zobrazte klepnutím"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Nepodarilo sa získať povolenia"</string>
@@ -1011,7 +1011,7 @@
<string name="auto_saver_enabled_text" msgid="7889491183116752719">"Keď batéria klesne pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%, automaticky sa aktivujte Šetrič batérie."</string>
<string name="open_saver_setting_action" msgid="2111461909782935190">"Nastavenia"</string>
<string name="auto_saver_okay_action" msgid="7815925750741935386">"Dobre"</string>
- <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <string name="heap_dump_tile_name" msgid="2464189856478823046">"V7pis haldy SysUI"</string>
<string name="ongoing_privacy_chip_content_single_app" msgid="2969750601815230385">"<xliff:g id="APP">%1$s</xliff:g> používa zoznam <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d229aae9019b..b4729f4ec9f2 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -622,8 +622,8 @@
<string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Če želite odpeti to aplikacijo, povlecite navzgor in pridržite."</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"Razumem"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"Ne, hvala"</string>
- <string name="screen_pinning_start" msgid="7483998671383371313">"Aplikacija je pripeta"</string>
- <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikacija je odpeta"</string>
+ <string name="screen_pinning_start" msgid="7483998671383371313">"Aplikacija je pripeta."</string>
+ <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikacija je odpeta."</string>
<string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"Želite skriti <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"Znova se bo pojavila, ko jo naslednjič vklopite v nastavitvah."</string>
<string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"Skrij"</string>
@@ -900,8 +900,8 @@
<string name="right_keycode" msgid="2480715509844798438">"Desna koda tipke"</string>
<string name="left_icon" msgid="5036278531966897006">"Leva ikona"</string>
<string name="right_icon" msgid="1103955040645237425">"Desna ikona"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Držite in povlecite, da dodate ploščice"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Držite in povlecite, da prerazporedite ploščice"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Držite in povlecite, da dodate ploščice."</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Držite in povlecite, da prerazporedite ploščice."</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Če želite odstraniti, povlecite sem"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Imeti morate vsaj toliko ploščic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Uredi"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a42e1262bc70..3ec14ea3fd81 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -617,7 +617,7 @@
<string name="screen_pinning_positive" msgid="3285785989665266984">"E kuptova"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"Jo, faleminderit!"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"Aplikacioni u gozhdua"</string>
- <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikacioni i zhgozhduar"</string>
+ <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikacioni u zhgozhdua"</string>
<string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"Të fshihet <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"Do të rishfaqet herën tjetër kur ta aktivizoni te cilësimet."</string>
<string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"Fshih"</string>
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Alarmi"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Konfiguro për të kryer pagesa më të shpejta dhe më të sigurta përmes telefonit"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"Shfaqi të gjitha"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"Shkyçe për të paguar"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"Nuk është konfiguruar"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 6a8ffe2a9dbe..84b33a9bbf62 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"ఈథర్‌నెట్"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"అలారం"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"మీ ఫోన్‌తో మరింత వేగంగా, సురక్షితంగా కొనుగోళ్లు చేయడానికి సెటప్ చేయండి"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"అన్నింటినీ చూపు"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"పే చేయడానికి అన్‌లాక్ చేయండి"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"సెటప్ చేయలేదు"</string>
@@ -1086,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"విస్మరించు"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్‌లు"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ప్లే చేయండి"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>ను తెరవండి"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి <xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g>‌ను ప్లే చేయండి"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> నుండి <xliff:g id="SONG_NAME">%1$s</xliff:g>‌ను ప్లే చేయండి"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"లోపం, మళ్లీ ప్రయత్నిస్తోంది..."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 70bd85036198..2f0957caaaae 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -33,6 +33,7 @@
<item>com.android.systemui.statusbar.tv.notifications.TvNotificationPanel</item>
<item>com.android.systemui.statusbar.tv.notifications.TvNotificationHandler</item>
<item>com.android.systemui.statusbar.tv.VpnStatusObserver</item>
+ <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 68777123e53b..2b7bc5812b2a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -606,14 +606,14 @@
<string name="screen_pinning_title" msgid="9058007390337841305">"ปักหมุดแอปอยู่"</string>
<string name="screen_pinning_description" msgid="8699395373875667743">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string>
<string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string>
- <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"วิธีนี้ช่วยให้เห็นแอปบนหน้าจอตลอดจนกว่าจะเลิกปักหมุด เลื่อนขึ้นค้างไว้เพื่อเลิกปักหมุด"</string>
+ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"วิธีนี้ช่วยให้เห็นแอปบนหน้าจอตลอดจนกว่าจะเลิกปักหมุด ปัดขึ้นค้างไว้เพื่อเลิกปักหมุด"</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string>
<string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"อาจมีการเข้าถึงข้อมูลส่วนตัว (เช่น รายชื่อติดต่อและเนื้อหาในอีเมล)"</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"แอปที่ปักหมุดไว้อาจเปิดแอปอื่นๆ"</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"หากต้องการเลิกปักหมุดแอปนี้ ให้แตะปุ่ม \"กลับ\" และ \"ภาพรวม\" ค้างไว้"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"หากต้องการเลิกปักหมุดแอปนี้ ให้แตะปุ่ม \"กลับ\" และ \"หน้าแรก\" ค้างไว้"</string>
- <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"หากต้องการเลิกปักหมุดแอปนี้ ให้เลื่อนขึ้นค้างไว้"</string>
+ <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"หากต้องการเลิกปักหมุดแอปนี้ ให้ปัดขึ้นค้างไว้"</string>
<string name="screen_pinning_positive" msgid="3285785989665266984">"รับทราบ"</string>
<string name="screen_pinning_negative" msgid="6882816864569211666">"ไม่เป็นไร ขอบคุณ"</string>
<string name="screen_pinning_start" msgid="7483998671383371313">"ปักหมุดแอปแล้ว"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c145645d8712..568be8a5a7d7 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -117,7 +117,7 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"İptal"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaş"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Ekran kaydı iptal edildi"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran kaydı saklandı"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran kaydı kaydedildi"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Görüntülemek için dokunun"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekran kaydı silinirken hata oluştu"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"İzinler alınamadı"</string>
@@ -675,8 +675,8 @@
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Kilit ekranı ayarları"</string>
<string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Uçak modu"</string>
- <string name="add_tile" msgid="6239678623873086686">"Blok ekle"</string>
- <string name="broadcast_tile" msgid="5224010633596487481">"Yayın Bloku"</string>
+ <string name="add_tile" msgid="6239678623873086686">"Kutu ekle"</string>
+ <string name="broadcast_tile" msgid="5224010633596487481">"Yayın Kutusu"</string>
<string name="zen_alarm_warning_indef" msgid="5252866591716504287">"<xliff:g id="WHEN">%1$s</xliff:g> olarak ayarlanmış bir sonraki alarmınızdan önce bu işlevi kapatmazsanız alarmı duymayacaksınız"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> olarak ayarlanmış bir sonraki alarmınızı duymayacaksınız"</string>
<string name="alarm_template" msgid="2234991538018805736">"saat: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -890,10 +890,10 @@
<string name="right_keycode" msgid="2480715509844798438">"Sağ tuş kodu"</string>
<string name="left_icon" msgid="5036278531966897006">"Sol simge"</string>
<string name="right_icon" msgid="1103955040645237425">"Sağ simge"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Blok eklemek için basılı tutup sürükleyin"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Blokları yeniden düzenlemek için basılı tutun ve sürükleyin"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Kutu eklemek için basılı tutup sürükleyin"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Kutuları yeniden düzenlemek için basılı tutun ve sürükleyin"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kaldırmak için buraya sürükleyin"</string>
- <string name="drag_to_remove_disabled" msgid="933046987838658850">"En az <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blok gerekiyor"</string>
+ <string name="drag_to_remove_disabled" msgid="933046987838658850">"En az <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kutu gerekiyor"</string>
<string name="qs_edit" msgid="5583565172803472437">"Düzenle"</string>
<string name="tuner_time" msgid="2450785840990529997">"Saat"</string>
<string-array name="clock_options">
@@ -908,15 +908,15 @@
</string-array>
<string name="tuner_low_priority" msgid="8412666814123009820">"Düşük öncelikli bildirim simgelerini göster"</string>
<string name="other" msgid="429768510980739978">"Diğer"</string>
- <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"Karoyu kaldırmak için"</string>
- <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"Sona karo eklemek için"</string>
- <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Karoyu taşı"</string>
- <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Karo ekle"</string>
+ <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"Kutuyu kaldırmak için"</string>
+ <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"Sona kutu eklemek için"</string>
+ <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Kutuyu taşı"</string>
+ <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Kutu ekle"</string>
<string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna taşı"</string>
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna ekle"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Konum: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
- <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kart eklendi"</string>
- <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Parça kaldırıldı"</string>
+ <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kutu eklendi"</string>
+ <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kutu kaldırıldı"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirimi: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları aç."</string>
@@ -1142,7 +1142,7 @@
<string name="missed_call" msgid="4228016077700161689">"Cevapsız arama"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
<string name="people_tile_description" msgid="8154966188085545556">"Yeni mesajları, cevapsız aramaları ve durum güncellemelerini görün"</string>
- <string name="people_tile_title" msgid="6589377493334871272">"Konuşma"</string>
+ <string name="people_tile_title" msgid="6589377493334871272">"Görüşme"</string>
<string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> bir mesaj gönderdi"</string>
<string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> bir resim gönderdi"</string>
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pil ölçeriniz okunurken sorun oluştu"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index cfba196f37fb..7aef2526ab16 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -96,7 +96,7 @@
<string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Знизу на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
<string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зліва на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
<string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Справа на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
- <string name="screenrecord_name" msgid="2596401223859996572">"Відеозапис екрана"</string>
+ <string name="screenrecord_name" msgid="2596401223859996572">"Запис відео з екрана"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"Почати запис?"</string>
@@ -117,7 +117,7 @@
<string name="screenrecord_cancel_label" msgid="7850926573274483294">"Скасувати"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поділитися"</string>
<string name="screenrecord_cancel_success" msgid="1775448688137393901">"Запис екрана скасовано"</string>
- <string name="screenrecord_save_title" msgid="1886652605520893850">"Запис відео з екрана збережено"</string>
+ <string name="screenrecord_save_title" msgid="1886652605520893850">"Запис екрана збережено"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Натисніть, щоб переглянути"</string>
<string name="screenrecord_delete_error" msgid="2870506119743013588">"Не вдалося видалити запис екрана"</string>
<string name="screenrecord_permission_error" msgid="7856841237023137686">"Не вдалось отримати дозволи"</string>
@@ -427,7 +427,7 @@
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC вимкнено"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ввімкнено"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Запис відео з екрана"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Запис екрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Почати"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зупинити"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string>
@@ -748,7 +748,7 @@
<string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Статус&lt;/b&gt;: пріоритет підвищено"</string>
<string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус&lt;/b&gt;: пріоритет знижено"</string>
<string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані"</string>
- <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається у вигляді спливаючої підказки"</string>
+ <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується у вигляді спливаючої підказки"</string>
<string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується навіть у режимі \"Не турбувати\""</string>
<string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається у вигляді спливаючої підказки, показується навіть у режимі \"Не турбувати\""</string>
<string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Налаштування"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 35adbd2079a5..b8911fda4f7f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1085,15 +1085,11 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"برخاست کریں"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
- <!-- no translation found for controls_media_playing_item_description (4531853311504359098) -->
- <skip />
+ <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چل رہا ہے"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"چلائیں"</string>
- <!-- no translation found for controls_media_smartspace_rec_description (4136242327044070732) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_description (2189271793070870883) -->
- <skip />
- <!-- no translation found for controls_media_smartspace_rec_item_no_artist_description (8703614798636591077) -->
- <skip />
+ <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> کھولیں"</string>
+ <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string>
+ <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> سے <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"خرابی، دوبارہ کوشش کی جا رہی ہے…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 97530bbdbff3..f41193887e61 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -342,7 +342,7 @@
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Eshitish apparatlari"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Yoqilmoqda…"</string>
<string name="quick_settings_brightness_label" msgid="680259653088849563">"Yorqinlik"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avtomatik burilish"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avto-burilish"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranning avtomatik burilishi"</string>
<string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> rejimi"</string>
<string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"Aylanmaydigan qilingan"</string>
@@ -408,7 +408,7 @@
<string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> sarflandi"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Cheklov: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Ogohlantirish: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Ishga oid ilovalar"</string>
+ <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Ish ilovalari"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Tungi rejim"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Kunbotarda yoqish"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Quyosh chiqqunicha"</string>
@@ -423,7 +423,7 @@
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC o‘chiq"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC yoniq"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Ekranni yozib olish"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Ekran yozuvi"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Boshlash"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Toʻxtatish"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
@@ -666,8 +666,7 @@
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
<string name="status_bar_alarm" msgid="87160847643623352">"Signal"</string>
<string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
- <!-- no translation found for wallet_empty_state_label (7776761245237530394) -->
- <skip />
+ <string name="wallet_empty_state_label" msgid="7776761245237530394">"Telefonda tezroq va xavfsizroq xarid qilish uchun sozlang"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"Hammasi"</string>
<string name="wallet_action_button_label_unlock" msgid="8663239748726774487">"Toʻlov uchun qulfdan chiqarish"</string>
<string name="wallet_secondary_label_no_card" msgid="1282609666895946317">"Sozlanmagan"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 88bc5be975df..1e10496573f1 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -405,7 +405,7 @@
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Sử dụng dữ liệu"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="1136599216568805644">"Dữ liệu còn lại"</string>
<string name="quick_settings_cellular_detail_over_limit" msgid="4561921367680636235">"Vượt quá giới hạn"</string>
- <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Đã sử dụng <xliff:g id="DATA_USED">%s</xliff:g>"</string>
+ <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Đã dùng <xliff:g id="DATA_USED">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Giới hạn <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Cảnh báo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Ứng dụng công việc"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 8f0a197109cd..9a278fd1a0dc 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -76,7 +76,7 @@
<string name="learn_more" msgid="4690632085667273811">"瞭解詳情"</string>
<string name="compat_mode_on" msgid="4963711187149440884">"放大為全螢幕"</string>
<string name="compat_mode_off" msgid="7682459748279487945">"放大為全螢幕"</string>
- <string name="global_action_screenshot" msgid="2760267567509131654">"擷取螢幕畫面"</string>
+ <string name="global_action_screenshot" msgid="2760267567509131654">"螢幕截圖"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"傳送了一張圖片"</string>
<string name="screenshot_saving_ticker" msgid="6519186952674544916">"正在儲存螢幕截圖…"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在儲存螢幕截圖…"</string>
@@ -732,7 +732,7 @@
<string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"不震動或發出聲音"</string>
- <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不震動或發出聲音,並調整排序到其他對話下方"</string>
+ <string name="notification_conversation_summary_low" msgid="1734433426085468009">"不震動或發出聲音,並顯示在對話區的下方"</string>
<string name="notification_channel_summary_default" msgid="3282930979307248890">"根據手機的設定響鈴或震動"</string>
<string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"可能會根據手機的設定響鈴或震動。根據預設,來自「<xliff:g id="APP_NAME">%1$s</xliff:g>」的對話會以對話框形式顯示。"</string>
<string name="notification_channel_summary_bubble" msgid="7235935211580860537">"利用浮動式捷徑快速存取這項內容。"</string>
@@ -891,7 +891,7 @@
<string name="left_icon" msgid="5036278531966897006">"向左圖示"</string>
<string name="right_icon" msgid="1103955040645237425">"向右圖示"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"按住並拖曳即可新增設定方塊"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"按住並拖曳即可重新排列圖塊"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"按住並拖曳即可重新排列設定方塊"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖曳到這裡即可移除"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"你至少必須要有 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個設定方塊"</string>
<string name="qs_edit" msgid="5583565172803472437">"編輯"</string>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 067d56f3d157..d2ed6017b205 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -143,6 +143,7 @@
<attr name="handleThickness" format="dimension" />
<attr name="handleColor" format="color" />
<attr name="scrimColor" format="color" />
+ <attr name="containerBackgroundColor" format="color" />
<attr name="isVertical" format="boolean" />
@@ -178,6 +179,7 @@
<attr name="handleThickness" />
<attr name="handleColor" />
<attr name="scrimColor" />
+ <attr name="containerBackgroundColor" />
</declare-styleable>
<declare-styleable name="MagnifierView">
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b4deaa0af543..82ce881b2fbc 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -396,10 +396,6 @@
<!-- Whether or not the notifications should always fade as they are dismissed. -->
<bool name="config_fadeNotificationsOnDismiss">false</bool>
- <!-- Whether or not the parent of the notification row itself is being translated when swiped or
- its children views. If true, then the contents are translated and vice versa. -->
- <bool name="config_translateNotificationContentsOnSwipe">true</bool>
-
<!-- Whether or not the fade on the notification is based on the amount that it has been swiped
off-screen. -->
<bool name="config_fadeDependingOnAmountSwiped">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 76a4c5ffe919..9b860c75f476 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -347,7 +347,7 @@
<!-- Padding to make tappable chip height 48dp (18+11+11+4+4) -->
<dimen name="screenshot_action_chip_margin_vertical">4dp</dimen>
<dimen name="screenshot_action_chip_padding_vertical">11dp</dimen>
- <dimen name="screenshot_action_chip_icon_size">18dp</dimen>
+ <dimen name="screenshot_action_chip_icon_size">18sp</dimen>
<!-- Padding on each side of the icon for icon-only chips -->
<dimen name="screenshot_action_chip_icon_only_padding_horizontal">14dp</dimen>
<!-- Padding at the edges of the chip for icon-and-text chips -->
@@ -486,6 +486,9 @@
<dimen name="volume_dialog_slider_height">116dp</dimen>
+ <!-- (volume_dialog_panel_width - rounded_slider_icon_size) / 2 -->
+ <dimen name="volume_slider_icon_inset">11dp</dimen>
+
<dimen name="volume_dialog_track_width">4dp</dimen>
<dimen name="volume_dialog_track_corner_radius">2dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7f4e4751312e..93ce8f3c2a96 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2705,6 +2705,8 @@
<!-- Accessibility floating menu strings -->
<!-- Message for the accessibility floating button migration tooltip. It shows when the user use gestural navigation then upgrade their system. It will tell the user the accessibility gesture had been replaced by accessibility floating button. [CHAR LIMIT=100] -->
<string name="accessibility_floating_button_migration_tooltip">Accessibility button replaced the accessibility gesture\n\n<annotation id="link">View settings</annotation></string>
+ <!-- Message for the accessibility floating button settings tooltip. It shows when the user use gestural navigation then upgrade their system. It will tell the user to have another option to switch from the accessibility gesture to a button. [CHAR LIMIT=100] -->
+ <string name="accessibility_floating_button_switch_migration_tooltip">You can switch from the accessibility gesture to a button\n\n<annotation id="link">Settings</annotation></string>
<!-- Message for the accessibility floating button docking tooltip. It shows when the user first time drag the button. It will tell the user about docking behavior. [CHAR LIMIT=70] -->
<string name="accessibility_floating_button_docking_tooltip">Move button to the edge to hide it temporarily</string>
<!-- Action in accessibility menu to move the accessibility floating button to the top left of the screen. [CHAR LIMIT=30] -->
@@ -2977,6 +2979,8 @@
<!-- Content description for a chip in the status bar showing that the user is currently on a phone call. [CHAR LIMIT=NONE] -->
<string name="ongoing_phone_call_content_description">Ongoing phone call</string>
+ <!-- Placeholder for string describing changes in global actions -->
+ <string name="global_actions_change_description" translatable="false"><xliff:g>%1$s</xliff:g></string>
<!-- URL for more information about changes in global actions -->
<string name="global_actions_change_url" translatable="false"></string>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index fb9aa4a4b358..998b318915af 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -85,9 +85,7 @@ public class PipSurfaceTransactionHelper {
final float left = destinationBounds.left - insets.left * scale;
final float top = destinationBounds.top - insets.top * scale;
mTmpTransform.setScale(scale, scale);
- final Rect cornerRadiusRect = new Rect(destinationBounds);
- cornerRadiusRect.inset(insets);
- final float cornerRadius = getScaledCornerRadius(sourceBounds, cornerRadiusRect);
+ final float cornerRadius = getScaledCornerRadius(mTmpDestinationRect, destinationBounds);
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
.setWindowCrop(leash, mTmpDestinationRect)
.setPosition(leash, left, top)
@@ -110,15 +108,23 @@ public class PipSurfaceTransactionHelper {
: (float) destinationBounds.height() / sourceBounds.height();
mTmpTransform.setRotate(degree, 0, 0);
mTmpTransform.postScale(scale, scale);
- final Rect cornerRadiusRect = new Rect(destinationBounds);
- cornerRadiusRect.inset(insets);
- final float cornerRadius = getScaledCornerRadius(sourceBounds, cornerRadiusRect);
+ final float cornerRadius = getScaledCornerRadius(mTmpDestinationRect, destinationBounds);
+ // adjust the positions, take account also the insets
+ final float adjustedPositionX, adjustedPositionY;
+ if (degree < 0) {
+ adjustedPositionX = positionX + insets.top * scale;
+ adjustedPositionY = positionY + insets.left * scale;
+ } else {
+ adjustedPositionX = positionX - insets.top * scale;
+ adjustedPositionY = positionY - insets.left * scale;
+ }
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
.setWindowCrop(leash, mTmpDestinationRect)
- .setPosition(leash, positionX, positionY)
+ .setPosition(leash, adjustedPositionX, adjustedPositionY)
.setCornerRadius(leash, cornerRadius);
return new PictureInPictureSurfaceTransaction(
- positionX, positionY, mTmpFloat9, degree, cornerRadius, mTmpDestinationRect);
+ adjustedPositionX, adjustedPositionY,
+ mTmpFloat9, degree, cornerRadius, mTmpDestinationRect);
}
/** @return the round corner radius scaled by given from and to bounds */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
index 42d2333587b4..442716878af4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
@@ -17,6 +17,7 @@
package com.android.systemui.shared.system;
import android.annotation.IntDef;
+import android.os.Build;
import android.view.View;
import com.android.internal.jank.InteractionJankMonitor;
@@ -58,23 +59,48 @@ public final class InteractionJankMonitorWrapper {
public @interface CujType {
}
- public static boolean begin(View v, @CujType int cujType) {
- return InteractionJankMonitor.getInstance().begin(v, cujType);
+ /**
+ * Begin a trace session.
+ *
+ * @param v an attached view.
+ * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+ */
+ public static void begin(View v, @CujType int cujType) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
+ InteractionJankMonitor.getInstance().begin(v, cujType);
}
- public static boolean begin(View v, @CujType int cujType, long timeout) {
+ /**
+ * Begin a trace session.
+ *
+ * @param v an attached view.
+ * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+ * @param timeout duration to cancel the instrumentation in ms
+ */
+ public static void begin(View v, @CujType int cujType, long timeout) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
Configuration.Builder builder =
new Configuration.Builder(cujType)
.setView(v)
.setTimeout(timeout);
- return InteractionJankMonitor.getInstance().begin(builder);
+ InteractionJankMonitor.getInstance().begin(builder);
}
- public static boolean end(@CujType int cujType) {
- return InteractionJankMonitor.getInstance().end(cujType);
+ /**
+ * End a trace session.
+ *
+ * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+ */
+ public static void end(@CujType int cujType) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
+ InteractionJankMonitor.getInstance().end(cujType);
}
- public static boolean cancel(@CujType int cujType) {
- return InteractionJankMonitor.getInstance().cancel(cujType);
+ /**
+ * Cancel the trace session.
+ */
+ public static void cancel(@CujType int cujType) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
+ InteractionJankMonitor.getInstance().cancel(cujType);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 3d51f2379727..38f8f7ac321f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -66,10 +66,8 @@ import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.Message;
-import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -243,10 +241,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final boolean mIsPrimaryUser;
private final boolean mIsAutomotive;
private final AuthController mAuthController;
- private final PowerManager mPowerManager;
private final StatusBarStateController mStatusBarStateController;
private int mStatusBarState;
- private boolean mDozing;
private final StatusBarStateController.StateListener mStatusBarStateControllerListener =
new StatusBarStateController.StateListener() {
@Override
@@ -255,8 +251,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
@Override
- public void onDozingChanged(boolean dozing) {
- mDozing = dozing;
+ public void onExpandedChanged(boolean isExpanded) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onShadeExpandedChanged(isExpanded);
+ }
+ }
}
};
@@ -784,6 +785,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
|| msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
mFingerprintLockedOut = true;
+ if (isUdfpsEnrolled()) {
+ updateFingerprintListeningState();
+ }
}
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1330,19 +1334,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
= new AuthenticationCallback() {
- private boolean mIsUdfpsRunningWhileDozing;
@Override
public void onAuthenticationFailed() {
handleFingerprintAuthFailed();
- cancelAodInterrupt();
}
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric());
- cancelAodInterrupt();
Trace.endSection();
}
@@ -1354,7 +1355,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
handleFingerprintError(errMsgId, errString.toString());
- cancelAodInterrupt();
}
@Override
@@ -1365,25 +1365,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onUdfpsPointerDown(int sensorId) {
Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId);
-
- if (mDozing) {
- mIsUdfpsRunningWhileDozing = true;
- }
}
@Override
public void onUdfpsPointerUp(int sensorId) {
Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId);
}
-
- private void cancelAodInterrupt() {
- if (mIsUdfpsRunningWhileDozing) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
- "com.android.systemui:AOD_INTERRUPT_END");
- }
- mAuthController.onCancelUdfps();
- mIsUdfpsRunningWhileDozing = false;
- }
};
private final FaceManager.FaceDetectionCallback mFaceDetectionCallback
@@ -1676,7 +1663,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
LockPatternUtils lockPatternUtils,
AuthController authController,
TelephonyListenerManager telephonyListenerManager,
- PowerManager powerManager,
FeatureFlags featureFlags) {
mContext = context;
mSubscriptionManager = SubscriptionManager.from(context);
@@ -1689,10 +1675,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mStatusBarStateController = statusBarStateController;
mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
mStatusBarState = mStatusBarStateController.getState();
- mDozing = mStatusBarStateController.isDozing();
mLockPatternUtils = lockPatternUtils;
mAuthController = authController;
- mPowerManager = powerManager;
dumpManager.registerDumpable(getClass().getName(), this);
mHandler = new Handler(mainLooper) {
@@ -2144,7 +2128,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|| (!getUserCanSkipBouncer(getCurrentUser())
&& !isEncryptedOrLockdown(getCurrentUser())
&& !userNeedsStrongAuth()
- && userDoesNotHaveTrust);
+ && userDoesNotHaveTrust
+ && !mFingerprintLockedOut);
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
&& shouldListenUdfpsState;
}
@@ -3273,6 +3258,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
pw.println(" udfpsEnrolled=" + isUdfpsEnrolled());
+ pw.println(" mFingerprintLockedOut=" + mFingerprintLockedOut);
pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId));
if (isUdfpsEnrolled()) {
pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index e561a5a84f24..9849a7efe837 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -333,4 +333,8 @@ public class KeyguardUpdateMonitorCallback {
*/
public void onRequireUnlockForNfc() { }
+ /**
+ * Called when the notification shade is expanded or collapsed.
+ */
+ public void onShadeExpandedChanged(boolean expanded) { }
}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 64a683e78953..a68f79604b25 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -130,10 +130,7 @@ public class ImageWallpaper extends WallpaperService {
.getBounds();
mHeight = window.height();
mWidth = window.width();
- mMiniBitmap = null;
- if (mWorker != null && mWorker.getThreadHandler() != null) {
- mWorker.getThreadHandler().post(this::updateMiniBitmap);
- }
+ mRenderer.setOnBitmapChanged(this::updateMiniBitmap);
}
EglHelper getEglHelperInstance() {
@@ -177,20 +174,19 @@ public class ImageWallpaper extends WallpaperService {
mPageOffset = (1 - imgWidth) / (float) (mPages - 1);
}
- private void updateMiniBitmap() {
- mRenderer.useBitmap(b -> {
- int size = Math.min(b.getWidth(), b.getHeight());
- float scale = 1.0f;
- if (size > MIN_SURFACE_WIDTH) {
- scale = (float) MIN_SURFACE_WIDTH / (float) size;
- }
- mImgHeight = b.getHeight();
- mImgWidth = b.getWidth();
- mMiniBitmap = Bitmap.createScaledBitmap(b, (int) Math.max(scale * b.getWidth(), 1),
- (int) Math.max(scale * b.getHeight(), 1), false);
- computeAndNotifyLocalColors(mLocalColorsToAdd, mMiniBitmap);
- mLocalColorsToAdd.clear();
- });
+ private void updateMiniBitmap(Bitmap b) {
+ if (b == null) return;
+ int size = Math.min(b.getWidth(), b.getHeight());
+ float scale = 1.0f;
+ if (size > MIN_SURFACE_WIDTH) {
+ scale = (float) MIN_SURFACE_WIDTH / (float) size;
+ }
+ mImgHeight = b.getHeight();
+ mImgWidth = b.getWidth();
+ mMiniBitmap = Bitmap.createScaledBitmap(b, (int) Math.max(scale * b.getWidth(), 1),
+ (int) Math.max(scale * b.getHeight(), 1), false);
+ computeAndNotifyLocalColors(mLocalColorsToAdd, mMiniBitmap);
+ mLocalColorsToAdd.clear();
}
private void updateSurfaceSize() {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index b0f4da251208..affad7a57d86 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -391,9 +391,9 @@ public class SwipeHelper implements Gefingerpoken {
boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
(getTranslation(animView) < 0 && !isDismissAll);
if (animateLeft || animateLeftForRtl || animateUpForMenu) {
- newPos = -getSize(animView);
+ newPos = -getTotalTranslationLength(animView);
} else {
- newPos = getSize(animView);
+ newPos = getTotalTranslationLength(animView);
}
long duration;
if (fixedDuration == 0) {
@@ -470,6 +470,15 @@ public class SwipeHelper implements Gefingerpoken {
}
/**
+ * Get the total translation length where we want to swipe to when dismissing the view. By
+ * default this is the size of the view, but can also be larger.
+ * @param animView the view to ask about
+ */
+ protected float getTotalTranslationLength(View animView) {
+ return getSize(animView);
+ }
+
+ /**
* Called to update the dismiss animation.
*/
protected void prepareDismissAnimation(View view, Animator anim) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index bfb7105f5860..17178fa8e606 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -75,7 +75,6 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
private final LayoutParams mParams;
- private int mWindowHeight;
@VisibleForTesting
final Rect mDraggableWindowBounds = new Rect();
private boolean mIsVisible = false;
@@ -95,7 +94,6 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
mWindowManager = mContext.getSystemService(WindowManager.class);
mSfVsyncFrameProvider = sfVsyncFrameProvider;
mParams = createLayoutParams(context);
- mWindowHeight = mWindowManager.getCurrentWindowMetrics().getBounds().height();
mImageView = imageView;
mImageView.setOnTouchListener(this::onTouch);
mImageView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@@ -313,12 +311,14 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
void onConfigurationChanged(int configDiff) {
if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
+ final Rect previousDraggableBounds = new Rect(mDraggableWindowBounds);
mDraggableWindowBounds.set(getDraggableWindowBounds());
- // Keep the Y position with the same height ratio before the window height is changed.
- final int windowHeight = mWindowManager.getCurrentWindowMetrics().getBounds().height();
- final float windowHeightFraction = (float) mParams.y / mWindowHeight;
- mParams.y = (int) (windowHeight * windowHeightFraction);
- mWindowHeight = windowHeight;
+ // Keep the Y position with the same height ratio before the window bounds and
+ // draggable bounds are changed.
+ final float windowHeightFraction = (float) (mParams.y - previousDraggableBounds.top)
+ / previousDraggableBounds.height();
+ mParams.y = (int) (windowHeightFraction * mDraggableWindowBounds.height())
+ + mDraggableWindowBounds.top;
stickToScreenEdge(mToLeftScreenEdge);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
index 47f373920b90..05256e646948 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
@@ -53,7 +53,7 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
@FloatRange(from = 0.0, to = 1.0)
private static final float DEFAULT_POSITION_X_PERCENT = 1.0f;
@FloatRange(from = 0.0, to = 1.0)
- private static final float DEFAULT_POSITION_Y_PERCENT = 0.8f;
+ private static final float DEFAULT_POSITION_Y_PERCENT = 0.9f;
private final Context mContext;
private final AccessibilityFloatingMenuView mMenuView;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
index 63cfd5123c96..ee09c620ec1d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
@@ -143,7 +143,7 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> {
}
void updateItemPadding(int padding, int size) {
- itemView.setPaddingRelative(padding, padding, padding, padding);
+ itemView.setPaddingRelative(padding, padding, padding, 0);
}
}
@@ -154,7 +154,7 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> {
@Override
void updateItemPadding(int padding, int size) {
- final int paddingBottom = size <= 2 ? padding : 0;
+ final int paddingBottom = size <= 1 ? padding : 0;
itemView.setPaddingRelative(padding, padding, padding, paddingBottom);
}
}
@@ -166,7 +166,7 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> {
@Override
void updateItemPadding(int padding, int size) {
- itemView.setPaddingRelative(padding, 0, padding, padding);
+ itemView.setPaddingRelative(padding, padding, padding, padding);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 5e6b904c1527..7947241ff794 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -43,6 +43,7 @@ import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
+import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -100,6 +101,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
@Nullable
private UdfpsController mUdfpsController;
@Nullable
+ private IUdfpsHbmListener mUdfpsHbmListener;
+ @Nullable
private SidefpsController mSidefpsController;
@VisibleForTesting
TaskStackListener mTaskStackListener;
@@ -470,6 +473,24 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
}
+ /**
+ * Stores the listener received from {@link com.android.server.display.DisplayModeDirector}.
+ *
+ * DisplayModeDirector implements {@link IUdfpsHbmListener} and registers it with this class by
+ * calling {@link CommandQueue#setUdfpsHbmListener(IUdfpsHbmListener)}.
+ */
+ @Override
+ public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
+ mUdfpsHbmListener = listener;
+ }
+
+ /**
+ * @return IUdfpsHbmListener that can be set by DisplayModeDirector.
+ */
+ @Nullable public IUdfpsHbmListener getUdfpsHbmListener() {
+ return mUdfpsHbmListener;
+ }
+
@Override
public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index cf577a37d625..77cca2e3089c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -24,9 +24,13 @@ import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.settingslib.Utils
+import com.android.systemui.statusbar.CircleReveal
+import com.android.systemui.statusbar.LiftReveal
+import com.android.systemui.statusbar.LightRevealEffect
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.StatusBar
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
@@ -49,10 +53,12 @@ class AuthRippleController @Inject constructor(
private val commandRegistry: CommandRegistry,
private val notificationShadeWindowController: NotificationShadeWindowController,
private val bypassController: KeyguardBypassController,
+ private val biometricUnlockController: BiometricUnlockController,
rippleView: AuthRippleView?
) : ViewController<AuthRippleView>(rippleView) {
var fingerprintSensorLocation: PointF? = null
private var faceSensorLocation: PointF? = null
+ private var circleReveal: LightRevealEffect? = null
@VisibleForTesting
public override fun onViewAttached() {
@@ -96,15 +102,47 @@ class AuthRippleController @Inject constructor(
private fun showRipple() {
notificationShadeWindowController.setForcePluginOpen(true, this)
- mView.startRipple(Runnable {
- notificationShadeWindowController.setForcePluginOpen(false, this)
- })
+ val biometricUnlockMode = biometricUnlockController.mode
+ val useCircleReveal = circleReveal != null &&
+ (biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK ||
+ biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING ||
+ biometricUnlockMode == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM)
+ val lightRevealScrim = statusBar.lightRevealScrim
+ if (useCircleReveal) {
+ lightRevealScrim?.revealEffect = circleReveal!!
+ }
+
+ mView.startRipple(
+ /* end runnable */
+ Runnable {
+ notificationShadeWindowController.setForcePluginOpen(false, this)
+ if (useCircleReveal) {
+ lightRevealScrim?.revealEffect = LiftReveal
+ }
+ },
+ /* circleReveal */
+ if (useCircleReveal) {
+ lightRevealScrim
+ } else {
+ null
+ }
+ )
}
fun updateSensorLocation() {
fingerprintSensorLocation = authController.fingerprintSensorLocation
faceSensorLocation = authController.faceAuthSensorLocation
- statusBar.updateCircleReveal()
+ fingerprintSensorLocation?.let {
+ circleReveal = CircleReveal(
+ it.x,
+ it.y,
+ 0f,
+ Math.max(
+ Math.max(it.x, statusBar.displayWidth - it.x),
+ Math.max(it.y, statusBar.displayHeight - it.y)
+ )
+ )
+ }
}
private fun updateRippleColor() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index 75373abc5124..dd73c4f8d071 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -31,6 +31,7 @@ import android.util.MathUtils
import android.view.View
import android.view.animation.PathInterpolator
import com.android.internal.graphics.ColorUtils
+import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.charging.RippleShader
private const val RIPPLE_ANIMATION_DURATION: Long = 1533
@@ -70,51 +71,79 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
.toFloat()
}
- fun startRipple(onAnimationEnd: Runnable?) {
+ fun startRipple(onAnimationEnd: Runnable?, lightReveal: LightRevealScrim?) {
if (rippleInProgress) {
return // Ignore if ripple effect is already playing
}
- val animator = ValueAnimator.ofFloat(0f, 1f)
- animator.interpolator = PathInterpolator(0.4f, 0f, 0f, 1f)
- animator.duration = RIPPLE_ANIMATION_DURATION
- animator.addUpdateListener { animator ->
- val now = animator.currentPlayTime
- rippleShader.progress = animator.animatedValue as Float
- rippleShader.time = now.toFloat()
- rippleShader.distortionStrength = 1 - rippleShader.progress
- invalidate()
+ val rippleAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
+ interpolator = PathInterpolator(0.4f, 0f, 0f, 1f)
+ duration = RIPPLE_ANIMATION_DURATION
+ addUpdateListener { animator ->
+ val now = animator.currentPlayTime
+ rippleShader.progress = animator.animatedValue as Float
+ rippleShader.time = now.toFloat()
+
+ lightReveal?.revealAmount = animator.animatedValue as Float
+ invalidate()
+ }
}
- val alphaInAnimator = ValueAnimator.ofInt(0, 127)
- alphaInAnimator.duration = 167
- alphaInAnimator.addUpdateListener { alphaInAnimator ->
- rippleShader.color = ColorUtils.setAlphaComponent(rippleShader.color,
- alphaInAnimator.animatedValue as Int)
- invalidate()
+
+ val revealAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
+ interpolator = rippleAnimator.interpolator
+ startDelay = 10
+ duration = rippleAnimator.duration
+ addUpdateListener { animator ->
+ lightReveal?.revealAmount = animator.animatedValue as Float
+ }
}
- val alphaOutAnimator = ValueAnimator.ofInt(127, 0)
- alphaOutAnimator.startDelay = 417
- alphaOutAnimator.duration = 1116
- alphaOutAnimator.addUpdateListener { alphaOutAnimator ->
- rippleShader.color = ColorUtils.setAlphaComponent(rippleShader.color,
- alphaOutAnimator.animatedValue as Int)
- invalidate()
+
+ val alphaInAnimator = ValueAnimator.ofInt(0, 127).apply {
+ duration = 167
+ addUpdateListener { animator ->
+ rippleShader.color = ColorUtils.setAlphaComponent(
+ rippleShader.color,
+ animator.animatedValue as Int
+ )
+ invalidate()
+ }
}
- val animatorSet = AnimatorSet()
- animatorSet.playTogether(animator, alphaInAnimator, alphaOutAnimator)
- animatorSet.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- onAnimationEnd?.run()
- rippleInProgress = false
- visibility = GONE
+ val alphaOutAnimator = ValueAnimator.ofInt(127, 0).apply {
+ startDelay = 417
+ duration = 1116
+ addUpdateListener { animator ->
+ rippleShader.color = ColorUtils.setAlphaComponent(
+ rippleShader.color,
+ animator.animatedValue as Int
+ )
+ invalidate()
}
- })
+ }
+
+ val animatorSet = AnimatorSet().apply {
+ playTogether(
+ rippleAnimator,
+ revealAnimator,
+ alphaInAnimator,
+ alphaOutAnimator
+ )
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationStart(animation: Animator?) {
+ rippleInProgress = true
+ visibility = VISIBLE
+ }
+
+ override fun onAnimationEnd(animation: Animator?) {
+ onAnimationEnd?.run()
+ rippleInProgress = false
+ visibility = GONE
+ }
+ })
+ }
// TODO (b/185124905): custom haptic TBD
// vibrate()
animatorSet.start()
- visibility = VISIBLE
- rippleInProgress = true
}
fun setColor(color: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index f975a804ca80..ec930b0c41d1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -378,6 +378,7 @@ public class UdfpsController implements DozeReceiver {
return true;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_HOVER_ENTER:
+ Trace.beginSection("UdfpsController.onTouch.ACTION_DOWN");
// To simplify the lifecycle of the velocity tracker, make sure it's never null
// after ACTION_DOWN, and always null after ACTION_CANCEL or ACTION_UP.
if (mVelocityTracker == null) {
@@ -388,8 +389,7 @@ public class UdfpsController implements DozeReceiver {
mVelocityTracker.clear();
}
if (isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView)) {
- Trace.beginAsyncSection(
- "UdfpsController#ACTION_DOWN", 1);
+ Trace.beginAsyncSection("UdfpsController.e2e.onPointerDown", 0);
// The pointer that causes ACTION_DOWN is always at index 0.
// We need to persist its ID to track it during ACTION_MOVE that could include
// data for many other pointers because of multi-touch support.
@@ -397,10 +397,12 @@ public class UdfpsController implements DozeReceiver {
mVelocityTracker.addMovement(event);
handled = true;
}
+ Trace.endSection();
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_HOVER_MOVE:
+ Trace.beginSection("UdfpsController.onTouch.ACTION_MOVE");
final int idx = mActivePointerId == -1
? event.getPointerId(0)
: event.findPointerIndex(mActivePointerId);
@@ -466,11 +468,13 @@ public class UdfpsController implements DozeReceiver {
onFingerUp();
}
}
+ Trace.endSection();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_HOVER_EXIT:
+ Trace.beginSection("UdfpsController.onTouch.ACTION_UP");
mActivePointerId = -1;
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
@@ -479,7 +483,7 @@ public class UdfpsController implements DozeReceiver {
Log.v(TAG, "onTouch | finger up");
onFingerUp();
mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
-
+ Trace.endSection();
break;
default:
@@ -818,12 +822,11 @@ public class UdfpsController implements DozeReceiver {
return;
}
mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
- Trace.endAsyncSection(
- "UdfpsController#ACTION_DOWN", 1);
- Trace.beginAsyncSection("UdfpsController#startIllumination", 1);
+ Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
+ Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0);
mView.startIllumination(() -> {
mFingerprintManager.onUiReady(mSensorProps.sensorId);
- Trace.endAsyncSection("UdfpsController#startIllumination", 1);
+ Trace.endAsyncSection("UdfpsController.e2e.startIllumination", 0);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 980bb12d390c..00888dfe48d3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -355,7 +355,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@Override
public void onBouncerVisibilityChanged() {
- mIsBouncerVisible = mKeyguardViewManager.bouncerIsOrWillBeShowing();
+ mIsBouncerVisible = mKeyguardViewManager.isBouncerShowing();
if (!mIsBouncerVisible) {
mInputBouncerHiddenAmount = 1f;
} else if (mKeyguardViewManager.isBouncerShowing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 39adabb06d40..23c44131ab60 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -70,6 +70,7 @@ public class DozeSensors {
private final Consumer<Boolean> mProxCallback;
private final SecureSettings mSecureSettings;
private final Callback mCallback;
+ private final boolean mScreenOffUdfpsEnabled;
@VisibleForTesting
protected TriggerSensor[] mSensors;
@@ -116,6 +117,8 @@ public class DozeSensors {
mProximitySensor = proximitySensor;
mSelectivelyRegisterProxSensors = dozeParameters.getSelectivelyRegisterSensorsUsingProx();
mListeningProxSensors = !mSelectivelyRegisterProxSensors;
+ mScreenOffUdfpsEnabled =
+ config.screenOffUdfpsEnabled(KeyguardUpdateMonitor.getCurrentUser());
boolean udfpsEnrolled =
authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser());
@@ -171,7 +174,7 @@ public class DozeSensors {
findSensorWithType(config.udfpsLongPressSensorType()),
"doze_pulse_on_auth",
true /* settingDef */,
- udfpsEnrolled,
+ udfpsEnrolled && (alwaysOn || mScreenOffUdfpsEnabled),
DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
true /* reports touch coordinates */,
true /* touchscreen */,
@@ -369,6 +372,7 @@ public class DozeSensors {
pw.println("mListeningTouchScreenSensors=" + mListeningTouchScreenSensors);
pw.println("mSelectivelyRegisterProxSensors=" + mSelectivelyRegisterProxSensors);
pw.println("mListeningProxSensors=" + mListeningProxSensors);
+ pw.println("mScreenOffUdfpsEnabled=" + mScreenOffUdfpsEnabled);
IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
idpw.increaseIndent();
for (TriggerSensor s : mSensors) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index ff95604088ed..7b34e52c16e8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -38,6 +38,7 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.doze.DozeMachine.State;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.Assert;
@@ -96,6 +97,7 @@ public class DozeTriggers implements DozeMachine.Part {
private long mNotificationPulseTime;
private boolean mPulsePending;
+ private Runnable mAodInterruptRunnable;
/** see {@link #onProximityFar} prox for callback */
private boolean mWantProxSensor;
@@ -303,11 +305,16 @@ public class DozeTriggers implements DozeMachine.Part {
} else if (isPickup) {
gentleWakeUp(pulseReason);
} else if (isUdfpsLongPress) {
+ final State state = mMachine.getState();
+ if (state == State.DOZE_AOD || state == State.DOZE) {
+ // Since the gesture won't be received by the UDFPS view, we need to
+ // manually inject an event once the display is ON
+ mAodInterruptRunnable = () ->
+ mAuthController.onAodInterrupt((int) screenX, (int) screenY,
+ rawValues[3] /* major */, rawValues[4] /* minor */);
+ }
+
requestPulse(DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS, true, null);
- // Since the gesture won't be received by the UDFPS view, manually inject an
- // event.
- mAuthController.onAodInterrupt((int) screenX, (int) screenY,
- rawValues[3] /* major */, rawValues[4] /* minor */);
} else {
mDozeHost.extendPulse(pulseReason);
}
@@ -439,6 +446,7 @@ public class DozeTriggers implements DozeMachine.Part {
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {
case INITIALIZED:
+ mAodInterruptRunnable = null;
sWakeDisplaySensorState = true;
mBroadcastReceiver.register(mBroadcastDispatcher);
mDozeHost.addCallback(mHostCallback);
@@ -448,6 +456,7 @@ public class DozeTriggers implements DozeMachine.Part {
break;
case DOZE:
case DOZE_AOD:
+ mAodInterruptRunnable = null;
mWantProxSensor = newState != DozeMachine.State.DOZE;
mWantSensors = true;
mWantTouchScreenSensors = true;
@@ -494,6 +503,11 @@ public class DozeTriggers implements DozeMachine.Part {
|| state == Display.STATE_DOZE_SUSPEND || state == Display.STATE_OFF;
mDozeSensors.setProxListening(mWantProxSensor && lowPowerStateOrOff);
mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors, lowPowerStateOrOff);
+
+ if (mAodInterruptRunnable != null && state == Display.STATE_ON) {
+ mAodInterruptRunnable.run();
+ mAodInterruptRunnable = null;
+ }
}
/**
@@ -576,6 +590,8 @@ public class DozeTriggers implements DozeMachine.Part {
@Override
public void dump(PrintWriter pw) {
+ pw.println(" mAodInterruptRunnable=" + mAodInterruptRunnable);
+
pw.print(" notificationPulseTime=");
pw.println(Formatter.formatShortElapsedTime(mContext, mNotificationPulseTime));
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index ff3cb2102d60..fbe06b02d955 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -21,6 +21,7 @@ import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
import android.app.AlarmManager;
import android.content.Context;
+import android.content.res.Configuration;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
@@ -34,6 +35,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.AlarmTimeout;
import com.android.systemui.util.wakelock.WakeLock;
@@ -48,7 +50,8 @@ import dagger.Lazy;
* The policy controlling doze.
*/
@DozeScope
-public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
+public class DozeUi implements DozeMachine.Part, TunerService.Tunable,
+ ConfigurationController.ConfigurationListener {
// if enabled, calls dozeTimeTick() whenever the time changes:
private static final boolean BURN_IN_TESTING_ENABLED = false;
private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
@@ -63,6 +66,7 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
private final DozeLog mDozeLog;
private final Lazy<StatusBarStateController> mStatusBarStateController;
private final TunerService mTunerService;
+ private final ConfigurationController mConfigurationController;
private boolean mKeyguardShowing;
private final KeyguardUpdateMonitorCallback mKeyguardVisibilityCallback =
@@ -84,6 +88,11 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
mHandler.post(mWakeLock.wrap(() -> {}));
}
}
+
+ @Override
+ public void onShadeExpandedChanged(boolean expanded) {
+ updateAnimateScreenOff();
+ }
};
private long mLastTimeTickElapsed = 0;
@@ -93,7 +102,8 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
WakeLock wakeLock, DozeHost host, @Main Handler handler,
DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor,
DozeLog dozeLog, TunerService tunerService,
- Lazy<StatusBarStateController> statusBarStateController) {
+ Lazy<StatusBarStateController> statusBarStateController,
+ ConfigurationController configurationController) {
mContext = context;
mWakeLock = wakeLock;
mHost = host;
@@ -107,11 +117,15 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
mStatusBarStateController = statusBarStateController;
mTunerService.addTunable(this, Settings.Secure.DOZE_ALWAYS_ON);
+
+ mConfigurationController = configurationController;
+ mConfigurationController.addCallback(this);
}
@Override
public void destroy() {
mTunerService.removeTunable(this);
+ mConfigurationController.removeCallback(this);
}
@Override
@@ -274,4 +288,9 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
updateAnimateScreenOff();
}
}
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ updateAnimateScreenOff();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index dfd85fe4dc90..bb44b09f1bce 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -30,6 +30,7 @@ import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
@@ -72,6 +73,7 @@ import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -112,47 +114,101 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
@VisibleForTesting
boolean mShowLockScreenCards = false;
+ private final KeyguardStateController.Callback mKeyguardStateControllerListener =
+ new KeyguardStateController.Callback() {
+ @Override
+ public void onUnlockedChanged() {
+ if (mDialog != null) {
+ ActionsDialog dialog = (ActionsDialog) mDialog;
+ boolean unlocked = mKeyguardStateController.isUnlocked();
+ if (dialog.mWalletViewController != null) {
+ dialog.mWalletViewController.onDeviceLockStateChanged(!unlocked);
+ }
+
+ if (unlocked) {
+ dialog.hideLockMessage();
+ }
+ }
+ }
+ };
+
+ private final ContentObserver mSettingsObserver = new ContentObserver(mMainHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ onPowerMenuLockScreenSettingsChanged();
+ }
+ };
+
/**
* @param context everything needs a context :(
*/
@Inject
- public GlobalActionsDialog(Context context, GlobalActionsManager windowManagerFuncs,
- AudioManager audioManager, IDreamManager iDreamManager,
- DevicePolicyManager devicePolicyManager, LockPatternUtils lockPatternUtils,
+ public GlobalActionsDialog(
+ Context context,
+ GlobalActionsManager windowManagerFuncs,
+ AudioManager audioManager,
+ IDreamManager iDreamManager,
+ DevicePolicyManager devicePolicyManager,
+ LockPatternUtils lockPatternUtils,
BroadcastDispatcher broadcastDispatcher,
TelephonyListenerManager telephonyListenerManager,
- GlobalSettings globalSettings, SecureSettings secureSettings,
- @Nullable Vibrator vibrator, @Main Resources resources,
- ConfigurationController configurationController, ActivityStarter activityStarter,
- KeyguardStateController keyguardStateController, UserManager userManager,
- TrustManager trustManager, IActivityManager iActivityManager,
- @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
- NotificationShadeDepthController depthController, SysuiColorExtractor colorExtractor,
+ GlobalSettings globalSettings,
+ SecureSettings secureSettings,
+ @Nullable Vibrator vibrator,
+ @Main Resources resources,
+ ConfigurationController configurationController,
+ ActivityStarter activityStarter,
+ KeyguardStateController keyguardStateController,
+ UserManager userManager,
+ TrustManager trustManager,
+ IActivityManager iActivityManager,
+ @Nullable TelecomManager telecomManager,
+ MetricsLogger metricsLogger,
+ NotificationShadeDepthController depthController,
+ SysuiColorExtractor colorExtractor,
IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
IWindowManager iWindowManager,
@Background Executor backgroundExecutor,
UiEventLogger uiEventLogger,
- RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler) {
-
- super(context, windowManagerFuncs,
- audioManager, iDreamManager,
- devicePolicyManager, lockPatternUtils,
- broadcastDispatcher, telephonyListenerManager,
- globalSettings, secureSettings,
- vibrator, resources,
+ RingerModeTracker ringerModeTracker,
+ SysUiState sysUiState,
+ @Main Handler handler,
+ PackageManager packageManager,
+ StatusBar statusBar) {
+
+ super(context,
+ windowManagerFuncs,
+ audioManager,
+ iDreamManager,
+ devicePolicyManager,
+ lockPatternUtils,
+ broadcastDispatcher,
+ telephonyListenerManager,
+ globalSettings,
+ secureSettings,
+ vibrator,
+ resources,
configurationController,
- keyguardStateController, userManager,
- trustManager, iActivityManager,
- telecomManager, metricsLogger,
- depthController, colorExtractor,
+ keyguardStateController,
+ userManager,
+ trustManager,
+ iActivityManager,
+ telecomManager,
+ metricsLogger,
+ depthController,
+ colorExtractor,
statusBarService,
notificationShadeWindowController,
iWindowManager,
backgroundExecutor,
uiEventLogger,
null,
- ringerModeTracker, sysUiState, handler);
+ ringerModeTracker,
+ sysUiState,
+ handler,
+ packageManager,
+ statusBar);
mLockPatternUtils = lockPatternUtils;
mKeyguardStateController = keyguardStateController;
@@ -162,34 +218,22 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
mNotificationShadeWindowController = notificationShadeWindowController;
mSysUiState = sysUiState;
mActivityStarter = activityStarter;
- keyguardStateController.addCallback(new KeyguardStateController.Callback() {
- @Override
- public void onUnlockedChanged() {
- if (mDialog != null) {
- ActionsDialog dialog = (ActionsDialog) mDialog;
- boolean unlocked = mKeyguardStateController.isUnlocked();
- if (dialog.mWalletViewController != null) {
- dialog.mWalletViewController.onDeviceLockStateChanged(!unlocked);
- }
- if (unlocked) {
- dialog.hideLockMessage();
- }
- }
- }
- });
+ mKeyguardStateController.addCallback(mKeyguardStateControllerListener);
// Listen for changes to show pay on the power menu while locked
onPowerMenuLockScreenSettingsChanged();
mGlobalSettings.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT),
false /* notifyForDescendants */,
- new ContentObserver(handler) {
- @Override
- public void onChange(boolean selfChange) {
- onPowerMenuLockScreenSettingsChanged();
- }
- });
+ mSettingsObserver);
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ mKeyguardStateController.removeCallback(mKeyguardStateControllerListener);
+ mGlobalSettings.unregisterContentObserver(mSettingsObserver);
}
/**
@@ -227,7 +271,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
ActionsDialog dialog = new ActionsDialog(getContext(), mAdapter, mOverflowAdapter,
this::getWalletViewController, mDepthController, mSysuiColorExtractor,
mStatusBarService, mNotificationShadeWindowController,
- mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter, getEventLogger());
+ mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter, getEventLogger(),
+ getStatusBar());
if (shouldShowLockMessage(dialog)) {
dialog.showLockMessage();
@@ -295,11 +340,13 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite
SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
- MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger) {
+ MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
+ StatusBar statusBar) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions,
adapter, overflowAdapter, depthController, sysuiColorExtractor,
statusBarService, notificationShadeWindowController, sysuiState,
- onRotateCallback, keyguardShowing, powerAdapter, uiEventLogger, null);
+ onRotateCallback, keyguardShowing, powerAdapter, uiEventLogger, null,
+ statusBar);
mWalletFactory = walletFactory;
// Update window attributes
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 8e152830e208..42cd4f7da3a8 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -74,8 +74,10 @@ import android.telephony.TelephonyManager;
import android.util.ArraySet;
import android.util.Log;
import android.view.ContextThemeWrapper;
+import android.view.GestureDetector;
import android.view.IWindowManager;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
@@ -119,6 +121,7 @@ import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.scrim.ScrimDrawable;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -174,6 +177,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
private final IDreamManager mDreamManager;
private final DevicePolicyManager mDevicePolicyManager;
private final LockPatternUtils mLockPatternUtils;
+ private final TelephonyListenerManager mTelephonyListenerManager;
private final KeyguardStateController mKeyguardStateController;
private final BroadcastDispatcher mBroadcastDispatcher;
protected final GlobalSettings mGlobalSettings;
@@ -228,6 +232,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
private int mDialogPressDelay = DIALOG_PRESS_DELAY; // ms
protected Handler mMainHandler;
private int mSmallestScreenWidthDp;
+ private final StatusBar mStatusBar;
@VisibleForTesting
public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum {
@@ -304,31 +309,46 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
* @param context everything needs a context :(
*/
@Inject
- public GlobalActionsDialogLite(Context context, GlobalActionsManager windowManagerFuncs,
- AudioManager audioManager, IDreamManager iDreamManager,
- DevicePolicyManager devicePolicyManager, LockPatternUtils lockPatternUtils,
+ public GlobalActionsDialogLite(
+ Context context,
+ GlobalActionsManager windowManagerFuncs,
+ AudioManager audioManager,
+ IDreamManager iDreamManager,
+ DevicePolicyManager devicePolicyManager,
+ LockPatternUtils lockPatternUtils,
BroadcastDispatcher broadcastDispatcher,
TelephonyListenerManager telephonyListenerManager,
- GlobalSettings globalSettings, SecureSettings secureSettings,
- @Nullable Vibrator vibrator, @Main Resources resources,
+ GlobalSettings globalSettings,
+ SecureSettings secureSettings,
+ @Nullable Vibrator vibrator,
+ @Main Resources resources,
ConfigurationController configurationController,
- KeyguardStateController keyguardStateController, UserManager userManager,
- TrustManager trustManager, IActivityManager iActivityManager,
- @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
- NotificationShadeDepthController depthController, SysuiColorExtractor colorExtractor,
+ KeyguardStateController keyguardStateController,
+ UserManager userManager,
+ TrustManager trustManager,
+ IActivityManager iActivityManager,
+ @Nullable TelecomManager telecomManager,
+ MetricsLogger metricsLogger,
+ NotificationShadeDepthController depthController,
+ SysuiColorExtractor colorExtractor,
IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
IWindowManager iWindowManager,
@Background Executor backgroundExecutor,
UiEventLogger uiEventLogger,
GlobalActionsInfoProvider infoProvider,
- RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler) {
+ RingerModeTracker ringerModeTracker,
+ SysUiState sysUiState,
+ @Main Handler handler,
+ PackageManager packageManager,
+ StatusBar statusBar) {
mContext = context;
mWindowManagerFuncs = windowManagerFuncs;
mAudioManager = audioManager;
mDreamManager = iDreamManager;
mDevicePolicyManager = devicePolicyManager;
mLockPatternUtils = lockPatternUtils;
+ mTelephonyListenerManager = telephonyListenerManager;
mKeyguardStateController = keyguardStateController;
mBroadcastDispatcher = broadcastDispatcher;
mGlobalSettings = globalSettings;
@@ -351,7 +371,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mRingerModeTracker = ringerModeTracker;
mSysUiState = sysUiState;
mMainHandler = handler;
- mSmallestScreenWidthDp = mContext.getResources().getConfiguration().smallestScreenWidthDp;
+ mSmallestScreenWidthDp = resources.getConfiguration().smallestScreenWidthDp;
+ mStatusBar = statusBar;
// receive broadcasts
IntentFilter filter = new IntentFilter();
@@ -360,11 +381,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
filter.addAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
- mHasTelephony =
- context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
// get notified of phone state changes
- telephonyListenerManager.addServiceStateListener(mPhoneStateListener);
+ mTelephonyListenerManager.addServiceStateListener(mPhoneStateListener);
mGlobalSettings.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
mAirplaneModeObserver);
@@ -384,6 +404,16 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mConfigurationController.addCallback(this);
}
+ /**
+ * Clean up callbacks
+ */
+ public void destroy() {
+ mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
+ mTelephonyListenerManager.removeServiceStateListener(mPhoneStateListener);
+ mGlobalSettings.unregisterContentObserver(mAirplaneModeObserver);
+ mConfigurationController.removeCallback(this);
+ }
+
protected Context getContext() {
return mContext;
}
@@ -392,6 +422,10 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
return mUiEventLogger;
}
+ protected StatusBar getStatusBar() {
+ return mStatusBar;
+ }
+
/**
* Show the global actions dialog (creating if necessary)
*
@@ -625,7 +659,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mDepthController, mSysuiColorExtractor,
mStatusBarService, mNotificationShadeWindowController,
mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger,
- mInfoProvider);
+ mInfoProvider, mStatusBar);
dialog.setOnDismissListener(this);
dialog.setOnShowListener(this);
@@ -679,14 +713,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mDialog.refreshDialog();
}
}
-
- /**
- * Clean up callbacks
- */
- public void destroy() {
- mConfigurationController.removeCallback(this);
- }
-
/**
* Implements {@link GlobalActionsPanelPlugin.Callbacks#dismissGlobalActionsMenu()}, which is
* called when the quick access wallet requests dismissal.
@@ -2008,7 +2034,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
}
};
- private ContentObserver mAirplaneModeObserver = new ContentObserver(mMainHandler) {
+ private final ContentObserver mAirplaneModeObserver = new ContentObserver(mMainHandler) {
@Override
public void onChange(boolean selfChange) {
onAirplaneModeChanged();
@@ -2100,9 +2126,53 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
protected final Runnable mOnRotateCallback;
private UiEventLogger mUiEventLogger;
private GlobalActionsInfoProvider mInfoProvider;
+ private GestureDetector mGestureDetector;
+ private StatusBar mStatusBar;
protected ViewGroup mContainer;
+ @VisibleForTesting
+ protected GestureDetector.SimpleOnGestureListener mGestureListener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onDown(MotionEvent e) {
+ // All gestures begin with this message, so continue listening
+ return true;
+ }
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ // Close without opening shade
+ mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
+ cancel();
+ return false;
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
+ float distanceY) {
+ if (distanceY < 0 && distanceY > distanceX
+ && e1.getY() <= mStatusBar.getStatusBarHeight()) {
+ // Downwards scroll from top
+ openShadeAndDismiss();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+ float velocityY) {
+ if (velocityY > 0 && Math.abs(velocityY) > Math.abs(velocityX)
+ && e1.getY() <= mStatusBar.getStatusBarHeight()) {
+ // Downwards fling from top
+ openShadeAndDismiss();
+ return true;
+ }
+ return false;
+ }
+ };
+
ActionsDialogLite(Context context, int themeRes, MyAdapter adapter,
MyOverflowAdapter overflowAdapter,
NotificationShadeDepthController depthController,
@@ -2110,7 +2180,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
NotificationShadeWindowController notificationShadeWindowController,
SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing,
MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
- @Nullable GlobalActionsInfoProvider infoProvider) {
+ @Nullable GlobalActionsInfoProvider infoProvider, StatusBar statusBar) {
super(context, themeRes);
mContext = context;
mAdapter = adapter;
@@ -2125,6 +2195,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mKeyguardShowing = keyguardShowing;
mUiEventLogger = uiEventLogger;
mInfoProvider = infoProvider;
+ mStatusBar = statusBar;
+
+ mGestureDetector = new GestureDetector(mContext, mGestureListener);
// Window initialization
Window window = getWindow();
@@ -2146,6 +2219,23 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
initializeLayout();
}
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return mGestureDetector.onTouchEvent(event) || super.onTouchEvent(event);
+ }
+
+ private void openShadeAndDismiss() {
+ mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
+ if (mStatusBar.isKeyguardShowing()) {
+ // match existing lockscreen behavior to open QS when swiping from status bar
+ mStatusBar.animateExpandSettingsPanel(null);
+ } else {
+ // otherwise, swiping down should expand notification shade
+ mStatusBar.animateExpandNotificationsPanel();
+ }
+ dismiss();
+ }
+
private ListPopupWindow createPowerOverflowPopup() {
GlobalActionsPopupMenu popup = new GlobalActionsPopupMenu(
new ContextThemeWrapper(
@@ -2194,9 +2284,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mGlobalActionsLayout.setRotationListener(this::onRotate);
mGlobalActionsLayout.setAdapter(mAdapter);
mContainer = findViewById(com.android.systemui.R.id.global_actions_container);
- mContainer.setOnClickListener(v -> {
- mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
- cancel();
+ mContainer.setOnTouchListener((v, event) -> {
+ mGestureDetector.onTouchEvent(event);
+ return v.onTouchEvent(event);
});
View overflowButton = findViewById(
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 178a74cecc2e..e37d3d586ccc 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -32,7 +32,6 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.Utils;
-import com.android.systemui.Dependency;
import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.scrim.ScrimDrawable;
import com.android.systemui.statusbar.BlurUtils;
@@ -52,19 +51,24 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
private final KeyguardStateController mKeyguardStateController;
private final DeviceProvisionedController mDeviceProvisionedController;
private final BlurUtils mBlurUtils;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final CommandQueue mCommandQueue;
private GlobalActionsDialogLite mGlobalActionsDialog;
private boolean mDisabled;
@Inject
public GlobalActionsImpl(Context context, CommandQueue commandQueue,
- Lazy<GlobalActionsDialogLite> globalActionsDialogLazy, BlurUtils blurUtils) {
+ Lazy<GlobalActionsDialogLite> globalActionsDialogLazy, BlurUtils blurUtils,
+ KeyguardStateController keyguardStateController,
+ DeviceProvisionedController deviceProvisionedController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor) {
mContext = context;
mGlobalActionsDialogLazy = globalActionsDialogLazy;
- mKeyguardStateController = Dependency.get(KeyguardStateController.class);
- mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+ mKeyguardStateController = keyguardStateController;
+ mDeviceProvisionedController = deviceProvisionedController;
mCommandQueue = commandQueue;
mBlurUtils = blurUtils;
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mCommandQueue.addCallback(this);
}
@@ -83,7 +87,7 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
mGlobalActionsDialog = mGlobalActionsDialogLazy.get();
mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(),
mDeviceProvisionedController.isDeviceProvisioned());
- Dependency.get(KeyguardUpdateMonitor.class).requestFaceAuth();
+ mKeyguardUpdateMonitor.requestFaceAuth();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsInfoProvider.kt b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsInfoProvider.kt
index 39008eecd6a2..17b532a643cd 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsInfoProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsInfoProvider.kt
@@ -25,6 +25,7 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
+import android.widget.TextView
import com.android.systemui.R
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.plugins.ActivityStarter
@@ -70,6 +71,11 @@ class GlobalActionsInfoProvider @Inject constructor(
val view = LayoutInflater.from(context).inflate(R.layout.global_actions_change_panel,
parent, false)
+
+ val walletTitle = walletClient.serviceLabel ?: context.getString(R.string.wallet_title)
+ val message = view.findViewById<TextView>(R.id.global_actions_change_message)
+ message?.setText(context.getString(R.string.global_actions_change_description, walletTitle))
+
val button = view.findViewById<ImageView>(R.id.global_actions_change_button)
button.setOnClickListener { _ ->
dismissParent.run()
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 01a353ce8f1f..d30783c29f92 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -46,6 +46,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer {
private final ImageGLWallpaper mWallpaper;
private final Rect mSurfaceSize = new Rect();
private final WallpaperTexture mTexture;
+ private Consumer<Bitmap> mOnBitmapUpdated;
public ImageWallpaperRenderer(Context context) {
final WallpaperManager wpm = context.getSystemService(WallpaperManager.class);
@@ -60,10 +61,9 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer {
/**
* @hide
- * @return
*/
- public void useBitmap(Consumer<Bitmap> c) {
- mTexture.use(c);
+ public void setOnBitmapChanged(Consumer<Bitmap> c) {
+ mOnBitmapUpdated = c;
}
@Override
@@ -80,6 +80,8 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer {
mTexture.use(bitmap -> {
if (bitmap == null) {
Log.w(TAG, "reload texture failed!");
+ } else if (mOnBitmapUpdated != null) {
+ mOnBitmapUpdated.accept(bitmap);
}
mWallpaper.setup(bitmap);
});
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index bec4ce6ba658..fc5f3b8ae994 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -20,7 +20,6 @@ import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.text.TextUtils;
-import android.view.View;
import androidx.annotation.IntDef;
@@ -202,10 +201,7 @@ public class KeyguardIndicationRotateTextViewController extends
mCurrIndicationType = type;
mIndicationQueue.removeIf(x -> x == type);
- if (mCurrIndicationType == INDICATION_TYPE_NONE) {
- mView.setVisibility(View.GONE);
- } else {
- mView.setVisibility(View.VISIBLE);
+ if (mCurrIndicationType != INDICATION_TYPE_NONE) {
mIndicationQueue.add(type); // re-add to show later
}
@@ -299,7 +295,7 @@ public class KeyguardIndicationRotateTextViewController extends
}
}
- private static final int INDICATION_TYPE_NONE = -1;
+ static final int INDICATION_TYPE_NONE = -1;
public static final int INDICATION_TYPE_OWNER_INFO = 0;
public static final int INDICATION_TYPE_DISCLOSURE = 1;
public static final int INDICATION_TYPE_LOGOUT = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
index 77d789292e5e..2bf102f724f4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
@@ -186,11 +186,9 @@ class KeyguardMediaController @Inject constructor(
}
private fun hideMediaPlayer() {
- if (useSplitShade) {
- setVisibility(splitShadeContainer, View.GONE)
- } else {
- setVisibility(singlePaneContainer, View.GONE)
- }
+ // always hide splitShadeContainer as it's initially visible and may influence layout
+ setVisibility(splitShadeContainer, View.GONE)
+ setVisibility(singlePaneContainer, View.GONE)
}
private fun setVisibility(view: ViewGroup?, newVisibility: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index c2b580773424..19190cd4a17d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -46,6 +46,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.constraintlayout.widget.ConstraintSet;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.settingslib.widget.AdaptiveIcon;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -468,7 +469,8 @@ public class MediaControlPanel {
TransitionLayout player) {
// TODO(b/174236650): Make sure that the carousel indicator also fades out.
// TODO(b/174236650): Instrument the animation to measure jank.
- return new GhostedViewLaunchAnimatorController(player) {
+ return new GhostedViewLaunchAnimatorController(player,
+ InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER) {
@Override
protected float getCurrentTopCornerRadius() {
return ((IlluminationDrawable) player.getBackground()).getCornerRadius();
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 5b1e039ad0f8..28d336ea18d5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -39,6 +39,7 @@ import android.media.session.MediaSession
import android.net.Uri
import android.os.Parcelable
import android.os.UserHandle
+import android.provider.Settings
import android.service.notification.StatusBarNotification
import android.text.TextUtils
import android.util.Log
@@ -54,6 +55,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.BcSmartspaceDataPlugin
import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState
import com.android.systemui.statusbar.notification.row.HybridGroupManager
+import com.android.systemui.tuner.TunerService
import com.android.systemui.util.Assert
import com.android.systemui.util.Utils
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -114,7 +116,8 @@ class MediaDataManager(
private val smartspaceMediaDataProvider: SmartspaceMediaDataProvider,
private var useMediaResumption: Boolean,
private val useQsMediaPlayer: Boolean,
- private val systemClock: SystemClock
+ private val systemClock: SystemClock,
+ private val tunerService: TunerService
) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener {
companion object {
@@ -147,6 +150,7 @@ class MediaDataManager(
// There should ONLY be at most one Smartspace media recommendation.
private var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
private var smartspaceSession: SmartspaceSession? = null
+ private var allowMediaRecommendations = Utils.allowMediaRecommendations(context)
@Inject
constructor(
@@ -164,12 +168,13 @@ class MediaDataManager(
mediaDataFilter: MediaDataFilter,
activityStarter: ActivityStarter,
smartspaceMediaDataProvider: SmartspaceMediaDataProvider,
- clock: SystemClock
+ clock: SystemClock,
+ tunerService: TunerService
) : this(context, backgroundExecutor, foregroundExecutor, mediaControllerFactory,
broadcastDispatcher, dumpManager, mediaTimeoutListener, mediaResumeListener,
mediaSessionBasedFilter, mediaDeviceManager, mediaDataCombineLatest, mediaDataFilter,
activityStarter, smartspaceMediaDataProvider, Utils.useMediaResumption(context),
- Utils.useQsMediaPlayer(context), clock)
+ Utils.useQsMediaPlayer(context), clock, tunerService)
private val appChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -243,6 +248,14 @@ class MediaDataManager(
})
}
smartspaceSession?.let { it.requestSmartspaceUpdate() }
+ tunerService.addTunable(object : TunerService.Tunable {
+ override fun onTuningChanged(key: String?, newValue: String?) {
+ allowMediaRecommendations = Utils.allowMediaRecommendations(context)
+ if (!allowMediaRecommendations) {
+ dismissSmartspaceRecommendation(key = smartspaceMediaData.targetId, delay = 0L)
+ }
+ }
+ }, Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION)
}
fun destroy() {
@@ -695,8 +708,7 @@ class MediaDataManager(
}
override fun onSmartspaceTargetsUpdated(targets: List<Parcelable>) {
- if (!Utils.allowMediaRecommendations(context)) {
- Log.d(TAG, "Smartspace recommendation is disabled in Settings.")
+ if (!allowMediaRecommendations) {
return
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 075bc700cfa0..edbf18789e28 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -187,6 +187,12 @@ class MediaHierarchyManager @Inject constructor(
private var currentAttachmentLocation = -1
/**
+ * Is there any active media in the carousel?
+ */
+ private var hasActiveMedia: Boolean = false
+ get() = mediaHosts.get(LOCATION_QQS)?.visible == true
+
+ /**
* Are we currently waiting on an animation to start?
*/
private var animationPending: Boolean = false
@@ -476,8 +482,12 @@ class MediaHierarchyManager @Inject constructor(
val viewHost = createUniqueObjectHost()
mediaObject.hostView = viewHost
mediaObject.addVisibilityChangeListener {
+ // If QQS changes visibility, we need to force an update to ensure the transition
+ // goes into the correct state
+ val stateUpdate = mediaObject.location == LOCATION_QQS
+
// Never animate because of a visibility change, only state changes should do that
- updateDesiredLocation(forceNoAnimation = true)
+ updateDesiredLocation(forceNoAnimation = true, forceStateUpdate = stateUpdate)
}
mediaHosts[mediaObject.location] = mediaObject
if (mediaObject.location == desiredLocation) {
@@ -521,10 +531,15 @@ class MediaHierarchyManager @Inject constructor(
* going from the old desired location to the new one.
*
* @param forceNoAnimation optional parameter telling the system not to animate
+ * @param forceStateUpdate optional parameter telling the system to update transition state
+ * even if location did not change
*/
- private fun updateDesiredLocation(forceNoAnimation: Boolean = false) {
+ private fun updateDesiredLocation(
+ forceNoAnimation: Boolean = false,
+ forceStateUpdate: Boolean = false
+ ) {
val desiredLocation = calculateLocation()
- if (desiredLocation != this.desiredLocation) {
+ if (desiredLocation != this.desiredLocation || forceStateUpdate) {
if (this.desiredLocation >= 0) {
previousLocation = this.desiredLocation
}
@@ -784,7 +799,7 @@ class MediaHierarchyManager @Inject constructor(
private fun getQSTransformationProgress(): Float {
val currentHost = getHost(desiredLocation)
val previousHost = getHost(previousLocation)
- if (currentHost?.location == LOCATION_QS) {
+ if (hasActiveMedia && currentHost?.location == LOCATION_QS) {
if (previousHost?.location == LOCATION_QQS) {
if (previousHost.visible || statusbarState != StatusBarState.KEYGUARD) {
return qsExpansion
@@ -917,6 +932,7 @@ class MediaHierarchyManager @Inject constructor(
val location = when {
qsExpansion > 0.0f && !onLockscreen -> LOCATION_QS
qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
+ !hasActiveMedia -> LOCATION_QS
onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
onLockscreen && allowedOnLockscreen -> LOCATION_LOCKSCREEN
else -> LOCATION_QQS
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 0d9749e05262..ff5d0b157c80 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -251,8 +251,9 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
private float mMLResults;
// For debugging
- private ArrayDeque<String> mPredictionLog = new ArrayDeque<>();
- private ArrayDeque<String> mGestureLog = new ArrayDeque<>();
+ private LogArray mPredictionLog = new LogArray(MAX_NUM_LOGGED_PREDICTIONS);
+ private LogArray mGestureLogInsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);
+ private LogArray mGestureLogOutsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);
private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
@@ -631,7 +632,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
return mMLResults >= mMLModelThreshold ? 1 : 0;
}
- private boolean isWithinTouchRegion(int x, int y) {
+ private boolean isWithinInsets(int x, int y) {
// Disallow if we are in the bottom gesture area
if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
return false;
@@ -644,7 +645,10 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
&& x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) {
return false;
}
+ return true;
+ }
+ private boolean isWithinTouchRegion(int x, int y) {
// If the point is inside the PiP or Nav bar overlay excluded bounds, then ignore the back
// gesture
final boolean isInsidePip = mIsInPipMode && mPipExcludedBounds.contains(x, y);
@@ -675,14 +679,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
}
// For debugging purposes
- if (mPredictionLog.size() >= MAX_NUM_LOGGED_PREDICTIONS) {
- mPredictionLog.removeFirst();
- }
- mPredictionLog.addLast(String.format("Prediction [%d,%d,%d,%d,%f,%d]",
+ mPredictionLog.log(String.format("Prediction [%d,%d,%d,%d,%f,%d]",
System.currentTimeMillis(), x, y, app, mMLResults, withinRange ? 1 : 0));
- if (DEBUG_MISSING_GESTURE) {
- Log.d(DEBUG_MISSING_GESTURE_TAG, mPredictionLog.peekLast());
- }
// Always allow if the user is in a transient sticky immersive state
if (mIsNavBarShownTransiently) {
@@ -755,7 +753,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
mMLResults = 0;
mLogGesture = false;
mInRejectedExclusion = false;
- mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed
+ boolean isWithinInsets = isWithinInsets((int) ev.getX(), (int) ev.getY());
+ mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed && isWithinInsets
&& !mGestureBlockingActivityRunning
&& !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
&& isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
@@ -769,18 +768,13 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
mThresholdCrossed = false;
}
- // For debugging purposes
- if (mGestureLog.size() >= MAX_NUM_LOGGED_GESTURES) {
- mGestureLog.removeFirst();
- }
- mGestureLog.addLast(String.format(
+ // For debugging purposes, only log edge points
+ (isWithinInsets ? mGestureLogInsideInsets : mGestureLogOutsideInsets).log(String.format(
"Gesture [%d,alw=%B,%B,%B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
- System.currentTimeMillis(), mAllowGesture, mIsOnLeftEdge, mIsBackGestureAllowed,
+ System.currentTimeMillis(), mAllowGesture, mIsOnLeftEdge,
+ mIsBackGestureAllowed,
QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisplaySize,
mEdgeWidthLeft, mLeftInset, mEdgeWidthRight, mRightInset, mExcludeRegion));
- if (DEBUG_MISSING_GESTURE) {
- Log.d(DEBUG_MISSING_GESTURE_TAG, mGestureLog.peekLast());
- }
} else if (mAllowGesture || mLogGesture) {
if (!mThresholdCrossed) {
mEndPoint.x = (int) ev.getX();
@@ -907,7 +901,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
pw.println(" mUseMLModel=" + mUseMLModel);
pw.println(" mDisabledForQuickstep=" + mDisabledForQuickstep);
pw.println(" mStartingQuickstepRotation=" + mStartingQuickstepRotation);
- pw.println(" mInRejectedExclusion" + mInRejectedExclusion);
+ pw.println(" mInRejectedExclusion=" + mInRejectedExclusion);
pw.println(" mExcludeRegion=" + mExcludeRegion);
pw.println(" mUnrestrictedExcludeRegion=" + mUnrestrictedExcludeRegion);
pw.println(" mIsInPipMode=" + mIsInPipMode);
@@ -922,7 +916,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
pw.println(" mTouchSlop=" + mTouchSlop);
pw.println(" mBottomGestureHeight=" + mBottomGestureHeight);
pw.println(" mPredictionLog=" + String.join("\n", mPredictionLog));
- pw.println(" mGestureLog=" + String.join("\n", mGestureLog));
+ pw.println(" mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
+ pw.println(" mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
pw.println(" mEdgeBackPlugin=" + mEdgeBackPlugin);
}
@@ -945,4 +940,23 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
}
proto.edgeBackGestureHandler.allowGesture = mAllowGesture;
}
+
+
+ private static class LogArray extends ArrayDeque<String> {
+ private final int mLength;
+
+ LogArray(int length) {
+ mLength = length;
+ }
+
+ void log(String message) {
+ if (size() >= mLength) {
+ removeFirst();
+ }
+ addLast(message);
+ if (DEBUG_MISSING_GESTURE) {
+ Log.d(DEBUG_MISSING_GESTURE_TAG, message);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/NotificationHelper.java b/packages/SystemUI/src/com/android/systemui/people/NotificationHelper.java
index b5ac90828fce..d863dcce4fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/people/NotificationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/NotificationHelper.java
@@ -240,9 +240,16 @@ public class NotificationHelper {
/** Returns whether {@code entry} is suppressed from shade, meaning we should not show it. */
public static boolean shouldFilterOut(
Optional<Bubbles> bubblesOptional, NotificationEntry entry) {
- return bubblesOptional.isPresent()
- && bubblesOptional.get().isBubbleNotificationSuppressedFromShade(
- entry.getKey(), entry.getSbn().getGroupKey());
+ boolean isSuppressed = false;
+ //TODO(b/190822282): Investigate what is causing the NullPointerException
+ try {
+ isSuppressed = bubblesOptional.isPresent()
+ && bubblesOptional.get().isBubbleNotificationSuppressedFromShade(
+ entry.getKey(), entry.getSbn().getGroupKey());
+ } catch (Exception e) {
+ Log.e(TAG, "Exception checking if notification is suppressed: " + e);
+ }
+ return isSuppressed;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index 6a025a750baa..d9e2648750a4 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -91,8 +91,8 @@ public class PeopleSpaceActivity extends Activity {
// than the activity's background.
LinearLayout item = findViewById(R.id.item);
GradientDrawable shape = (GradientDrawable) item.getBackground();
- final TypedArray ta = mContext.obtainStyledAttributes(
- new int[]{android.R.attr.colorBackgroundFloating});
+ final TypedArray ta = mContext.getTheme().obtainStyledAttributes(
+ new int[]{com.android.internal.R.attr.colorSurface});
shape.setColor(ta.getColor(0, Color.WHITE));
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
index c416b5edb264..b031637e4016 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
@@ -35,9 +35,11 @@ import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.people.PeopleSpaceUtils;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubble;
import java.util.Optional;
@@ -53,14 +55,35 @@ public class LaunchConversationActivity extends Activity {
private final UserManager mUserManager;
private boolean mIsForTesting;
private IStatusBarService mIStatusBarService;
+ private CommandQueue mCommandQueue;
+ private Bubble mBubble;
+ private NotificationEntry mEntryToBubble;
@Inject
public LaunchConversationActivity(NotificationEntryManager notificationEntryManager,
- Optional<BubblesManager> bubblesManagerOptional, UserManager userManager) {
+ Optional<BubblesManager> bubblesManagerOptional, UserManager userManager,
+ CommandQueue commandQueue) {
super();
mNotificationEntryManager = notificationEntryManager;
mBubblesManagerOptional = bubblesManagerOptional;
mUserManager = userManager;
+ mCommandQueue = commandQueue;
+ mCommandQueue.addCallback(new CommandQueue.Callbacks() {
+ // (b/190833924) Wait for the app transition to finish before showing the bubble,
+ // opening the bubble while the transition is happening can mess with the placement
+ // of the bubble's surface.
+ @Override
+ public void appTransitionFinished(int displayId) {
+ if (mBubblesManagerOptional.isPresent()) {
+ if (mBubble != null) {
+ mBubblesManagerOptional.get().expandStackAndSelectBubble(mBubble);
+ } else if (mEntryToBubble != null) {
+ mBubblesManagerOptional.get().expandStackAndSelectBubble(mEntryToBubble);
+ }
+ }
+ mCommandQueue.removeCallback(this);
+ }
+ });
}
@Override
@@ -95,14 +118,28 @@ public class LaunchConversationActivity extends Activity {
return;
}
- NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- notificationKey);
- if (entry != null && entry.canBubble() && mBubblesManagerOptional.isPresent()) {
- if (DEBUG) Log.d(TAG, "Open bubble for conversation");
- mBubblesManagerOptional.get().expandStackAndSelectBubble(entry);
- // Just opt-out and don't cancel the notification for bubbles.
- finish();
- return;
+ // We can potentially bubble without a notification, so rather than rely on
+ // notificationKey here (which could be null if there's no notification or if the
+ // bubble is suppressing the notification), so we'll use the shortcutId for lookups.
+ // This misses one specific case: a bubble that was never opened & still has a
+ // visible notification, but the bubble was dismissed & aged out of the overflow.
+ // So it wouldn't exist in the stack or overflow to be looked up BUT the notif entry
+ // would still exist & be bubbleable. So if we don't get a bubble from the
+ // shortcutId, fallback to notificationKey if it exists.
+ if (mBubblesManagerOptional.isPresent()) {
+ mBubble = mBubblesManagerOptional.get().getBubbleWithShortcutId(tileId);
+ NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
+ notificationKey);
+ if (mBubble != null || (entry != null && entry.canBubble())) {
+ mEntryToBubble = entry;
+ if (DEBUG) {
+ Log.d(TAG,
+ "Opening bubble: " + mBubble + ", entry: " + mEntryToBubble);
+ }
+ // Just opt-out and don't cancel the notification for bubbles.
+ finish();
+ return;
+ }
}
if (mIStatusBarService == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index f6d93895ce05..929aedae6706 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -28,6 +28,7 @@ import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
@@ -73,7 +74,7 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
private final PageIndicator mPageIndicator;
private final View mPowerMenuLite;
private final boolean mShowPMLiteButton;
- private GlobalActionsDialogLite mGlobalActionsDialog;
+ private final GlobalActionsDialogLite mGlobalActionsDialog;
private final UiEventLogger mUiEventLogger;
private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
@@ -272,7 +273,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
private void startSettingsActivity() {
ActivityLaunchAnimator.Controller animationController =
mSettingsButtonContainer != null ? ActivityLaunchAnimator.Controller.fromView(
- mSettingsButtonContainer) : null;
+ mSettingsButtonContainer,
+ InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON) : null;
mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
true /* dismissShade */, animationController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index e1a66b2c07ee..7b8a6a0a8d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -539,8 +539,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private void pinToBottom(float absoluteBottomPosition, MediaHost mediaHost, boolean expanded) {
View hostView = mediaHost.getHostView();
- // on keyguard we cross-fade to expanded, so no need to pin it.
- if (mLastQSExpansion > 0 && !isKeyguardState()) {
+ // On keyguard we cross-fade to expanded, so no need to pin it.
+ // If the collapsed qs isn't visible, we also just keep it at the laid out position.
+ if (mLastQSExpansion > 0 && !isKeyguardState() && mQqsMediaHost.getVisible()) {
float targetPosition = absoluteBottomPosition - getTotalBottomMargin(hostView)
- hostView.getHeight();
float currentPosition = mediaHost.getCurrentBounds().top
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 525bad8a0e25..6ddf2a75f491 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -45,7 +45,9 @@ import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.external.CustomTile;
+import com.android.systemui.qs.external.CustomTileStatePersister;
import com.android.systemui.qs.external.TileLifecycleManager;
+import com.android.systemui.qs.external.TileServiceKey;
import com.android.systemui.qs.external.TileServices;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.settings.UserTracker;
@@ -93,6 +95,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
private final QSLogger mQSLogger;
private final UiEventLogger mUiEventLogger;
private final InstanceIdSequence mInstanceIdSequence;
+ private final CustomTileStatePersister mCustomTileStatePersister;
private final List<Callback> mCallbacks = new ArrayList<>();
private AutoTileManager mAutoTiles;
@@ -119,7 +122,8 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
QSLogger qsLogger,
UiEventLogger uiEventLogger,
UserTracker userTracker,
- SecureSettings secureSettings) {
+ SecureSettings secureSettings,
+ CustomTileStatePersister customTileStatePersister) {
mIconController = iconController;
mContext = context;
mUserContext = context;
@@ -139,6 +143,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
mDumpManager.registerDumpable(TAG, this);
mUserTracker = userTracker;
mSecureSettings = secureSettings;
+ mCustomTileStatePersister = customTileStatePersister;
mainHandler.post(() -> {
// This is technically a hack to avoid circular dependency of
@@ -418,6 +423,11 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
changeTiles(mTileSpecs, newSpecs);
}
+ /**
+ * Change the tiles triggered by the user editing.
+ * <p>
+ * This is not called on device start, or on user change.
+ */
public void changeTiles(List<String> previousTiles, List<String> newTiles) {
final List<String> copy = new ArrayList<>(previousTiles);
final int NP = copy.size();
@@ -433,6 +443,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
mBroadcastDispatcher);
lifecycleManager.onStopListening();
lifecycleManager.onTileRemoved();
+ mCustomTileStatePersister.removeState(new TileServiceKey(component, mCurrentUser));
TileLifecycleManager.setTileAdded(mContext, component, false);
lifecycleManager.flushMessagesAndUnbind();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 08a68bc8a9a7..997b96626747 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -266,10 +266,9 @@ public class QuickStatusBarHeader extends FrameLayout {
private void updateAlphaAnimator() {
TouchAnimator.Builder builder = new TouchAnimator.Builder()
- // The following two views have to be hidden manually, so as not to hide the
- // Privacy chip in QQS
- .addFloat(mDateView, "alpha", 0, 1)
.addFloat(mSecurityHeaderView, "alpha", 0, 1)
+ // These views appear on expanding down
+ .addFloat(mClockView, "alpha", 0, 1)
.addFloat(mQSCarriers, "alpha", 0, 1)
.setListener(new TouchAnimator.ListenerAdapter() {
@Override
@@ -400,12 +399,14 @@ public class QuickStatusBarHeader extends FrameLayout {
mClockIconsSeparatorLayoutParams.width = 0;
setSeparatorVisibility(false);
mShowClockIconsSeparator = false;
+ mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
} else {
datePrivacySeparatorLayoutParams.width = topCutout.width();
mDatePrivacySeparator.setVisibility(View.VISIBLE);
mClockIconsSeparatorLayoutParams.width = topCutout.width();
mShowClockIconsSeparator = true;
setSeparatorVisibility(mKeyguardExpansionFraction == 0f);
+ mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ON);
}
}
mDatePrivacySeparator.setLayoutParams(datePrivacySeparatorLayoutParams);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 5a60d2624a43..d017c74b4306 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -369,6 +369,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
holder.getTileAsCustomizeView().setShowAppLabel(position > mEditIndex && !info.isSystem);
// Don't show the side view for third party tiles, as we don't have the actual state.
holder.getTileAsCustomizeView().setShowSideView(position < mEditIndex || info.isSystem);
+ holder.mTileView.setSelected(true);
holder.mTileView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
holder.mTileView.setClickable(true);
holder.mTileView.setOnClickListener(null);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 10eea828bcb4..396eca5c1bee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -46,6 +46,7 @@ import android.widget.Switch;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -85,6 +86,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
private final IQSTileService mService;
private final TileServiceManager mServiceManager;
private final int mUser;
+ private final CustomTileStatePersister mCustomTileStatePersister;
private android.graphics.drawable.Icon mDefaultIcon;
private CharSequence mDefaultLabel;
@@ -94,6 +96,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
private boolean mIsTokenGranted;
private boolean mIsShowingDialog;
+ private final TileServiceKey mKey;
+
private CustomTile(
QSHost host,
Looper backgroundLooper,
@@ -104,7 +108,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
ActivityStarter activityStarter,
QSLogger qsLogger,
String action,
- Context userContext
+ Context userContext,
+ CustomTileStatePersister customTileStatePersister
) {
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
@@ -113,15 +118,29 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
mTile = new Tile();
mUserContext = userContext;
mUser = mUserContext.getUserId();
- updateDefaultTileAndIcon();
+ mKey = new TileServiceKey(mComponent, mUser);
+
mServiceManager = host.getTileServices().getTileWrapper(this);
+ mService = mServiceManager.getTileService();
+ mCustomTileStatePersister = customTileStatePersister;
+ }
+
+ @Override
+ protected void handleInitialize() {
+ updateDefaultTileAndIcon();
if (mServiceManager.isToggleableTile()) {
// Replace states with BooleanState
resetStates();
}
-
- mService = mServiceManager.getTileService();
mServiceManager.setTileChangeListener(this);
+ if (mServiceManager.isActiveTile()) {
+ Tile t = mCustomTileStatePersister.readState(mKey);
+ if (t != null) {
+ applyTileState(t, /* overwriteNulls */ false);
+ mServiceManager.clearPendingBind();
+ refreshState();
+ }
+ }
}
@Override
@@ -191,7 +210,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
@Override
public void onTileChanged(ComponentName tile) {
- updateDefaultTileAndIcon();
+ mHandler.post(this::updateDefaultTileAndIcon);
}
@Override
@@ -213,16 +232,44 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
}
public Tile getQsTile() {
+ // TODO(b/191145007) Move to background thread safely
updateDefaultTileAndIcon();
return mTile;
}
- public void updateState(Tile tile) {
- mTile.setIcon(tile.getIcon());
- mTile.setLabel(tile.getLabel());
- mTile.setSubtitle(tile.getSubtitle());
- mTile.setContentDescription(tile.getContentDescription());
- mTile.setStateDescription(tile.getStateDescription());
+ /**
+ * Update state of {@link this#mTile} from a remote {@link TileService}.
+ * @param tile tile populated with state to apply
+ */
+ public void updateTileState(Tile tile) {
+ // This comes from a binder call IQSService.updateQsTile
+ mHandler.post(() -> handleUpdateTileState(tile));
+ }
+
+ private void handleUpdateTileState(Tile tile) {
+ applyTileState(tile, /* overwriteNulls */ true);
+ if (mServiceManager.isActiveTile()) {
+ mCustomTileStatePersister.persistState(mKey, tile);
+ }
+ }
+
+ @WorkerThread
+ private void applyTileState(Tile tile, boolean overwriteNulls) {
+ if (tile.getIcon() != null || overwriteNulls) {
+ mTile.setIcon(tile.getIcon());
+ }
+ if (tile.getLabel() != null || overwriteNulls) {
+ mTile.setLabel(tile.getLabel());
+ }
+ if (tile.getSubtitle() != null || overwriteNulls) {
+ mTile.setSubtitle(tile.getSubtitle());
+ }
+ if (tile.getContentDescription() != null || overwriteNulls) {
+ mTile.setContentDescription(tile.getContentDescription());
+ }
+ if (tile.getStateDescription() != null || overwriteNulls) {
+ mTile.setStateDescription(tile.getStateDescription());
+ }
mTile.setState(tile.getState());
}
@@ -459,6 +506,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
final StatusBarStateController mStatusBarStateController;
final ActivityStarter mActivityStarter;
final QSLogger mQSLogger;
+ final CustomTileStatePersister mCustomTileStatePersister;
Context mUserContext;
String mSpec = "";
@@ -472,7 +520,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
- QSLogger qsLogger
+ QSLogger qsLogger,
+ CustomTileStatePersister customTileStatePersister
) {
mQSHostLazy = hostLazy;
mBackgroundLooper = backgroundLooper;
@@ -482,6 +531,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
mStatusBarStateController = statusBarStateController;
mActivityStarter = activityStarter;
mQSLogger = qsLogger;
+ mCustomTileStatePersister = customTileStatePersister;
}
Builder setSpec(@NonNull String spec) {
@@ -509,7 +559,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
mActivityStarter,
mQSLogger,
action,
- mUserContext
+ mUserContext,
+ mCustomTileStatePersister
);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
new file mode 100644
index 000000000000..021e632810f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.external
+
+import android.content.ComponentName
+import android.content.Context
+import android.service.quicksettings.Tile
+import android.util.Log
+import com.android.internal.annotations.VisibleForTesting
+import org.json.JSONException
+import org.json.JSONObject
+import javax.inject.Inject
+
+data class TileServiceKey(val componentName: ComponentName, val user: Int) {
+ private val string = "${componentName.flattenToString()}:$user"
+ override fun toString() = string
+}
+private const val STATE = "state"
+private const val LABEL = "label"
+private const val SUBTITLE = "subtitle"
+private const val CONTENT_DESCRIPTION = "content_description"
+private const val STATE_DESCRIPTION = "state_description"
+
+/**
+ * Persists and retrieves state for [CustomTile].
+ *
+ * This class will persists to a fixed [SharedPreference] file a state for a pair of [ComponentName]
+ * and user id ([TileServiceKey]).
+ *
+ * It persists the state from a [Tile] necessary to present the view in the same state when
+ * retrieved, with the exception of the icon.
+ */
+class CustomTileStatePersister @Inject constructor(context: Context) {
+ companion object {
+ private const val FILE_NAME = "custom_tiles_state"
+ }
+
+ private val sharedPreferences = context.getSharedPreferences(FILE_NAME, 0)
+
+ /**
+ * Read the state from [SharedPreferences].
+ *
+ * Returns `null` if the tile has no saved state.
+ *
+ * Any fields that have not been saved will be set to `null`
+ */
+ fun readState(key: TileServiceKey): Tile? {
+ val state = sharedPreferences.getString(key.toString(), null) ?: return null
+ return try {
+ readTileFromString(state)
+ } catch (e: JSONException) {
+ Log.e("TileServicePersistence", "Bad saved state: $state", e)
+ null
+ }
+ }
+
+ /**
+ * Persists the state into [SharedPreferences].
+ *
+ * The implementation does not store fields that are `null` or icons.
+ */
+ fun persistState(key: TileServiceKey, tile: Tile) {
+ val state = writeToString(tile)
+
+ sharedPreferences.edit().putString(key.toString(), state).apply()
+ }
+
+ /**
+ * Removes the state for a given tile, user pair.
+ *
+ * Used when the tile is removed by the user.
+ */
+ fun removeState(key: TileServiceKey) {
+ sharedPreferences.edit().remove(key.toString()).apply()
+ }
+}
+
+@VisibleForTesting
+internal fun readTileFromString(stateString: String): Tile {
+ val json = JSONObject(stateString)
+ return Tile().apply {
+ state = json.getInt(STATE)
+ label = json.getStringOrNull(LABEL)
+ subtitle = json.getStringOrNull(SUBTITLE)
+ contentDescription = json.getStringOrNull(CONTENT_DESCRIPTION)
+ stateDescription = json.getStringOrNull(STATE_DESCRIPTION)
+ }
+}
+
+// Properties with null values will not be saved to the Json string in any way. This makes sure
+// to properly retrieve a null in that case.
+private fun JSONObject.getStringOrNull(name: String): String? {
+ return if (has(name)) getString(name) else null
+}
+
+@VisibleForTesting
+internal fun writeToString(tile: Tile): String {
+ // Not storing the icon
+ return with(tile) {
+ JSONObject()
+ .put(STATE, state)
+ .put(LABEL, label)
+ .put(SUBTITLE, subtitle)
+ .put(CONTENT_DESCRIPTION, contentDescription)
+ .put(STATE_DESCRIPTION, stateDescription)
+ .toString()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 35cf2a12745e..a7cd11314d7e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -204,7 +204,7 @@ public class TileServices extends IQSService.Stub {
tileServiceManager.clearPendingBind();
tileServiceManager.setLastUpdate(System.currentTimeMillis());
}
- customTile.updateState(tile);
+ customTile.updateTileState(tile);
customTile.refreshState();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 8f7c493417ec..842fd6c62d06 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -160,7 +160,8 @@ public class QSFactoryImpl implements QSFactory {
public QSTile createTile(String tileSpec) {
QSTileImpl tile = createTileInternal(tileSpec);
if (tile != null) {
- tile.handleStale(); // Tile was just created, must be stale.
+ tile.initialize();
+ tile.postStale(); // Tile was just created, must be stale.
}
return tile;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index a938821a343f..4616be8f7937 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -50,6 +50,7 @@ import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
@@ -158,6 +159,15 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
*/
abstract public int getMetricsCategory();
+ /**
+ * Performs initialization of the tile
+ *
+ * Use this to perform initialization of the tile. Empty by default.
+ */
+ protected void handleInitialize() {
+
+ }
+
protected QSTileImpl(
QSHost host,
Looper backgroundLooper,
@@ -346,6 +356,15 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
mHandler.sendEmptyMessage(H.DESTROY);
}
+ /**
+ * Schedules initialization of the tile.
+ *
+ * Should be called upon creation of the tile, before performing other operations
+ */
+ public void initialize() {
+ mHandler.sendEmptyMessage(H.INITIALIZE);
+ }
+
public TState getState() {
return mState;
}
@@ -370,6 +389,13 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
}
/**
+ * Posts a stale message to the background thread.
+ */
+ public void postStale() {
+ mHandler.sendEmptyMessage(H.STALE);
+ }
+
+ /**
* Handles secondary click on the tile.
*
* Defaults to {@link QSTileImpl#handleClick}
@@ -389,7 +415,8 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
*/
protected void handleLongClick(@Nullable View view) {
ActivityLaunchAnimator.Controller animationController =
- view != null ? ActivityLaunchAnimator.Controller.fromView(view) : null;
+ view != null ? ActivityLaunchAnimator.Controller.fromView(view,
+ InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE) : null;
mActivityStarter.postStartActivityDismissingKeyguard(getLongClickIntent(), 0,
animationController);
}
@@ -580,6 +607,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
private static final int SET_LISTENING = 13;
@VisibleForTesting
protected static final int STALE = 14;
+ private static final int INITIALIZE = 15;
@VisibleForTesting
protected H(Looper looper) {
@@ -638,6 +666,9 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
} else if (msg.what == STALE) {
name = "handleStale";
handleStale();
+ } else if (msg.what == INITIALIZE) {
+ name = "initialize";
+ handleInitialize();
} else {
throw new IllegalArgumentException("Unknown msg: " + msg.what);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
index 69d49d44f822..73d13700d61b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
@@ -11,6 +11,7 @@ import android.text.TextUtils
import android.text.format.DateFormat
import android.view.View
import androidx.annotation.VisibleForTesting
+import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.MetricsLogger
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
@@ -70,7 +71,10 @@ class AlarmTile @Inject constructor(
}
override fun handleClick(view: View?) {
- val animationController = view?.let { ActivityLaunchAnimator.Controller.fromView(it) }
+ val animationController = view?.let {
+ ActivityLaunchAnimator.Controller.fromView(
+ it, InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE)
+ }
val pendingIntent = lastAlarmInfo?.showIntent
if (pendingIntent != null) {
mActivityStarter.postStartActivityDismissingKeyguard(pendingIntent, animationController)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index 6d3190ffa725..f66b7226fbae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -22,6 +22,7 @@ import android.os.Handler
import android.os.Looper
import android.service.quicksettings.Tile
import android.view.View
+import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.MetricsLogger
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
@@ -106,7 +107,8 @@ class DeviceControlsTile @Inject constructor(
putExtra(ControlsUiController.EXTRA_ANIMATE, true)
}
val animationController = view?.let {
- ActivityLaunchAnimator.Controller.fromView(it)
+ ActivityLaunchAnimator.Controller.fromView(
+ it, InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE)
}
mUiHandler.post {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 0e4434baa0e8..98cd88af232f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -37,6 +37,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -120,7 +121,8 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
@Override
protected void handleClick(@Nullable View view) {
ActivityLaunchAnimator.Controller animationController =
- view == null ? null : ActivityLaunchAnimator.Controller.fromView(view);
+ view == null ? null : ActivityLaunchAnimator.Controller.fromView(view,
+ InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE);
mUiHandler.post(() -> {
if (mSelectedCard != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 32a6c6c20504..24b9208d4ed1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -103,6 +103,8 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
state.state = (isRecording || isStarting) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.label = mContext.getString(R.string.quick_settings_screen_record_label);
state.icon = ResourceIcon.get(R.drawable.ic_screenrecord);
+ // Show expand icon when clicking will open a dialog
+ state.forceExpandIcon = state.state == Tile.STATE_INACTIVE;
if (isRecording) {
state.secondaryLabel = mContext.getString(R.string.quick_settings_screen_record_stop);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
index 17e94c4b3f69..f14044682b61 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
@@ -16,6 +16,8 @@
package com.android.systemui.screenshot;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_EDIT;
import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_SHARE;
import static com.android.systemui.screenshot.ScreenshotController.EXTRA_ACTION_INTENT;
@@ -30,6 +32,8 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
+import android.view.RemoteAnimationAdapter;
+import android.view.WindowManagerGlobal;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -69,6 +73,16 @@ public class ActionProxyReceiver extends BroadcastReceiver {
intent.getBooleanExtra(EXTRA_DISALLOW_ENTER_PIP, false));
try {
actionIntent.send(context, 0, null, null, null, null, opts.toBundle());
+ if (intent.getBooleanExtra(ScreenshotController.EXTRA_OVERRIDE_TRANSITION, false)) {
+ RemoteAnimationAdapter runner = new RemoteAnimationAdapter(
+ ScreenshotController.SCREENSHOT_REMOTE_RUNNER, 0, 0);
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY);
+ } catch (Exception e) {
+ Log.e(TAG, "Error overriding screenshot app transition", e);
+ }
+ }
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Pending intent canceled", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 9e11451afa06..0a60f6da159e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -62,6 +62,7 @@ public class CropView extends View {
private final float mCropTouchMargin;
private final Paint mShadePaint;
private final Paint mHandlePaint;
+ private final Paint mContainerBackgroundPaint;
// Crop rect with each element represented as [0,1] along its proper axis.
private RectF mCrop = new RectF(0, 0, 1, 1);
@@ -79,6 +80,9 @@ public class CropView extends View {
// The allowable values for the current boundary being dragged
private Range<Float> mMotionRange;
+ // Value [0,1] indicating progress in animateEntrance()
+ private float mEntranceInterpolation = 1f;
+
private CropInteractionListener mCropInteractionListener;
private final ExploreByTouchHelper mExploreByTouchHelper;
@@ -92,6 +96,9 @@ public class CropView extends View {
attrs, R.styleable.CropView, 0, 0);
mShadePaint = new Paint();
mShadePaint.setColor(t.getColor(R.styleable.CropView_scrimColor, Color.TRANSPARENT));
+ mContainerBackgroundPaint = new Paint();
+ mContainerBackgroundPaint.setColor(t.getColor(R.styleable.CropView_containerBackgroundColor,
+ Color.TRANSPARENT));
mHandlePaint = new Paint();
mHandlePaint.setColor(t.getColor(R.styleable.CropView_handleColor, Color.BLACK));
mHandlePaint.setStrokeCap(Paint.Cap.ROUND);
@@ -125,10 +132,22 @@ public class CropView extends View {
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
- drawShade(canvas, 0, 0, 1, mCrop.top);
- drawShade(canvas, 0, mCrop.bottom, 1, 1);
+ // Top and bottom borders reflect the boundary between the (scrimmed) image and the
+ // opaque container background. This is only meaningful during an entrance transition.
+ float topBorder = MathUtils.lerp(mCrop.top, 0, mEntranceInterpolation);
+ float bottomBorder = MathUtils.lerp(mCrop.bottom, 1, mEntranceInterpolation);
+ drawShade(canvas, 0, topBorder, 1, mCrop.top);
+ drawShade(canvas, 0, mCrop.bottom, 1, bottomBorder);
drawShade(canvas, 0, mCrop.top, mCrop.left, mCrop.bottom);
drawShade(canvas, mCrop.right, mCrop.top, 1, mCrop.bottom);
+
+ // Entrance transition expects the crop bounds to be full width, so we only draw container
+ // background on the top and bottom.
+ drawContainerBackground(canvas, 0, 0, 1, topBorder);
+ drawContainerBackground(canvas, 0, bottomBorder, 1, 1);
+
+ mHandlePaint.setAlpha((int) (mEntranceInterpolation * 255));
+
drawHorizontalHandle(canvas, mCrop.top, /* draw the handle tab up */ true);
drawHorizontalHandle(canvas, mCrop.bottom, /* draw the handle tab down */ false);
drawVerticalHandle(canvas, mCrop.left, /* left */ true);
@@ -282,6 +301,22 @@ public class CropView extends View {
}
/**
+ * Fade in crop bounds, animate reveal of cropped-out area from current crop bounds.
+ */
+ public void animateEntrance() {
+ mEntranceInterpolation = 0;
+ ValueAnimator animator = new ValueAnimator();
+ animator.addUpdateListener(animation -> {
+ mEntranceInterpolation = animation.getAnimatedFraction();
+ invalidate();
+ });
+ animator.setFloatValues(0f, 1f);
+ animator.setDuration(750);
+ animator.setInterpolator(new FastOutSlowInInterpolator());
+ animator.start();
+ }
+
+ /**
* Set additional top and bottom padding for the image being cropped (used when the
* corresponding ImageView doesn't take the full height).
*/
@@ -369,6 +404,13 @@ public class CropView extends View {
fractionToVerticalPixels(bottom), mShadePaint);
}
+ private void drawContainerBackground(Canvas canvas, float left, float top, float right,
+ float bottom) {
+ canvas.drawRect(fractionToHorizontalPixels(left), fractionToVerticalPixels(top),
+ fractionToHorizontalPixels(right),
+ fractionToVerticalPixels(bottom), mContainerBackgroundPaint);
+ }
+
private void drawHorizontalHandle(Canvas canvas, float frac, boolean handleTabUp) {
int y = fractionToVerticalPixels(frac);
canvas.drawLine(fractionToHorizontalPixels(mCrop.left), y,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index d5b4032b1c0f..25ec1d74008e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -192,7 +192,6 @@ public class LongScreenshotActivity extends Activity {
mLongScreenshot = longScreenshot;
Drawable drawable = mLongScreenshot.getDrawable();
mPreview.setImageDrawable(drawable);
- mCropView.setVisibility(View.VISIBLE);
mMagnifierView.setDrawable(mLongScreenshot.getDrawable(),
mLongScreenshot.getWidth(), mLongScreenshot.getHeight());
// Original boundaries go from the image tile set's y=0 to y=pageSize, so
@@ -219,10 +218,12 @@ public class LongScreenshotActivity extends Activity {
public void onTransitionEnd(Transition transition) {
super.onTransitionEnd(transition);
mPreview.animate().alpha(1f);
- mCropView.animateBoundaryTo(
+ mCropView.setBoundaryPosition(
CropView.CropBoundary.TOP, topFraction);
- mCropView.animateBoundaryTo(
+ mCropView.setBoundaryPosition(
CropView.CropBoundary.BOTTOM, bottomFraction);
+ mCropView.animateEntrance();
+ mCropView.setVisibility(View.VISIBLE);
setButtonsEnabled(true);
mEnterTransitionView.setVisibility(View.GONE);
}
@@ -250,6 +251,7 @@ public class LongScreenshotActivity extends Activity {
Log.d(TAG, "onCachedImageLoaded(imageResult=" + imageResult + ")");
BitmapDrawable drawable = new BitmapDrawable(getResources(), imageResult.bitmap);
mPreview.setImageDrawable(drawable);
+ mPreview.setAlpha(1f);
mMagnifierView.setDrawable(drawable, imageResult.bitmap.getWidth(),
imageResult.bitmap.getHeight());
mCropView.setVisibility(View.VISIBLE);
@@ -476,19 +478,21 @@ public class LongScreenshotActivity extends Activity {
params.height = boundaries.height();
mTransitionView.setLayoutParams(params);
- ConstraintLayout.LayoutParams enterTransitionParams =
- (ConstraintLayout.LayoutParams) mEnterTransitionView.getLayoutParams();
- float topFraction = Math.max(0,
- -mLongScreenshot.getTop() / (float) mLongScreenshot.getHeight());
- enterTransitionParams.width = (int) (scale * drawable.getIntrinsicWidth());
- enterTransitionParams.height = (int) (scale * mLongScreenshot.getPageHeight());
- mEnterTransitionView.setLayoutParams(enterTransitionParams);
-
- Matrix matrix = new Matrix();
- matrix.setScale(scale, scale);
- matrix.postTranslate(0, -scale * drawable.getIntrinsicHeight() * topFraction);
- mEnterTransitionView.setImageMatrix(matrix);
- mEnterTransitionView.setTranslationY(
- topFraction * previewHeight + mPreview.getPaddingTop() + extraPadding);
+ if (mLongScreenshot != null) {
+ ConstraintLayout.LayoutParams enterTransitionParams =
+ (ConstraintLayout.LayoutParams) mEnterTransitionView.getLayoutParams();
+ float topFraction = Math.max(0,
+ -mLongScreenshot.getTop() / (float) mLongScreenshot.getHeight());
+ enterTransitionParams.width = (int) (scale * drawable.getIntrinsicWidth());
+ enterTransitionParams.height = (int) (scale * mLongScreenshot.getPageHeight());
+ mEnterTransitionView.setLayoutParams(enterTransitionParams);
+
+ Matrix matrix = new Matrix();
+ matrix.setScale(scale, scale);
+ matrix.postTranslate(0, -scale * drawable.getIntrinsicHeight() * topFraction);
+ mEnterTransitionView.setImageMatrix(matrix);
+ mEnterTransitionView.setTranslationY(
+ topFraction * previewHeight + mPreview.getPaddingTop() + extraPadding);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index b5e51c68b76a..e9dea65c2078 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -319,6 +319,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
.putExtra(ScreenshotController.EXTRA_ID, mScreenshotId)
.putExtra(ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED,
mSmartActionsEnabled)
+ .putExtra(ScreenshotController.EXTRA_OVERRIDE_TRANSITION, true)
.setAction(Intent.ACTION_EDIT)
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index b1e589f274a4..5efa1b2992b2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -53,15 +53,18 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
import android.view.DisplayAddress;
+import android.view.IRemoteAnimationFinishedCallback;
+import android.view.IRemoteAnimationRunner;
import android.view.KeyEvent;
import android.view.LayoutInflater;
-import android.view.MotionEvent;
+import android.view.RemoteAnimationTarget;
import android.view.ScrollCaptureResponse;
import android.view.SurfaceControl;
import android.view.View;
@@ -107,6 +110,31 @@ public class ScreenshotController {
private ListenableFuture<ScrollCaptureResponse> mLastScrollCaptureRequest;
/**
+ * This is effectively a no-op, but we need something non-null to pass in, in order to
+ * successfully override the pending activity entrance animation.
+ */
+ static final IRemoteAnimationRunner.Stub SCREENSHOT_REMOTE_RUNNER =
+ new IRemoteAnimationRunner.Stub() {
+ @Override
+ public void onAnimationStart(
+ @WindowManager.TransitionOldType int transit,
+ RemoteAnimationTarget[] apps,
+ RemoteAnimationTarget[] wallpapers,
+ RemoteAnimationTarget[] nonApps,
+ final IRemoteAnimationFinishedCallback finishedCallback) {
+ try {
+ finishedCallback.onAnimationFinished();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error finishing screenshot remote animation", e);
+ }
+ }
+
+ @Override
+ public void onAnimationCancelled() {
+ }
+ };
+
+ /**
* POD used in the AsyncTask which saves an image in the background.
*/
static class SaveImageInBackgroundData {
@@ -183,6 +211,7 @@ public class ScreenshotController {
static final String ACTION_TYPE_SHARE = "Share";
static final String ACTION_TYPE_EDIT = "Edit";
static final String EXTRA_SMART_ACTIONS_ENABLED = "android:smart_actions_enabled";
+ static final String EXTRA_OVERRIDE_TRANSITION = "android:screenshot_override_transition";
static final String EXTRA_ACTION_INTENT = "android:screenshot_action_intent";
static final String SCREENSHOT_URI_ID = "android:screenshot_uri_id";
@@ -415,18 +444,12 @@ public class ScreenshotController {
public void onDismiss() {
finishDismiss();
}
- });
- // TODO(159460485): Remove this when focus is handled properly in the system
- mScreenshotView.setOnTouchListener((v, event) -> {
- if (event.getActionMasked() == MotionEvent.ACTION_OUTSIDE) {
- if (DEBUG_INPUT) {
- Log.d(TAG, "onTouch: ACTION_OUTSIDE");
- }
- // Once the user touches outside, stop listening for input
+ @Override
+ public void onTouchOutside() {
+ // TODO(159460485): Remove this when focus is handled properly in the system
setWindowFocusable(false);
}
- return false;
});
mScreenshotView.setOnKeyListener((v, keyCode, event) -> {
@@ -549,7 +572,7 @@ public class ScreenshotController {
mScreenshotHandler.postDelayed(this::requestScrollCapture, 150);
mScreenshotView.updateDisplayCutoutMargins(
mWindowManager.getCurrentWindowMetrics().getWindowInsets()
- .getDisplayCutout());
+ .getDisplayCutout());
}
});
});
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index c33c2dbc16a0..2a2217912b58 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -50,11 +50,14 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.LayerDrawable;
+import android.os.Looper;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
+import android.view.Choreographer;
+import android.view.Display;
import android.view.DisplayCutout;
import android.view.GestureDetector;
import android.view.LayoutInflater;
@@ -65,6 +68,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
@@ -79,6 +84,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition;
+import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
import java.util.ArrayList;
@@ -94,6 +100,9 @@ public class ScreenshotView extends FrameLayout implements
void onUserInteraction();
void onDismiss();
+
+ /** DOWN motion event was observed outside of the touchable areas of this view. */
+ void onTouchOutside();
}
private static final String TAG = logTag(ScreenshotView.class);
@@ -124,8 +133,6 @@ public class ScreenshotView extends FrameLayout implements
private final AccessibilityManager mAccessibilityManager;
private int mNavMode;
- private int mLeftInset;
- private int mRightInset;
private boolean mOrientationPortrait;
private boolean mDirectionLTR;
@@ -152,6 +159,7 @@ public class ScreenshotView extends FrameLayout implements
private boolean mPendingSharedTransition;
private GestureDetector mSwipeDetector;
private SwipeDismissHandler mSwipeDismissHandler;
+ private InputMonitorCompat mInputMonitor;
private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
private PendingInteraction mPendingInteraction;
@@ -209,6 +217,17 @@ public class ScreenshotView extends FrameLayout implements
});
mSwipeDetector.setIsLongpressEnabled(false);
mSwipeDismissHandler = new SwipeDismissHandler();
+ addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ startInputListening();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ stopInputListening();
+ }
+ });
}
public void hideScrollChip() {
@@ -238,6 +257,10 @@ public class ScreenshotView extends FrameLayout implements
@Override // ViewTreeObserver.OnComputeInternalInsetsListener
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ inoutInfo.touchableRegion.set(getTouchRegion());
+ }
+
+ private Region getTouchRegion() {
Region touchRegion = new Region();
final Rect tmpRect = new Rect();
@@ -251,15 +274,41 @@ public class ScreenshotView extends FrameLayout implements
touchRegion.op(tmpRect, Region.Op.UNION);
if (QuickStepContract.isGesturalMode(mNavMode)) {
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ final WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
+ final Insets gestureInsets = windowMetrics.getWindowInsets().getInsets(
+ WindowInsets.Type.systemGestures());
// Receive touches in gesture insets such that they don't cause TOUCH_OUTSIDE
- Rect inset = new Rect(0, 0, mLeftInset, mDisplayMetrics.heightPixels);
+ Rect inset = new Rect(0, 0, gestureInsets.left, mDisplayMetrics.heightPixels);
touchRegion.op(inset, Region.Op.UNION);
- inset.set(mDisplayMetrics.widthPixels - mRightInset, 0, mDisplayMetrics.widthPixels,
- mDisplayMetrics.heightPixels);
+ inset.set(mDisplayMetrics.widthPixels - gestureInsets.right, 0,
+ mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);
touchRegion.op(inset, Region.Op.UNION);
}
+ return touchRegion;
+ }
- inoutInfo.touchableRegion.set(touchRegion);
+ private void startInputListening() {
+ stopInputListening();
+ mInputMonitor = new InputMonitorCompat("Screenshot", Display.DEFAULT_DISPLAY);
+ mInputMonitor.getInputReceiver(Looper.getMainLooper(), Choreographer.getInstance(),
+ ev -> {
+ if (ev instanceof MotionEvent) {
+ MotionEvent event = (MotionEvent) ev;
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN
+ && !getTouchRegion().contains(
+ (int) event.getRawX(), (int) event.getRawY())) {
+ mCallbacks.onTouchOutside();
+ }
+ }
+ });
+ }
+
+ private void stopInputListening() {
+ if (mInputMonitor != null) {
+ mInputMonitor.dispose();
+ mInputMonitor = null;
+ }
}
@Override // ViewGroup
@@ -316,17 +365,6 @@ public class ScreenshotView extends FrameLayout implements
mDirectionLTR =
getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
- setOnApplyWindowInsetsListener((v, insets) -> {
- if (QuickStepContract.isGesturalMode(mNavMode)) {
- Insets gestureInsets = insets.getInsets(WindowInsets.Type.systemGestures());
- mLeftInset = gestureInsets.left;
- mRightInset = gestureInsets.right;
- } else {
- mLeftInset = mRightInset = 0;
- }
- return ScreenshotView.this.onApplyWindowInsets(insets);
- });
-
// Get focus so that the key events go to the layout.
setFocusableInTouchMode(true);
requestFocus();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 91a0e6fedef8..0bb702f6c9e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -112,6 +112,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private ViewGroup mIndicationArea;
private KeyguardIndicationTextView mTopIndicationView;
+ private KeyguardIndicationTextView mLockScreenIndicationView;
private final IBatteryStats mBatteryInfo;
private final SettableWakeLock mWakeLock;
private final DockManager mDockManager;
@@ -208,17 +209,21 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
mStatusBarStateController.addCallback(mStatusBarStateListener);
mKeyguardStateController.addCallback(this);
+
+ mStatusBarStateListener.onDozingChanged(mStatusBarStateController.isDozing());
}
public void setIndicationArea(ViewGroup indicationArea) {
mIndicationArea = indicationArea;
mTopIndicationView = indicationArea.findViewById(R.id.keyguard_indication_text);
+ mLockScreenIndicationView = indicationArea.findViewById(
+ R.id.keyguard_indication_text_bottom);
mInitialTextColorState = mTopIndicationView != null
? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
- indicationArea.findViewById(R.id.keyguard_indication_text_bottom),
- mExecutor,
- mStatusBarStateController);
+ mLockScreenIndicationView,
+ mExecutor,
+ mStatusBarStateController);
updateIndication(false /* animate */);
updateDisclosure();
if (mBroadcastReceiver == null) {
@@ -630,6 +635,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
// should be shown based on user or device state
// AoD
if (mDozing) {
+ mLockScreenIndicationView.setVisibility(View.GONE);
mTopIndicationView.setVisibility(VISIBLE);
// When dozing we ignore any text color and use white instead, because
// colors can be hard to read in low brightness.
@@ -659,6 +665,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
// LOCK SCREEN
mTopIndicationView.setVisibility(GONE);
+ mTopIndicationView.setText(null);
+ mLockScreenIndicationView.setVisibility(View.VISIBLE);
updateIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
}
@@ -914,7 +922,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
} else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
- showTransientIndication(errString);
+ showTransientIndication(errString, /* isError */ true,
+ /* hideOnScreenOff */ true);
// We want to keep this message around in case the screen was off
hideTransientIndicationDelayed(HIDE_DELAY_MS);
} else {
@@ -1032,9 +1041,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
if (mHideTransientMessageOnScreenOff && mDozing) {
hideTransientIndication();
- } else {
- updateIndication(false);
}
+ updateIndication(false);
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
index 6a5f001ac2ee..ec648ad519a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
@@ -93,10 +93,10 @@ class CircleReveal(
val endRadius: Float
) : LightRevealEffect {
override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) {
- val interpolatedAmount = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(amount)
- val fadeAmount =
- LightRevealEffect.getPercentPastThreshold(interpolatedAmount, 0.75f)
- val radius = startRadius + ((endRadius - startRadius) * interpolatedAmount)
+ // reveal amount updates already have an interpolator, so we intentionally use the
+ // non-interpolated amount
+ val fadeAmount = LightRevealEffect.getPercentPastThreshold(amount, 0.5f)
+ val radius = startRadius + ((endRadius - startRadius) * amount)
scrim.revealGradientEndColorAlpha = 1f - fadeAmount
scrim.setRevealGradientBounds(
centerX - radius /* left */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 085a076c5c55..baac2549055f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -259,11 +259,9 @@ public class NotificationShelf extends ActivatableNotificationView implements
final float inShelfAmount = updateShelfTransformation(i, child, scrollingFast,
expandingAnimated, isLastChild);
- final float stackEnd = mAmbientState.getStackY()
- + mAmbientState.getStackHeight();
// TODO(b/172289889) scale mPaddingBetweenElements with expansion amount
if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) {
- notificationClipEnd = stackEnd;
+ notificationClipEnd = shelfStart + getIntrinsicHeight();
} else {
notificationClipEnd = shelfStart - mPaddingBetweenElements;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 9f59023f1890..f8a1ff879e72 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -145,11 +145,11 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
}
@Override
- public boolean setState(int state) {
+ public boolean setState(int state, boolean force) {
if (state > MAX_STATE || state < MIN_STATE) {
throw new IllegalArgumentException("Invalid state " + state);
}
- if (state == mState) {
+ if (!force && state == mState) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index b6d6ed53b681..73f3d90bd4f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -59,7 +59,19 @@ public interface SysuiStatusBarStateController extends StatusBarStateController
* @param state see {@link StatusBarState} for valid options
* @return {@code true} if the state changed, else {@code false}
*/
- boolean setState(int state);
+ default boolean setState(int state) {
+ return setState(state, false /* force */);
+ }
+
+ /**
+ * Update the status bar state
+ * @param state see {@link StatusBarState} for valid options
+ * @param force whether to set the state even if it's the same as the current state. This will
+ * dispatch the state to all StatusBarStateListeners, ensuring that all listening
+ * components are reset to this state.
+ * @return {@code true} if the state was changed or set forcefully
+ */
+ boolean setState(int state, boolean force);
/**
* Update the dozing state from {@link StatusBar}'s perspective
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 8479b30c3a75..f30010cf4d1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -383,10 +383,18 @@ const val ANIMATING_OUT = 3
const val SHOWING_PERSISTENT_DOT = 4
private const val TAG = "SystemStatusAnimationScheduler"
-private const val DELAY: Long = 100
-private const val DISPLAY_LENGTH = 5000L
-private const val ENTRANCE_ANIM_LENGTH = 500L
-private const val CHIP_ANIM_LENGTH = 500L
+private const val DELAY = 0L
+
+/**
+ * The total time spent animation should be 1500ms. The entrance animation is how much time
+ * we give to the system to animate system elements out of the way. Total chip animation length
+ * will be equivalent to 2*chip_anim_length + display_length
+ */
+private const val ENTRANCE_ANIM_LENGTH = 250L
+private const val CHIP_ANIM_LENGTH = 250L
+// 1s + entrance time + chip anim_length
+private const val DISPLAY_LENGTH = 1500L
+
private const val MIN_UPTIME: Long = 5 * 1000
private const val DEBUG = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index aef01e9bd811..0fb1c54bb150 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -71,11 +71,11 @@ public final class NotificationClicker implements View.OnClickListener {
// Check if the notification is displaying the menu, if so slide notification back
if (isMenuVisible(row)) {
mLogger.logMenuVisible(entry);
- row.animateTranslateNotification(0);
+ row.animateResetTranslation();
return;
} else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
mLogger.logParentMenuVisible(entry);
- row.getNotificationParent().animateTranslateNotification(0);
+ row.getNotificationParent().animateResetTranslation();
return;
} else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
// We never want to open the app directly if the user clicks in between
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 760bee21b0d1..b0a7767accfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -264,7 +264,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
override fun onStateChanged(newState: Int) {
- if (unlockedScreenOffAnimationController.shouldPlayScreenOffAnimation()) {
+ if (dozeParameters.shouldControlUnlockedScreenOff()) {
if (unlockedScreenOffAnimationController.isScreenOffAnimationPlaying() &&
state == StatusBarState.KEYGUARD &&
newState == StatusBarState.SHADE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 413662447028..c24c2be3faa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -330,30 +330,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
}
- @Override
- public void setDistanceToTopRoundness(float distanceToTopRoundness) {
- super.setDistanceToTopRoundness(distanceToTopRoundness);
- mBackgroundNormal.setDistanceToTopRoundness(distanceToTopRoundness);
- }
-
- /** Sets whether this view is the last notification in a section. */
- @Override
- public void setLastInSection(boolean lastInSection) {
- if (lastInSection != mLastInSection) {
- super.setLastInSection(lastInSection);
- mBackgroundNormal.setLastInSection(lastInSection);
- }
- }
-
- /** Sets whether this view is the first notification in a section. */
- @Override
- public void setFirstInSection(boolean firstInSection) {
- if (firstInSection != mFirstInSection) {
- super.setFirstInSection(firstInSection);
- mBackgroundNormal.setFirstInSection(firstInSection);
- }
- }
-
/**
* Set an override tint color that is used for the background.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 6fd556763943..ba28dc59def4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -846,8 +846,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
updateClickAndFocus();
if (mNotificationParent != null) {
setOverrideTintColor(NO_COLOR, 0.0f);
- // Let's reset the distance to top roundness, as this isn't applied to group children
- setDistanceToTopRoundness(NO_ROUNDNESS);
mNotificationParent.updateBackgroundForGroupState();
}
updateBackgroundClipping();
@@ -876,7 +874,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override
protected boolean handleSlideBack() {
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
- animateTranslateNotification(0 /* targetLeft */);
+ animateResetTranslation();
return true;
}
return false;
@@ -1713,21 +1711,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
mChildrenContainer.onNotificationUpdated();
- if (mShouldTranslateContents) {
- mTranslateableViews.add(mChildrenContainer);
- }
+ mTranslateableViews.add(mChildrenContainer);
});
- if (mShouldTranslateContents) {
- // Add the views that we translate to reveal the menu
- mTranslateableViews = new ArrayList<>();
- for (int i = 0; i < getChildCount(); i++) {
- mTranslateableViews.add(getChildAt(i));
- }
- // Remove views that don't translate
- mTranslateableViews.remove(mChildrenContainerStub);
- mTranslateableViews.remove(mGutsStub);
+ // Add the views that we translate to reveal the menu
+ mTranslateableViews = new ArrayList<>();
+ for (int i = 0; i < getChildCount(); i++) {
+ mTranslateableViews.add(getChildAt(i));
}
+ // Remove views that don't translate
+ mTranslateableViews.remove(mChildrenContainerStub);
+ mTranslateableViews.remove(mGutsStub);
}
private void doLongClickCallback() {
@@ -1805,7 +1799,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mTranslateAnim.cancel();
}
- if (!mShouldTranslateContents) {
+ if (mDismissUsingRowTranslationX) {
setTranslationX(0);
} else if (mTranslateableViews != null) {
for (int i = 0; i < mTranslateableViews.size(); i++) {
@@ -1867,23 +1861,47 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mPrivateLayout.getActiveRemoteInputText();
}
- public void animateTranslateNotification(final float leftTarget) {
+ /**
+ * Reset the translation with an animation.
+ */
+ public void animateResetTranslation() {
if (mTranslateAnim != null) {
mTranslateAnim.cancel();
}
- mTranslateAnim = getTranslateViewAnimator(leftTarget, null /* updateListener */);
+ mTranslateAnim = getTranslateViewAnimator(0, null /* updateListener */);
if (mTranslateAnim != null) {
mTranslateAnim.start();
}
}
+ /**
+ * Set the dismiss behavior of the view.
+ * @param usingRowTranslationX {@code true} if the view should translate using regular
+ * translationX, otherwise the contents will be
+ * translated.
+ */
+ @Override
+ public void setDismissUsingRowTranslationX(boolean usingRowTranslationX) {
+ if (usingRowTranslationX != mDismissUsingRowTranslationX) {
+ // In case we were already transitioning, let's switch over!
+ float previousTranslation = getTranslation();
+ if (previousTranslation != 0) {
+ setTranslation(0);
+ }
+ super.setDismissUsingRowTranslationX(usingRowTranslationX);
+ if (previousTranslation != 0) {
+ setTranslation(previousTranslation);
+ }
+ }
+ }
+
@Override
public void setTranslation(float translationX) {
invalidate();
if (isBlockingHelperShowingAndTranslationFinished()) {
mGuts.setTranslationX(translationX);
return;
- } else if (!mShouldTranslateContents) {
+ } else if (mDismissUsingRowTranslationX) {
setTranslationX(translationX);
} else if (mTranslateableViews != null) {
// Translate the group of views
@@ -1907,7 +1925,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override
public float getTranslation() {
- if (!mShouldTranslateContents) {
+ if (mDismissUsingRowTranslationX) {
return getTranslationX();
}
@@ -2898,7 +2916,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
float y = event.getY();
NotificationViewWrapper wrapper = getVisibleNotificationViewWrapper();
NotificationHeaderView header = wrapper == null ? null : wrapper.getNotificationHeader();
- if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
+ // the extra translation only needs to be added, if we're translating the notification
+ // contents, otherwise the motionEvent is already at the right place due to the
+ // touch event system.
+ float translation = !mDismissUsingRowTranslationX ? getTranslation() : 0;
+ if (header != null && header.isInTouchRect(x - translation, y)) {
return true;
}
if ((!mIsSummaryWithChildren || shouldShowPublic())
@@ -3037,24 +3059,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
@Override
- public boolean topAmountNeedsClipping() {
- if (isGroupExpanded()) {
- return true;
- }
- if (isGroupExpansionChanging()) {
- return true;
- }
- if (getShowingLayout().shouldClipToRounding(true /* topRounded */,
- false /* bottomRounded */)) {
- return true;
- }
- if (mGuts != null && mGuts.getAlpha() != 0.0f) {
- return true;
- }
- return false;
- }
-
- @Override
protected boolean childNeedsClipping(View child) {
if (child instanceof NotificationContentView) {
NotificationContentView contentView = (NotificationContentView) child;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 5134c62dc182..d58fe3b3c4a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -71,21 +71,19 @@ public abstract class ExpandableOutlineView extends ExpandableView {
private int mBackgroundTop;
/**
- * {@code true} if the children views of the {@link ExpandableOutlineView} are translated when
+ * {@code false} if the children views of the {@link ExpandableOutlineView} are translated when
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
*/
- protected boolean mShouldTranslateContents;
- private boolean mTopAmountRounded;
- private float mDistanceToTopRoundness = -1;
+ protected boolean mDismissUsingRowTranslationX = true;
private float[] mTmpCornerRadii = new float[8];
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
- && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners
- && !mTopAmountRounded) {
- int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
+ && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners) {
+ // Only when translating just the contents, does the outline need to be shifted.
+ int translation = !mDismissUsingRowTranslationX ? (int) getTranslation() : 0;
int left = Math.max(translation, 0);
int top = mClipTopAmount + mBackgroundTop;
int right = getWidth() + Math.min(translation, 0);
@@ -110,7 +108,9 @@ public abstract class ExpandableOutlineView extends ExpandableView {
float topRoundness = mAlwaysRoundBothCorners
? mOutlineRadius : getCurrentBackgroundRadiusTop();
if (!mCustomOutline) {
- int translation = mShouldTranslateContents && !ignoreTranslation
+ // The outline just needs to be shifted if we're translating the contents. Otherwise
+ // it's already in the right place.
+ int translation = !mDismissUsingRowTranslationX && !ignoreTranslation
? (int) getTranslation() : 0;
int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
left = Math.max(translation, 0) - halfExtraWidth;
@@ -168,33 +168,15 @@ public abstract class ExpandableOutlineView extends ExpandableView {
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
canvas.save();
- Path intersectPath = null;
- if (mTopAmountRounded && topAmountNeedsClipping()) {
- int left = (int) (- mExtraWidthForClipping / 2.0f);
- int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
- int right = getWidth() + (int) (mExtraWidthForClipping + left);
- int bottom = (int) Math.max(mMinimumHeightForClipping,
- Math.max(getActualHeight() - mClipBottomAmount, top + mOutlineRadius));
- getRoundedRectPath(left, top, right, bottom, mOutlineRadius, 0.0f, mClipPath);
- intersectPath = mClipPath;
- }
- boolean clipped = false;
if (childNeedsClipping(child)) {
Path clipPath = getCustomClipPath(child);
if (clipPath == null) {
clipPath = getClipPath(false /* ignoreTranslation */);
}
if (clipPath != null) {
- if (intersectPath != null) {
- clipPath.op(intersectPath, Path.Op.INTERSECT);
- }
canvas.clipPath(clipPath);
- clipped = true;
}
}
- if (!clipped && intersectPath != null) {
- canvas.clipPath(intersectPath);
- }
boolean result = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return result;
@@ -212,32 +194,19 @@ public abstract class ExpandableOutlineView extends ExpandableView {
invalidate();
}
- @Override
- public void setDistanceToTopRoundness(float distanceToTopRoundness) {
- super.setDistanceToTopRoundness(distanceToTopRoundness);
- if (distanceToTopRoundness != mDistanceToTopRoundness) {
- mTopAmountRounded = distanceToTopRoundness >= 0;
- mDistanceToTopRoundness = distanceToTopRoundness;
- applyRoundness();
- }
- }
-
protected boolean childNeedsClipping(View child) {
return false;
}
- public boolean topAmountNeedsClipping() {
- return true;
- }
-
protected boolean isClippingNeeded() {
- return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
+ // When translating the contents instead of the overall view, we need to make sure we clip
+ // rounded to the contents.
+ boolean forTranslation = getTranslation() != 0 && !mDismissUsingRowTranslationX;
+ return mAlwaysRoundBothCorners || mCustomOutline || forTranslation;
}
private void initDimens() {
Resources res = getResources();
- mShouldTranslateContents =
- res.getBoolean(R.bool.config_translateNotificationContentsOnSwipe);
mOutlineRadius = res.getDimension(R.dimen.notification_shadow_radius);
mAlwaysRoundBothCorners = res.getBoolean(R.bool.config_clipNotificationsToOutline);
if (!mAlwaysRoundBothCorners) {
@@ -272,11 +241,6 @@ public abstract class ExpandableOutlineView extends ExpandableView {
}
public float getCurrentBackgroundRadiusTop() {
- // If this view is top amount notification view, it should always has round corners on top.
- // It will be applied with applyRoundness()
- if (mTopAmountRounded) {
- return mOutlineRadius;
- }
return getCurrentTopRoundness() * mOutlineRadius;
}
@@ -382,9 +346,25 @@ public abstract class ExpandableOutlineView extends ExpandableView {
}
}
+ /**
+ * Set the dismiss behavior of the view.
+ * @param usingRowTranslationX {@code true} if the view should translate using regular
+ * translationX, otherwise the contents will be
+ * translated.
+ */
+ public void setDismissUsingRowTranslationX(boolean usingRowTranslationX) {
+ mDismissUsingRowTranslationX = usingRowTranslationX;
+ }
+
@Override
public int getOutlineTranslation() {
- return mCustomOutline ? mOutlineRect.left : (int) getTranslation();
+ if (mCustomOutline) {
+ return mOutlineRect.left;
+ }
+ if (mDismissUsingRowTranslationX) {
+ return 0;
+ }
+ return (int) getTranslation();
}
public void updateOutline() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 763d197847c3..8b0764b1c313 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -46,7 +46,6 @@ import java.util.List;
public abstract class ExpandableView extends FrameLayout implements Dumpable {
private static final String TAG = "ExpandableView";
- public static final float NO_ROUNDNESS = -1;
protected OnHeightChangedListener mOnHeightChangedListener;
private int mActualHeight;
protected int mClipTopAmount;
@@ -192,14 +191,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
}
}
- /**
- * Set the distance to the top roundness, from where we should start clipping a value above
- * or equal to 0 is the effective distance, and if a value below 0 is received, there should
- * be no clipping.
- */
- public void setDistanceToTopRoundness(float distanceToTopRoundness) {
- }
-
public void setActualHeight(int actualHeight) {
setActualHeight(actualHeight, true /* notifyListeners */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 298d4f07a8df..8e24890c8812 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -115,13 +115,18 @@ public class FooterView extends StackScrollerDecorView {
}
public class FooterViewState extends ExpandableViewState {
+ /**
+ * used to hide the content of the footer to animate.
+ * #hide is applied without animation, but #hideContent has animation.
+ */
+ public boolean hideContent;
+
@Override
public void applyToView(View view) {
super.applyToView(view);
if (view instanceof FooterView) {
FooterView footerView = (FooterView) view;
- boolean visible = this.clipTopAmount < mClearAllTopPadding;
- footerView.setContentVisible(visible && footerView.isVisible());
+ footerView.setContentVisible(!hideContent);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 4b1f679b8851..754de580cd61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -42,10 +42,8 @@ public class NotificationBackgroundView extends View {
private int mActualHeight;
private int mClipBottomAmount;
private int mTintColor;
- private float[] mCornerRadii = new float[8];
+ private final float[] mCornerRadii = new float[8];
private boolean mBottomIsRounded;
- private boolean mLastInSection;
- private boolean mFirstInSection;
private int mBackgroundTop;
private boolean mBottomAmountClips = true;
private boolean mExpandAnimationRunning;
@@ -53,9 +51,6 @@ public class NotificationBackgroundView extends View {
private int mDrawableAlpha = 255;
private boolean mIsPressedAllowed;
- private boolean mTopAmountRounded;
- private float mDistanceToTopRoundness;
-
public NotificationBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
mDontModifyCorners = getResources().getBoolean(
@@ -90,15 +85,6 @@ public class NotificationBackgroundView extends View {
left = (int) ((getWidth() - mActualWidth) / 2.0f);
right = (int) (left + mActualWidth);
}
- if (mTopAmountRounded) {
- int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness);
- if (clipTop >= 0 || !mFirstInSection) {
- top += clipTop;
- }
- if (clipTop >= 0 && !mLastInSection) {
- bottom += clipTop;
- }
- }
drawable.setBounds(left, top, right, bottom);
drawable.draw(canvas);
}
@@ -180,14 +166,6 @@ public class NotificationBackgroundView extends View {
invalidate();
}
- public void setDistanceToTopRoundness(float distanceToTopRoundness) {
- if (distanceToTopRoundness != mDistanceToTopRoundness) {
- mTopAmountRounded = distanceToTopRoundness >= 0;
- mDistanceToTopRoundness = distanceToTopRoundness;
- invalidate();
- }
- }
-
@Override
public boolean hasOverlappingRendering() {
@@ -246,18 +224,6 @@ public class NotificationBackgroundView extends View {
}
}
- /** Sets whether this background belongs to the last notification in a section. */
- public void setLastInSection(boolean lastInSection) {
- mLastInSection = lastInSection;
- invalidate();
- }
-
- /** Sets whether this background belongs to the first notification in a section. */
- public void setFirstInSection(boolean firstInSection) {
- mFirstInSection = firstInSection;
- invalidate();
- }
-
private void updateBackgroundRadii() {
if (mDontModifyCorners) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 0c86262d9037..6822d24947c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -75,7 +75,6 @@ public class AmbientState {
private int mExpandAnimationTopChange;
private ExpandableNotificationRow mExpandingNotification;
private float mHideAmount;
- private float mNotificationScrimTop;
private boolean mAppearing;
private float mPulseHeight = MAX_PULSE_HEIGHT;
private float mDozeAmount = 0.0f;
@@ -256,20 +255,6 @@ public class AmbientState {
return mHideAmount;
}
- /**
- * Set y position of top of notifications background scrim, relative to top of screen.
- */
- public void setNotificationScrimTop(float notificationScrimTop) {
- mNotificationScrimTop = notificationScrimTop;
- }
-
- /**
- * @return Y position of top of notifications background scrim, relative to top of screen.
- */
- public float getNotificationScrimTop() {
- return mNotificationScrimTop;
- }
-
public void setHideSensitive(boolean hideSensitive) {
mHideSensitive = hideSensitive;
}
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 8277fae64a62..d79c57565dcd 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
@@ -40,6 +40,7 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
@@ -424,13 +425,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private final Rect mBackgroundAnimationRect = new Rect();
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
private int mHeadsUpInset;
+
+ /**
+ * The position of the scroll boundary relative to this view. This is where the notifications
+ * stop scrolling and will start to clip instead.
+ */
+ private int mQsScrollBoundaryPosition;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private final Rect mTmpRect = new Rect();
private DismissListener mDismissListener;
private DismissAllAnimationListener mDismissAllAnimationListener;
private NotificationRemoteInputManager mRemoteInputManager;
private ShadeController mShadeController;
- private Runnable mOnStackYChanged;
+ private Consumer<Boolean> mOnStackYChanged;
protected boolean mClearAllEnabled;
@@ -453,6 +460,38 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private NotificationStackScrollLayoutController mController;
private boolean mKeyguardMediaControllorVisible;
+
+ /**
+ * The clip path used to clip the view in a rounded way.
+ */
+ private final Path mRoundedClipPath = new Path();
+
+ /**
+ * Should we use rounded rect clipping right now
+ */
+ private boolean mShouldUseRoundedRectClipping = false;
+
+ private int mRoundedRectClippingLeft;
+ private int mRoundedRectClippingTop;
+ private int mRoundedRectClippingBottom;
+ private int mRoundedRectClippingRight;
+ private float[] mBgCornerRadii = new float[8];
+
+ /**
+ * Whether stackY should be animated in case the view is getting shorter than the scroll
+ * position and this scrolling will lead to the top scroll inset getting smaller.
+ */
+ private boolean mAnimateStackYForContentHeightChange = false;
+
+ /**
+ * Are we launching a notification right now
+ */
+ private boolean mLaunchingNotification;
+
+ /**
+ * Do notifications dismiss with normal transitioning
+ */
+ private boolean mDismissUsingRowTranslationX = true;
private NotificationEntry mTopHeadsUpEntry;
private long mNumHeadsUp;
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
@@ -506,7 +545,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSectionsManager = notificationSectionsManager;
mFeatureFlags = featureFlags;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
- mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
+ updateSplitNotificationShade();
mSectionsManager.initialize(this, LayoutInflater.from(context));
mSections = mSectionsManager.createSectionsForBuckets();
@@ -862,6 +901,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mCornerRadius = res.getDimensionPixelSize(R.dimen.notification_corner_radius);
mHeadsUpInset = mStatusBarHeight + res.getDimensionPixelSize(
R.dimen.heads_up_status_bar_padding);
+ mQsScrollBoundaryPosition = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.quick_qs_offset_height);
}
void updateCornerRadius() {
@@ -961,6 +1002,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateFirstAndLastBackgroundViews();
updateAlgorithmLayoutMinHeight();
updateOwnTranslationZ();
+
+ // Once the layout has finished, we don't need to animate any scrolling clampings anymore.
+ mAnimateStackYForContentHeightChange = false;
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -1017,33 +1061,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void onPreDrawDuringAnimation() {
mShelf.updateAppearance();
- updateClippingToTopRoundedCorner();
if (!mNeedsAnimation && !mChildrenUpdateRequested) {
updateBackground();
}
}
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void updateClippingToTopRoundedCorner() {
- Float clipStart = mAmbientState.getNotificationScrimTop();
- Float clipEnd = clipStart + mCornerRadius;
- boolean first = true;
- for (int i = 0; i < getChildCount(); i++) {
- ExpandableView child = (ExpandableView) getChildAt(i);
- if (child.getVisibility() == GONE) {
- continue;
- }
- float start = child.getTranslationY();
- float end = start + child.getActualHeight();
- boolean clip = clipStart > start && clipStart < end
- || clipEnd >= start && clipEnd <= end;
- clip &= !(first && mScrollAdapter.isScrolledToTop());
- child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0)
- : ExpandableView.NO_ROUNDNESS);
- first = false;
- }
- }
-
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void updateScrollStateForAddedChildren() {
if (mChildrenToAddAnimated.isEmpty()) {
@@ -1117,7 +1139,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private void clampScrollPosition() {
int scrollRange = getScrollRange();
if (scrollRange < mOwnScrollY) {
- setOwnScrollY(scrollRange);
+ boolean animateStackY = false;
+ if (scrollRange < getScrollAmountToScrollBoundary()
+ && mAnimateStackYForContentHeightChange) {
+ // if the scroll boundary updates the position of the stack,
+ animateStackY = true;
+ }
+ setOwnScrollY(scrollRange, animateStackY);
}
}
@@ -1146,6 +1174,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
* Apply expansion fraction to the y position and height of the notifications panel.
*/
private void updateStackPosition() {
+ updateStackPosition(false /* listenerNeedsAnimation */);
+ }
+
+ /**
+ * Apply expansion fraction to the y position and height of the notifications panel.
+ * @param listenerNeedsAnimation does the listener need to animate?
+ */
+ private void updateStackPosition(boolean listenerNeedsAnimation) {
// Consider interpolating from an mExpansionStartY for use on lockscreen and AOD
float endTopPosition = mTopPadding + mExtraTopInsetForFullShadeTransition
+ mAmbientState.getOverExpansion();
@@ -1153,7 +1189,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
final float stackY = MathUtils.lerp(0, endTopPosition, fraction);
mAmbientState.setStackY(stackY);
if (mOnStackYChanged != null) {
- mOnStackYChanged.run();
+ mOnStackYChanged.accept(listenerNeedsAnimation);
}
if (mQsExpansionFraction <= 0) {
final float stackEndHeight = Math.max(0f,
@@ -1165,7 +1201,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
}
- void setOnStackYChanged(Runnable onStackYChanged) {
+ /**
+ * Add a listener when the StackY changes. The argument signifies whether an animation is
+ * needed.
+ */
+ void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
mOnStackYChanged = onStackYChanged;
}
@@ -1600,7 +1640,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Resources res = getResources();
- mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
+ updateSplitNotificationShade();
mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
float densityScale = res.getDisplayMetrics().density;
mSwipeHelper.setDensityScale(densityScale);
@@ -2527,8 +2567,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateScrollStateForRemovedChild(child);
boolean animationGenerated = generateRemoveAnimation(child);
if (animationGenerated) {
- if (!mSwipedOutViews.contains(child)
- || Math.abs(child.getTranslation()) != child.getWidth()) {
+ if (!mSwipedOutViews.contains(child) || !isFullySwipedOut(child)) {
container.addTransientView(child, 0);
child.setTransientContainer(container);
}
@@ -2540,6 +2579,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
focusNextViewIfFocused(child);
}
+ /**
+ * Has this view been fully swiped out such that it's not visible anymore.
+ */
+ public boolean isFullySwipedOut(ExpandableView child) {
+ return Math.abs(child.getTranslation()) >= Math.abs(getTotalTranslationLength(child));
+ }
+
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void focusNextViewIfFocused(View view) {
if (view instanceof ExpandableNotificationRow) {
@@ -2659,17 +2705,27 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
final int startingPosition = getPositionInLinearLayout(removedChild);
final int childHeight = getIntrinsicHeight(removedChild) + mPaddingBetweenElements;
final int endPosition = startingPosition + childHeight;
- if (endPosition <= mOwnScrollY) {
+ final int scrollBoundaryStart = getScrollAmountToScrollBoundary();
+ mAnimateStackYForContentHeightChange = true;
+ // This is reset onLayout
+ if (endPosition <= mOwnScrollY - scrollBoundaryStart) {
// This child is fully scrolled of the top, so we have to deduct its height from the
// scrollPosition
setOwnScrollY(mOwnScrollY - childHeight);
- } else if (startingPosition < mOwnScrollY) {
+ } else if (startingPosition < mOwnScrollY - scrollBoundaryStart) {
// This child is currently being scrolled into, set the scroll position to the
// start of this child
- setOwnScrollY(startingPosition);
+ setOwnScrollY(startingPosition + scrollBoundaryStart);
}
}
+ /**
+ * @return the amount of scrolling needed to start clipping notifications.
+ */
+ private int getScrollAmountToScrollBoundary() {
+ return mTopPadding - mQsScrollBoundaryPosition;
+ }
+
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private int getIntrinsicHeight(View view) {
if (view instanceof ExpandableView) {
@@ -2758,7 +2814,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateAnimationState(child);
updateChronometerForChild(child);
if (child instanceof ExpandableNotificationRow) {
- ((ExpandableNotificationRow) child).setDismissRtl(mDismissRtl);
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ row.setDismissRtl(mDismissRtl);
+ row.setDismissUsingRowTranslationX(mDismissUsingRowTranslationX);
+
}
}
@@ -2818,6 +2877,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange());
+
+ // Disable clipping for launches
+ setLaunchingNotification(params != null);
requestChildrenUpdate();
}
@@ -2901,7 +2963,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mAnimationEvents.clear();
updateBackground();
updateViewShadows();
- updateClippingToTopRoundedCorner();
} else {
applyCurrentState();
}
@@ -3030,7 +3091,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
removedTranslation = row.getTranslationWhenRemoved();
ignoreChildren = false;
}
- childWasSwipedOut |= Math.abs(row.getTranslation()) == row.getWidth();
+ childWasSwipedOut |= isFullySwipedOut(row);
} else if (child instanceof MediaHeaderView) {
childWasSwipedOut = true;
}
@@ -3038,11 +3099,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
Rect clipBounds = child.getClipBounds();
childWasSwipedOut = clipBounds != null && clipBounds.height() == 0;
- if (childWasSwipedOut && child instanceof ExpandableView) {
+ if (childWasSwipedOut) {
// Clean up any potential transient views if the child has already been swiped
// out, as we won't be animating it further (due to its height already being
// clipped to 0.
- ViewGroup transientContainer = ((ExpandableView) child).getTransientContainer();
+ ViewGroup transientContainer = child.getTransientContainer();
if (transientContainer != null) {
transientContainer.removeTransientView(child);
}
@@ -3795,6 +3856,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateNotificationAnimationStates();
updateChronometers();
requestChildrenUpdate();
+ updateUseRoundedRectClipping();
}
}
@@ -3815,6 +3877,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
void onChildHeightChanged(ExpandableView view, boolean needsAnimation) {
+ boolean previouslyNeededAnimation = mAnimateStackYForContentHeightChange;
+ if (needsAnimation) {
+ mAnimateStackYForContentHeightChange = true;
+ }
updateContentHeight();
updateScrollPositionOnExpandInBottom(view);
clampScrollPosition();
@@ -3835,6 +3901,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
requestAnimationOnViewResize(row);
}
requestChildrenUpdate();
+ mAnimateStackYForContentHeightChange = previouslyNeededAnimation;
}
void onChildHeightReset(ExpandableView view) {
@@ -4015,7 +4082,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
setAnimationRunning(false);
updateBackground();
updateViewShadows();
- updateClippingToTopRoundedCorner();
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4048,7 +4114,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
expandableView.setFakeShadowIntensity(
diff / FakeShadowView.SHADOW_SIBLING_TRESHOLD,
previous.getOutlineAlpha(), (int) yLocation,
- previous.getOutlineTranslation());
+ (int) (previous.getOutlineTranslation() + previous.getTranslation()));
}
previous = expandableView;
}
@@ -4550,17 +4616,29 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void setQsExpansionFraction(float qsExpansionFraction) {
mQsExpansionFraction = qsExpansionFraction;
+ updateUseRoundedRectClipping();
+
+ // If notifications are scrolled,
+ // clear out scrollY by the time we push notifications offscreen
+ if (mOwnScrollY > 0) {
+ setOwnScrollY((int) MathUtils.lerp(mOwnScrollY, 0, mQsExpansionFraction));
+ }
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private void setOwnScrollY(int ownScrollY) {
+ setOwnScrollY(ownScrollY, false /* animateScrollChangeListener */);
+ }
+
+ @ShadeViewRefactor(RefactorComponent.COORDINATOR)
+ private void setOwnScrollY(int ownScrollY, boolean animateStackYChangeListener) {
if (ownScrollY != mOwnScrollY) {
// We still want to call the normal scrolled changed for accessibility reasons
onScrollChanged(mScrollX, ownScrollY, mScrollX, mOwnScrollY);
mOwnScrollY = ownScrollY;
mAmbientState.setScrollY(mOwnScrollY);
updateOnScrollChange();
- updateStackPosition();
+ updateStackPosition(animateStackYChangeListener);
}
}
@@ -4626,6 +4704,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mStatusBarState = statusBarState;
mAmbientState.setStatusBarState(statusBarState);
updateSpeedBumpIndex();
+ updateDismissBehavior();
}
void onStatePostChange(boolean fromShadeLocked) {
@@ -5186,6 +5265,108 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
/**
+ * Set rounded rect clipping bounds on this view.
+ */
+ public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
+ int bottomRadius) {
+ if (mRoundedRectClippingLeft == left && mRoundedRectClippingRight == right
+ && mRoundedRectClippingBottom == bottom && mRoundedRectClippingTop == top
+ && mBgCornerRadii[0] == topRadius && mBgCornerRadii[5] == bottomRadius) {
+ return;
+ }
+ mRoundedRectClippingLeft = left;
+ mRoundedRectClippingTop = top;
+ mRoundedRectClippingBottom = bottom;
+ mRoundedRectClippingRight = right;
+ mBgCornerRadii[0] = topRadius;
+ mBgCornerRadii[1] = topRadius;
+ mBgCornerRadii[2] = topRadius;
+ mBgCornerRadii[3] = topRadius;
+ mBgCornerRadii[4] = bottomRadius;
+ mBgCornerRadii[5] = bottomRadius;
+ mBgCornerRadii[6] = bottomRadius;
+ mBgCornerRadii[7] = bottomRadius;
+ mRoundedClipPath.reset();
+ mRoundedClipPath.addRoundRect(left, top, right, bottom, mBgCornerRadii, Path.Direction.CW);
+ if (mShouldUseRoundedRectClipping) {
+ invalidate();
+ }
+ }
+
+ private void updateSplitNotificationShade() {
+ boolean split = shouldUseSplitNotificationShade(mFeatureFlags, getResources());
+ if (split != mShouldUseSplitNotificationShade) {
+ mShouldUseSplitNotificationShade = split;
+ updateDismissBehavior();
+ updateUseRoundedRectClipping();
+ }
+ }
+
+ private void updateDismissBehavior() {
+ // On the split keyguard, dismissing with clipping without a visual boundary looks odd,
+ // so let's use the content dismiss behavior instead.
+ boolean dismissUsingRowTranslationX = !mShouldUseSplitNotificationShade
+ || mStatusBarState != StatusBarState.KEYGUARD;
+ if (mDismissUsingRowTranslationX != dismissUsingRowTranslationX) {
+ mDismissUsingRowTranslationX = dismissUsingRowTranslationX;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) child).setDismissUsingRowTranslationX(
+ dismissUsingRowTranslationX);
+ }
+ }
+ }
+ }
+
+ /**
+ * Set if we're launching a notification right now.
+ */
+ private void setLaunchingNotification(boolean launching) {
+ if (launching == mLaunchingNotification) {
+ return;
+ }
+ mLaunchingNotification = launching;
+ updateUseRoundedRectClipping();
+ }
+
+ /**
+ * Should we use rounded rect clipping
+ */
+ private void updateUseRoundedRectClipping() {
+ // We don't want to clip notifications when QS is expanded, because incoming heads up on
+ // the bottom would be clipped otherwise
+ boolean qsAllowsClipping = mQsExpansionFraction < 0.5f || mShouldUseSplitNotificationShade;
+ boolean clip = !mLaunchingNotification && mIsExpanded && qsAllowsClipping;
+ if (clip != mShouldUseRoundedRectClipping) {
+ mShouldUseRoundedRectClipping = clip;
+ invalidate();
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ if (mShouldUseRoundedRectClipping) {
+ // Let's clip rounded.
+ canvas.clipPath(mRoundedClipPath);
+ }
+ super.dispatchDraw(canvas);
+ }
+
+ /**
+ * Calculate the total translation needed when dismissing.
+ */
+ public float getTotalTranslationLength(View animView) {
+ if (!mDismissUsingRowTranslationX) {
+ return animView.getMeasuredWidth();
+ }
+ float notificationWidth = animView.getMeasuredWidth();
+ int containerWidth = getMeasuredWidth();
+ float padding = (containerWidth - notificationWidth) / 2.0f;
+ return containerWidth - padding;
+ }
+
+ /**
* A listener that is notified when the empty space below the notifications is clicked on
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index dec98887577e..fb4f5592e97f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -384,6 +384,11 @@ public class NotificationStackScrollLayoutController {
}
@Override
+ public float getTotalTranslationLength(View animView) {
+ return mView.getTotalTranslationLength(animView);
+ }
+
+ @Override
public void onSnooze(StatusBarNotification sbn,
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
mStatusBar.setNotificationSnoozed(sbn, snoozeOption);
@@ -822,8 +827,18 @@ public class NotificationStackScrollLayoutController {
return mView.isLayoutRtl();
}
+ /**
+ * @return the left of the view.
+ */
public int getLeft() {
- return mView.getLeft();
+ return mView.getLeft();
+ }
+
+ /**
+ * @return the top of the view.
+ */
+ public int getTop() {
+ return mView.getTop();
}
public float getTranslationX() {
@@ -1008,7 +1023,7 @@ public class NotificationStackScrollLayoutController {
mView.setQsExpansionFraction(expansionFraction);
}
- public void setOnStackYChanged(Runnable onStackYChanged) {
+ public void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
mView.setOnStackYChanged(onStackYChanged);
}
@@ -1440,6 +1455,14 @@ public class NotificationStackScrollLayoutController {
}
/**
+ * Set rounded rect clipping bounds on this view.
+ */
+ public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
+ int bottomRadius) {
+ mView.setRoundedClippingBounds(left, top, right, bottom, topRadius, bottomRadius);
+ }
+
+ /**
* Enum for UiEvent logged from this class
*/
enum NotificationPanelEvent implements UiEventLogger.UiEventEnum {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index f4c4d440b063..664776975b24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -325,6 +325,11 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
}
@Override
+ protected float getTotalTranslationLength(View animView) {
+ return mCallback.getTotalTranslationLength(animView);
+ }
+
+ @Override
public void setTranslation(View v, float translate) {
if (v instanceof SwipeableView) {
((SwipeableView) v).setTranslation(translate);
@@ -466,6 +471,13 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
void onSnooze(StatusBarNotification sbn, SnoozeOption snoozeOption);
void onDismiss();
+
+ /**
+ * Get the total translation length where we want to swipe to when dismissing the view. By
+ * default this is the size of the view, but can also be larger.
+ * @param animView the view to ask about
+ */
+ float getTotalTranslationLength(View animView);
}
static class Builder {
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 a02ebbfa3521..74e8de4c9d11 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
@@ -158,7 +158,7 @@ public class StackScrollAlgorithm {
AmbientState ambientState) {
float drawStart = ambientState.isOnKeyguard() ? 0
: ambientState.getStackY() - ambientState.getScrollY();
- float clipStart = ambientState.getNotificationScrimTop();
+ float clipStart = 0;
int childCount = algorithmState.visibleChildren.size();
boolean firstHeadsUp = true;
for (int i = 0; i < childCount; i++) {
@@ -411,8 +411,8 @@ public class StackScrollAlgorithm {
final float footerEnd = algorithmState.mCurrentExpandedYPosition
+ view.getIntrinsicHeight();
final boolean noSpaceForFooter = footerEnd > ambientState.getStackEndHeight();
-
- viewState.hidden = shadeClosed || isShelfShowing || noSpaceForFooter;
+ ((FooterView.FooterViewState) viewState).hideContent =
+ shadeClosed || isShelfShowing || noSpaceForFooter;
} else if (view != ambientState.getTrackedHeadsUpRow()) {
if (ambientState.isExpansionChanging()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 4fd2064b394d..ee12b4b2d728 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -392,7 +392,7 @@ public class StackStateAnimator {
0, () -> removeTransientView(changingView), null);
} else if (event.animationType ==
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
- if (Math.abs(changingView.getTranslation()) == changingView.getWidth()
+ if (mHostLayout.isFullySwipedOut(changingView)
&& changingView.getTransientContainer() != null) {
changingView.getTransientContainer().removeTransientView(changingView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 01d489f91de2..c4d1abc1b74c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -63,6 +63,7 @@ public class DozeParameters implements TunerService.Tunable,
private final Resources mResources;
private final BatteryController mBatteryController;
private final FeatureFlags mFeatureFlags;
+ private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private final Set<Callback> mCallbacks = new HashSet<>();
@@ -78,7 +79,8 @@ public class DozeParameters implements TunerService.Tunable,
BatteryController batteryController,
TunerService tunerService,
DumpManager dumpManager,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
mResources = resources;
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
mAlwaysOnPolicy = alwaysOnDisplayPolicy;
@@ -89,6 +91,7 @@ public class DozeParameters implements TunerService.Tunable,
mPowerManager = powerManager;
mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation);
mFeatureFlags = featureFlags;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
tunerService.addTunable(
this,
@@ -220,7 +223,8 @@ public class DozeParameters implements TunerService.Tunable,
* then abruptly showing AOD.
*/
public boolean shouldControlUnlockedScreenOff() {
- return getAlwaysOn() && mFeatureFlags.useNewLockscreenAnimations();
+ return getAlwaysOn() && mFeatureFlags.useNewLockscreenAnimations()
+ && mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation();
}
private boolean getBoolean(String propName, int resId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index 68e20705fbeb..96276f46d23d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -38,7 +38,7 @@ import java.util.LinkedList;
* A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
*/
public class KeyguardIndicationTextView extends TextView {
- private static final long MSG_DURATION_MILLIS = 600;
+ private static final long MSG_DURATION_MILLIS = 1500;
private long mNextAnimationTime = 0;
private boolean mAnimationsEnabled = true;
private LinkedList<CharSequence> mMessages = new LinkedList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index b3569d0884ca..aaddfca4b685 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -101,6 +101,7 @@ import com.android.systemui.fragments.FragmentService;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingManager.FalsingTapListener;
import com.android.systemui.plugins.qs.DetailAdapter;
@@ -108,6 +109,7 @@ import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.qs.QSDetailDisplayer;
+import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.GestureRecorder;
@@ -581,6 +583,11 @@ public class NotificationPanelViewController extends PanelViewController {
* The alpha of the views which only show on the keyguard but not in shade / shade locked
*/
private float mKeyguardOnlyContentAlpha = 1.0f;
+
+ /**
+ * Are we currently in gesture navigation
+ */
+ private boolean mIsGestureNavigation;
private int mOldLayoutDirection;
private NotificationShelfController mNotificationShelfController;
private int mScrimCornerRadius;
@@ -669,6 +676,7 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardMediaController keyguardMediaController,
PrivacyDotViewController privacyDotViewController,
TapAgainViewController tapAgainViewController,
+ NavigationModeController navigationModeController,
FragmentService fragmentService,
QuickAccessWalletController quickAccessWalletController,
@Main Executor uiExecutor,
@@ -769,6 +777,9 @@ public class NotificationPanelViewController extends PanelViewController {
mAuthController = authController;
mLockIconViewController = lockIconViewController;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
+ int currentMode = navigationModeController.addListener(
+ mode -> mIsGestureNavigation = QuickStepContract.isGesturalMode(mode));
+ mIsGestureNavigation = QuickStepContract.isGesturalMode(currentMode);
mView.setBackgroundColor(Color.TRANSPARENT);
OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener();
@@ -819,6 +830,7 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScrollLayoutController.setOverscrollTopChangedListener(
mOnOverscrollTopChangedListener);
mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled);
+ mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged);
mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener(
mOnEmptySpaceClickListener);
addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp);
@@ -1808,9 +1820,15 @@ public class NotificationPanelViewController extends PanelViewController {
}
private boolean isInQsArea(float x, float y) {
- return (x >= mQsFrame.getX() && x <= mQsFrame.getX() + mQsFrame.getWidth()) && (
- y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom()
- || y <= mQs.getView().getY() + mQs.getView().getHeight());
+ if (x < mQsFrame.getX() || x > mQsFrame.getX() + mQsFrame.getWidth()) {
+ return false;
+ }
+ // Let's reject anything at the very bottom around the home handle in gesture nav
+ if (mIsGestureNavigation && y > mView.getHeight() - mNavigationBarBottomHeight) {
+ return false;
+ }
+ return y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom()
+ || y <= mQs.getView().getY() + mQs.getView().getHeight();
}
private boolean isOpenQsEvent(MotionEvent event) {
@@ -2181,15 +2199,17 @@ public class NotificationPanelViewController extends PanelViewController {
mDepthController.setQsPanelExpansion(qsExpansionFraction);
}
- private Runnable mOnStackYChanged = () -> {
+ private void onStackYChanged(boolean shouldAnimate) {
if (mQs != null) {
+ if (shouldAnimate) {
+ mAnimateNextNotificationBounds = true;
+ mNotificationBoundsAnimationDelay = 0;
+ }
setQSClippingBounds();
}
};
private void onNotificationScrolled(int newScrollPosition) {
- // Since this is an overscroller, sometimes the scrollY can be temporarily negative
- // (when overscrollng on the top and flinging). Let's
updateQSExpansionEnabledAmbient();
}
@@ -2200,8 +2220,9 @@ public class NotificationPanelViewController extends PanelViewController {
}
private void updateQSExpansionEnabledAmbient() {
+ final float scrollRangeToTop = mAmbientState.getTopPadding() - mQuickQsOffsetHeight;
mQsExpansionEnabledAmbient =
- mAmbientState.getScrollY() <= 0 && !mAmbientState.isShadeOpening();
+ mAmbientState.getScrollY() <= scrollRangeToTop && !mAmbientState.isShadeOpening();
setQsExpansionEnabled();
}
@@ -2210,14 +2231,13 @@ public class NotificationPanelViewController extends PanelViewController {
* and QS state.
*/
private void setQSClippingBounds() {
- int top = 0;
- int bottom = 0;
- int left = 0;
- int right = 0;
+ int top;
+ int bottom;
+ int left;
+ int right;
final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction());
- final boolean visible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0)
- && !mShouldUseSplitNotificationShade;
+ final boolean qsVisible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0);
if (!mShouldUseSplitNotificationShade) {
if (mTransitioningToFullShadeProgress > 0.0f) {
@@ -2226,7 +2246,6 @@ public class NotificationPanelViewController extends PanelViewController {
top = mTransitionToFullShadeQSPosition;
} else {
final float notificationTop = getQSEdgePosition();
- mAmbientState.setNotificationScrimTop(notificationTop);
top = (int) (isOnKeyguard() ? Math.min(qsPanelBottomY, notificationTop)
: notificationTop);
}
@@ -2234,8 +2253,7 @@ public class NotificationPanelViewController extends PanelViewController {
// notification bounds should take full screen width regardless of insets
left = 0;
right = getView().getRight() + mDisplayRightInset;
- } else if (qsPanelBottomY > 0) { // so bounds are empty on lockscreen
- mAmbientState.setNotificationScrimTop(mSplitShadeNotificationsTopPadding);
+ } else {
top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
bottom = mNotificationStackScrollLayoutController.getHeight();
left = mNotificationStackScrollLayoutController.getLeft();
@@ -2243,17 +2261,17 @@ public class NotificationPanelViewController extends PanelViewController {
}
// top should never be lower than bottom, otherwise it will be invisible.
top = Math.min(top, bottom);
- applyQSClippingBounds(left, top, right, bottom, visible);
+ applyQSClippingBounds(left, top, right, bottom, qsVisible);
}
private void applyQSClippingBounds(int left, int top, int right, int bottom,
- boolean visible) {
+ boolean qsVisible) {
if (!mAnimateNextNotificationBounds || mKeyguardStatusAreaClipBounds.isEmpty()) {
if (mQsClippingAnimation != null) {
// update the end position of the animator
mQsClippingAnimationEndBounds.set(left, top, right, bottom);
} else {
- applyQSClippingImmediately(left, top, right, bottom, visible);
+ applyQSClippingImmediately(left, top, right, bottom, qsVisible);
}
} else {
mQsClippingAnimationEndBounds.set(left, top, right, bottom);
@@ -2277,7 +2295,7 @@ public class NotificationPanelViewController extends PanelViewController {
int animBottom = (int) MathUtils.lerp(startBottom,
mQsClippingAnimationEndBounds.bottom, fraction);
applyQSClippingImmediately(animLeft, animTop, animRight, animBottom,
- visible /* visible */);
+ qsVisible /* qsVisible */);
});
mQsClippingAnimation.addListener(new AnimatorListenerAdapter() {
@Override
@@ -2292,7 +2310,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
private void applyQSClippingImmediately(int left, int top, int right, int bottom,
- boolean visible) {
+ boolean qsVisible) {
// Fancy clipping for quick settings
int radius = mScrimCornerRadius;
int statusBarClipTop = 0;
@@ -2300,19 +2318,34 @@ public class NotificationPanelViewController extends PanelViewController {
if (!mShouldUseSplitNotificationShade) {
// The padding on this area is large enough that we can use a cheaper clipping strategy
mKeyguardStatusAreaClipBounds.set(left, top, right, bottom);
- clipStatusView = visible;
+ clipStatusView = qsVisible;
radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
Math.min(top / (float) mScrimCornerRadius, 1f));
statusBarClipTop = top - mKeyguardStatusBar.getTop();
}
if (mQs != null) {
- mQs.setFancyClipping(top, bottom, radius, visible);
+ mQs.setFancyClipping(top, bottom, radius, qsVisible
+ && !mShouldUseSplitNotificationShade);
}
mKeyguardStatusViewController.setClipBounds(
clipStatusView ? mKeyguardStatusAreaClipBounds : null);
- mScrimController.setNotificationsBounds(left, top, right, bottom);
+ if (!qsVisible && mShouldUseSplitNotificationShade) {
+ // On the lockscreen when qs isn't visible, we don't want the bounds of the shade to
+ // be visible, otherwise you can see the bounds once swiping up to see bouncer
+ mScrimController.setNotificationsBounds(0, 0, 0, 0);
+ } else {
+ mScrimController.setNotificationsBounds(left, top, right, bottom);
+ }
+
mScrimController.setScrimCornerRadius(radius);
mKeyguardStatusBar.setTopClipping(statusBarClipTop);
+ int nsslLeft = left - mNotificationStackScrollLayoutController.getLeft();
+ int nsslRight = right - mNotificationStackScrollLayoutController.getLeft();
+ int nsslTop = top - mNotificationStackScrollLayoutController.getTop();
+ int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop();
+ int bottomRadius = mShouldUseSplitNotificationShade ? radius : 0;
+ mNotificationStackScrollLayoutController.setRoundedClippingBounds(
+ nsslLeft, nsslTop, nsslRight, nsslBottom, radius, bottomRadius);
}
private float getQSEdgePosition() {
@@ -3305,7 +3338,6 @@ public class NotificationPanelViewController extends PanelViewController {
// The expandedHeight is always the full panel Height when bypassing
expandedHeight = getMaxPanelHeightNonBypass();
}
- mNotificationStackScrollLayoutController.setOnStackYChanged(mOnStackYChanged);
mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight);
updateKeyguardBottomAreaAlpha();
updateBigClockAlpha();
@@ -4204,7 +4236,7 @@ public class NotificationPanelViewController extends PanelViewController {
int oldState = mBarState;
boolean keyguardShowing = statusBarState == KEYGUARD;
- if (mUnlockedScreenOffAnimationController.shouldPlayScreenOffAnimation()
+ if (mDozeParameters.shouldControlUnlockedScreenOff()
&& oldState == StatusBarState.SHADE
&& statusBarState == KEYGUARD) {
// This means we're doing the screen off animation - position the keyguard status
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 52f9aca82783..c95879650049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -26,11 +26,9 @@ import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENAB
import android.app.IActivityManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
-import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.RemoteException;
-import android.os.SystemProperties;
import android.os.Trace;
import android.util.Log;
import android.view.Display;
@@ -53,6 +51,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.google.android.collect.Lists;
@@ -108,12 +107,14 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
StatusBarStateController statusBarStateController,
ConfigurationController configurationController,
KeyguardViewMediator keyguardViewMediator,
- KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor,
- DumpManager dumpManager) {
+ KeyguardBypassController keyguardBypassController,
+ SysuiColorExtractor colorExtractor,
+ DumpManager dumpManager,
+ KeyguardStateController keyguardStateController) {
mContext = context;
mWindowManager = windowManager;
mActivityManager = activityManager;
- mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
+ mKeyguardScreenRotation = keyguardStateController.isKeyguardScreenRotationAllowed();
mDozeParameters = dozeParameters;
mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
mLpChanged = new LayoutParams();
@@ -173,12 +174,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
}
}
- private boolean shouldEnableKeyguardScreenRotation() {
- Resources res = mContext.getResources();
- return SystemProperties.getBoolean("lockscreen.rot_override", false)
- || res.getBoolean(R.bool.config_enableLockScreenRotation);
- }
-
/**
* Adds the notification shade view to the window manager.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5ee5e489479d..5d2fe523c803 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -21,7 +21,6 @@ import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WindowType;
import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
-import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
@@ -46,8 +45,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import static com.android.wm.shell.bubbles.BubbleController.TASKBAR_CHANGED_BROADCAST;
-import android.animation.ValueAnimator;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -121,6 +118,7 @@ import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.widget.DateTimeView;
+import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
@@ -402,8 +400,6 @@ public class StatusBar extends SystemUI implements DemoMode,
private LightRevealScrim mLightRevealScrim;
private WiredChargingRippleController mChargingRippleAnimationController;
private PowerButtonReveal mPowerButtonReveal;
- private CircleReveal mCircleReveal;
- private ValueAnimator mCircleRevealAnimator = ValueAnimator.ofFloat(0f, 1f);
private final Object mQueueLock = new Object();
@@ -2778,9 +2774,14 @@ public class StatusBar extends SystemUI implements DemoMode,
+ String.valueOf(CameraIntents.getOverrideCameraPackage(mContext)));
}
- public static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
+ public static void dumpBarTransitions(
+ PrintWriter pw, String var, @Nullable BarTransitions transitions) {
pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
- pw.println(BarTransitions.modeToString(transitions.getMode()));
+ if (transitions != null) {
+ pw.println(BarTransitions.modeToString(transitions.getMode()));
+ } else {
+ pw.println("Unknown");
+ }
}
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
@@ -2803,11 +2804,11 @@ public class StatusBar extends SystemUI implements DemoMode,
return mDisplayMetrics.density;
}
- float getDisplayWidth() {
+ public float getDisplayWidth() {
return mDisplayMetrics.widthPixels;
}
- float getDisplayHeight() {
+ public float getDisplayHeight() {
return mDisplayMetrics.heightPixels;
}
@@ -2841,9 +2842,11 @@ public class StatusBar extends SystemUI implements DemoMode,
mActivityIntentHelper.wouldLaunchResolverActivity(intent,
mLockscreenUserManager.getCurrentUserId());
+ boolean animate =
+ animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
+ true /* isActivityIntent */);
ActivityLaunchAnimator.Controller animController =
- !willLaunchResolverActivity && shouldAnimateLaunch(true /* isActivityIntent */)
- ? wrapAnimationController(animationController, dismissShade) : null;
+ animate ? wrapAnimationController(animationController, dismissShade) : null;
// If we animate, we will dismiss the shade only once the animation is done. This is taken
// care of by the StatusBarLaunchAnimationController.
@@ -2857,7 +2860,7 @@ public class StatusBar extends SystemUI implements DemoMode,
int[] result = new int[]{ActivityManager.START_CANCELED};
mActivityLaunchAnimator.startIntentWithAnimation(animController,
- true /* animate */, intent.getPackage(), (adapter) -> {
+ animate, intent.getPackage(), (adapter) -> {
ActivityOptions options = new ActivityOptions(
getActivityOptions(mDisplayId, adapter));
options.setDisallowEnterPictureInPictureWhileLaunching(
@@ -2907,16 +2910,12 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
- willLaunchResolverActivity, true /* deferred */);
+ willLaunchResolverActivity, true /* deferred */, animate);
}
@Nullable
private ActivityLaunchAnimator.Controller wrapAnimationController(
- @Nullable ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
- if (animationController == null) {
- return null;
- }
-
+ ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
View rootView = animationController.getLaunchContainer().getRootView();
if (rootView == mSuperStatusBarViewFactory.getStatusBarWindowView()) {
// We are animating a view in the status bar. We have to make sure that the status bar
@@ -2959,34 +2958,56 @@ public class StatusBar extends SystemUI implements DemoMode,
final boolean dismissShade,
final boolean afterKeyguardGone,
final boolean deferred) {
- dismissKeyguardThenExecute(() -> {
- if (runnable != null) {
- if (mStatusBarKeyguardViewManager.isShowing()
- && mStatusBarKeyguardViewManager.isOccluded()) {
- mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
- } else {
- AsyncTask.execute(runnable);
- }
- }
- if (dismissShade) {
- if (mExpandedVisible && !mBouncerShowing) {
- mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed*/);
- } else {
+ executeRunnableDismissingKeyguard(runnable, cancelAction, dismissShade, afterKeyguardGone,
+ deferred, false /* willAnimateOnKeyguard */);
+ }
- // Do it after DismissAction has been processed to conserve the needed ordering.
- mHandler.post(mShadeController::runPostCollapseRunnables);
+ public void executeRunnableDismissingKeyguard(final Runnable runnable,
+ final Runnable cancelAction,
+ final boolean dismissShade,
+ final boolean afterKeyguardGone,
+ final boolean deferred,
+ final boolean willAnimateOnKeyguard) {
+ OnDismissAction onDismissAction = new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ if (runnable != null) {
+ if (mStatusBarKeyguardViewManager.isShowing()
+ && mStatusBarKeyguardViewManager.isOccluded()) {
+ mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+ } else {
+ AsyncTask.execute(runnable);
+ }
}
- } else if (isInLaunchTransition()
- && mNotificationPanelViewController.isLaunchTransitionFinished()) {
+ if (dismissShade) {
+ if (mExpandedVisible && !mBouncerShowing) {
+ mShadeController.animateCollapsePanels(
+ CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */, true /* delayed*/);
+ } else {
+
+ // Do it after DismissAction has been processed to conserve the needed
+ // ordering.
+ mHandler.post(mShadeController::runPostCollapseRunnables);
+ }
+ } else if (StatusBar.this.isInLaunchTransition()
+ && mNotificationPanelViewController.isLaunchTransitionFinished()) {
+
+ // We are not dismissing the shade, but the launch transition is already
+ // finished,
+ // so nobody will call readyForKeyguardDone anymore. Post it such that
+ // keyguardDonePending gets called first.
+ mHandler.post(mStatusBarKeyguardViewManager::readyForKeyguardDone);
+ }
+ return deferred;
+ }
- // We are not dismissing the shade, but the launch transition is already finished,
- // so nobody will call readyForKeyguardDone anymore. Post it such that
- // keyguardDonePending gets called first.
- mHandler.post(mStatusBarKeyguardViewManager::readyForKeyguardDone);
+ @Override
+ public boolean willRunAnimationOnKeyguard() {
+ return willAnimateOnKeyguard;
}
- return deferred;
- }, cancelAction, afterKeyguardGone);
+ };
+ dismissKeyguardThenExecute(onDismissAction, cancelAction, afterKeyguardGone);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -3408,6 +3429,10 @@ public class StatusBar extends SystemUI implements DemoMode,
}
boolean updateIsKeyguard() {
+ return updateIsKeyguard(false /* force */);
+ }
+
+ boolean updateIsKeyguard(boolean force) {
boolean wakeAndUnlocking = mBiometricUnlockController.getMode()
== BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
@@ -3431,7 +3456,7 @@ public class StatusBar extends SystemUI implements DemoMode,
showKeyguardImpl();
}
} else {
- return hideKeyguardImpl();
+ return hideKeyguardImpl(force);
}
return false;
}
@@ -3513,9 +3538,6 @@ public class StatusBar extends SystemUI implements DemoMode,
public void fadeKeyguardWhilePulsing() {
mNotificationPanelViewController.fadeOut(0, FADE_KEYGUARD_DURATION_PULSING,
()-> {
- if (shouldShowCircleReveal()) {
- startCircleReveal();
- }
hideKeyguard();
mStatusBarKeyguardViewManager.onKeyguardFadedAway();
}).start();
@@ -3560,11 +3582,11 @@ public class StatusBar extends SystemUI implements DemoMode,
/**
* @return true if we would like to stay in the shade, false if it should go away entirely
*/
- public boolean hideKeyguardImpl() {
+ public boolean hideKeyguardImpl(boolean force) {
mIsKeyguard = false;
Trace.beginSection("StatusBar#hideKeyguard");
boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
- if (!(mStatusBarStateController.setState(StatusBarState.SHADE))) {
+ if (!(mStatusBarStateController.setState(StatusBarState.SHADE, force))) {
//TODO: StatusBarStateController should probably know about hiding the keyguard and
// notify listeners.
@@ -3856,7 +3878,7 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void onDozeAmountChanged(float linear, float eased) {
if (mFeatureFlags.useNewLockscreenAnimations()
- && !mCircleRevealAnimator.isRunning()) {
+ && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
mLightRevealScrim.setRevealAmount(1f - linear);
}
}
@@ -3879,7 +3901,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|| (!isDozing && mWakefulnessLifecycle.getLastWakeReason()
== PowerManager.WAKE_REASON_POWER_BUTTON)) {
mLightRevealScrim.setRevealEffect(mPowerButtonReveal);
- } else if (!mCircleRevealAnimator.isRunning()) {
+ } else if (!(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
}
@@ -3891,36 +3913,8 @@ public class StatusBar extends SystemUI implements DemoMode,
Trace.endSection();
}
- /**
- * Update the parameters for the dozing circle reveal that animates when the user authenticates
- * from AOD using the fingerprint sensor.
- */
- public void updateCircleReveal() {
- final PointF fpLocation = mAuthRippleController.getFingerprintSensorLocation();
- if (fpLocation != null) {
- mCircleReveal =
- new CircleReveal(
- fpLocation.x,
- fpLocation.y,
- 0,
- Math.max(Math.max(fpLocation.x, getDisplayWidth() - fpLocation.x),
- Math.max(fpLocation.y, getDisplayHeight() - fpLocation.y)));
- }
- }
-
- private void startCircleReveal() {
- mLightRevealScrim.setRevealEffect(mCircleReveal);
- mCircleRevealAnimator.cancel();
- mCircleRevealAnimator.addUpdateListener(animation ->
- mLightRevealScrim.setRevealAmount(
- (float) mCircleRevealAnimator.getAnimatedValue()));
- mCircleRevealAnimator.setDuration(900);
- mCircleRevealAnimator.start();
- }
-
- private boolean shouldShowCircleReveal() {
- return mCircleReveal != null && !mCircleRevealAnimator.isRunning()
- && mBiometricUnlockController.getBiometricType() == FINGERPRINT;
+ public LightRevealScrim getLightRevealScrim() {
+ return mLightRevealScrim;
}
private void updateKeyguardState() {
@@ -4060,7 +4054,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// The screen off animation uses our LightRevealScrim - we need to be expanded for it to
// be visible.
- if (mUnlockedScreenOffAnimationController.shouldPlayScreenOffAnimation()) {
+ if (mDozeParameters.shouldControlUnlockedScreenOff()) {
makeExpandedVisible(true);
}
@@ -4609,28 +4603,37 @@ public class StatusBar extends SystemUI implements DemoMode,
*
* @param action The action to execute after dismissing the keyguard.
* @param collapsePanel Whether we should collapse the panel after dismissing the keyguard.
- * @param deferKeyguardDismiss Whether we should defer the keyguard actual dismissal, for
- * instance to run animations on the keyguard before hiding it.
+ * @param willAnimateOnKeyguard Whether {@param action} will run an animation on the keyguard if
+ * we are locked.
*/
private void executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone,
- boolean collapsePanel, boolean deferKeyguardDismiss) {
+ boolean collapsePanel, boolean willAnimateOnKeyguard) {
if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
- dismissKeyguardThenExecute(() -> {
- new Thread(() -> {
- try {
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- action.run();
- }).start();
+ OnDismissAction onDismissAction = new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ new Thread(() -> {
+ try {
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ action.run();
+ }).start();
- return collapsePanel ? mShadeController.collapsePanel() : deferKeyguardDismiss;
- }, afterKeyguardGone);
+ return collapsePanel ? mShadeController.collapsePanel() : willAnimateOnKeyguard;
+ }
+
+ @Override
+ public boolean willRunAnimationOnKeyguard() {
+ return willAnimateOnKeyguard;
+ }
+ };
+ dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
}
@Override
@@ -4674,7 +4677,6 @@ public class StatusBar extends SystemUI implements DemoMode,
// the animation on the keyguard). The animation will take care of (instantly) collapsing
// the shade and hiding the keyguard once it is done.
boolean collapse = !animate;
- boolean deferKeyguardDismiss = animate;
executeActionDismissingKeyguard(() -> {
try {
// We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
@@ -4703,7 +4705,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (intentSentUiThreadCallback != null) {
postOnUiThread(intentSentUiThreadCallback);
}
- }, willLaunchResolverActivity, collapse, deferKeyguardDismiss);
+ }, willLaunchResolverActivity, collapse, animate);
}
private void postOnUiThread(Runnable runnable) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index c7efcb2923e7..e8463992ed13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -192,6 +192,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private OnDismissAction mAfterKeyguardGoneAction;
private Runnable mKeyguardGoneCancelAction;
+ private boolean mDismissActionWillAnimateOnKeyguard;
private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
// Dismiss action to be launched when we stop dozing or the keyguard is gone.
@@ -447,6 +448,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
+ mDismissActionWillAnimateOnKeyguard = r != null && r.willRunAnimationOnKeyguard();
// If there is an an alternate auth interceptor (like the UDFPS), show that one instead
// of the bouncer.
@@ -625,9 +627,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mBouncer.startPreHideAnimation(finishRunnable);
mStatusBar.onBouncerPreHideAnimation();
- // startPreHideAnimation() will change the visibility of the bouncer, so we have to
- // make sure to update its state.
- updateStates();
+ // We update the state (which will show the keyguard) only if an animation will run on
+ // the keyguard. If there is no animation, we wait before updating the state so that we
+ // go directly from bouncer to launcher/app.
+ if (mDismissActionWillAnimateOnKeyguard) {
+ updateStates();
+ }
} else if (finishRunnable != null) {
finishRunnable.run();
}
@@ -798,6 +803,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mAfterKeyguardGoneAction = null;
}
mKeyguardGoneCancelAction = null;
+ mDismissActionWillAnimateOnKeyguard = false;
for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) {
mAfterKeyguardGoneRunnables.get(i).run();
}
@@ -866,6 +872,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return; // allow bouncer to trigger saved actions
}
mAfterKeyguardGoneAction = null;
+ mDismissActionWillAnimateOnKeyguard = false;
if (mKeyguardGoneCancelAction != null) {
mKeyguardGoneCancelAction.run();
mKeyguardGoneCancelAction = null;
@@ -892,6 +899,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
};
protected void updateStates() {
+ if (mContainer == null ) {
+ return;
+ }
int vis = mContainer.getSystemUiVisibility();
boolean showing = mShowing;
boolean occluded = mOccluded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index d93b76646d58..98b9cc9bc716 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -41,6 +41,7 @@ import android.text.TextUtils;
import android.util.EventLog;
import android.view.View;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
@@ -260,10 +261,19 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
&& mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
mLockscreenUserManager.getCurrentUserId());
- ActivityStarter.OnDismissAction postKeyguardAction =
- () -> handleNotificationClickAfterKeyguardDismissed(
+ ActivityStarter.OnDismissAction postKeyguardAction = new ActivityStarter.OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ return handleNotificationClickAfterKeyguardDismissed(
entry, row, controller, intent,
isActivityIntent, animate, showOverLockscreen);
+ }
+
+ @Override
+ public boolean willRunAnimationOnKeyguard() {
+ return animate;
+ }
+ };
if (showOverLockscreen) {
mIsCollapsingToShowActivityOverLockscreen = true;
postKeyguardAction.onDismiss();
@@ -453,53 +463,76 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
public void startNotificationGutsIntent(final Intent intent, final int appUid,
ExpandableNotificationRow row) {
boolean animate = mStatusBar.shouldAnimateLaunch(true /* isActivityIntent */);
- mActivityStarter.dismissKeyguardThenExecute(() -> {
- AsyncTask.execute(() -> {
- ActivityLaunchAnimator.Controller animationController =
- new StatusBarLaunchAnimatorController(
- mNotificationAnimationProvider.getAnimatorController(row),
- mStatusBar, true /* isActivityIntent */);
-
- mActivityLaunchAnimator.startIntentWithAnimation(
- animationController, animate, intent.getPackage(),
- (adapter) -> TaskStackBuilder.create(mContext)
- .addNextIntentWithParentStack(intent)
- .startActivities(getActivityOptions(
- mStatusBar.getDisplayId(),
- adapter),
- new UserHandle(UserHandle.getUserId(appUid))));
- });
- return true;
- }, null, false /* afterKeyguardGone */);
+ ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ AsyncTask.execute(() -> {
+ ActivityLaunchAnimator.Controller animationController =
+ new StatusBarLaunchAnimatorController(
+ mNotificationAnimationProvider.getAnimatorController(row),
+ mStatusBar, true /* isActivityIntent */);
+
+ mActivityLaunchAnimator.startIntentWithAnimation(
+ animationController, animate, intent.getPackage(),
+ (adapter) -> TaskStackBuilder.create(mContext)
+ .addNextIntentWithParentStack(intent)
+ .startActivities(getActivityOptions(
+ mStatusBar.getDisplayId(),
+ adapter),
+ new UserHandle(UserHandle.getUserId(appUid))));
+ });
+ return true;
+ }
+
+ @Override
+ public boolean willRunAnimationOnKeyguard() {
+ return animate;
+ }
+ };
+ mActivityStarter.dismissKeyguardThenExecute(onDismissAction, null,
+ false /* afterKeyguardGone */);
}
@Override
public void startHistoryIntent(View view, boolean showHistory) {
boolean animate = mStatusBar.shouldAnimateLaunch(true /* isActivityIntent */);
- mActivityStarter.dismissKeyguardThenExecute(() -> {
- AsyncTask.execute(() -> {
- Intent intent = showHistory ? new Intent(
- Settings.ACTION_NOTIFICATION_HISTORY) : new Intent(
- Settings.ACTION_NOTIFICATION_SETTINGS);
- TaskStackBuilder tsb = TaskStackBuilder.create(mContext)
- .addNextIntent(new Intent(Settings.ACTION_NOTIFICATION_SETTINGS));
- if (showHistory) {
- tsb.addNextIntent(intent);
- }
+ ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ AsyncTask.execute(() -> {
+ Intent intent = showHistory ? new Intent(
+ Settings.ACTION_NOTIFICATION_HISTORY) : new Intent(
+ Settings.ACTION_NOTIFICATION_SETTINGS);
+ TaskStackBuilder tsb = TaskStackBuilder.create(mContext)
+ .addNextIntent(new Intent(Settings.ACTION_NOTIFICATION_SETTINGS));
+ if (showHistory) {
+ tsb.addNextIntent(intent);
+ }
- ActivityLaunchAnimator.Controller animationController =
- new StatusBarLaunchAnimatorController(
- ActivityLaunchAnimator.Controller.fromView(view), mStatusBar,
- true /* isActivityIntent */);
+ ActivityLaunchAnimator.Controller viewController =
+ ActivityLaunchAnimator.Controller.fromView(view,
+ InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON
+ );
+ ActivityLaunchAnimator.Controller animationController =
+ new StatusBarLaunchAnimatorController(viewController, mStatusBar,
+ true /* isActivityIntent */);
+
+ mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
+ intent.getPackage(),
+ (adapter) -> tsb.startActivities(
+ getActivityOptions(mStatusBar.getDisplayId(), adapter),
+ UserHandle.CURRENT));
+ });
+ return true;
+ }
- mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
- intent.getPackage(),
- (adapter) -> tsb.startActivities(
- getActivityOptions(mStatusBar.getDisplayId(), adapter),
- UserHandle.CURRENT));
- });
- return true;
- }, null, false /* afterKeyguardGone */);
+ @Override
+ public boolean willRunAnimationOnKeyguard() {
+ return animate;
+ }
+ };
+ mActivityStarter.dismissKeyguardThenExecute(onDismissAction, null,
+ false /* afterKeyguardGone */);
}
private void removeHunAfterClick(ExpandableNotificationRow row) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index e135cc51a7bc..52bf2d577776 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -3,6 +3,8 @@ package com.android.systemui.statusbar.phone
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
+import android.content.Context
+import android.content.res.Configuration
import android.os.Handler
import android.view.View
import com.android.systemui.animation.Interpolators
@@ -16,6 +18,7 @@ import com.android.systemui.statusbar.notification.AnimatableProperty
import com.android.systemui.statusbar.notification.PropertyAnimator
import com.android.systemui.statusbar.notification.stack.AnimationProperties
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
+import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject
/**
@@ -38,10 +41,11 @@ private const val LIGHT_REVEAL_ANIMATION_DURATION = 750L
*/
@SysUISingleton
class UnlockedScreenOffAnimationController @Inject constructor(
+ private val context: Context,
private val wakefulnessLifecycle: WakefulnessLifecycle,
private val statusBarStateControllerImpl: StatusBarStateControllerImpl,
private val keyguardViewMediatorLazy: dagger.Lazy<KeyguardViewMediator>,
- private val dozeParameters: DozeParameters
+ private val keyguardStateController: KeyguardStateController
) : WakefulnessLifecycle.Observer {
private val handler = Handler()
@@ -131,13 +135,18 @@ class UnlockedScreenOffAnimationController @Inject constructor(
lightRevealAnimationPlaying = false
aodUiAnimationPlaying = false
- // Make sure the status bar is in the correct keyguard state, since we might have left it in
- // the KEYGUARD state if this wakeup cancelled the screen off animation.
- statusBar.updateIsKeyguard()
+ // Make sure the status bar is in the correct keyguard state, forcing it if necessary. This
+ // is required if the screen off animation is cancelled, since it might be incorrectly left
+ // in the KEYGUARD or SHADE states depending on when it was cancelled and whether 'lock
+ // instantly' is enabled. We need to force it so that the state is set even if we're going
+ // from SHADE to SHADE or KEYGUARD to KEYGUARD, since we might have changed parts of the UI
+ // (such as showing AOD in the shade) without actually changing the StatusBarState. This
+ // ensures that the UI definitely reflects the desired state.
+ statusBar.updateIsKeyguard(true /* force */)
}
override fun onStartedGoingToSleep() {
- if (shouldPlayScreenOffAnimation()) {
+ if (shouldPlayUnlockedScreenOffAnimation()) {
lightRevealAnimationPlaying = true
lightRevealAnimator.start()
@@ -151,13 +160,31 @@ class UnlockedScreenOffAnimationController @Inject constructor(
}
/**
- * Whether we should play the screen off animation when the phone starts going to sleep. We can
- * do that if dozeParameters says we can control the unlocked screen off animation and we are in
- * the SHADE state. If we're in KEYGUARD or SHADE_LOCKED, the regular
+ * Whether we want to play the screen off animation when the phone starts going to sleep, based
+ * on the current state of the device.
*/
- fun shouldPlayScreenOffAnimation(): Boolean {
- return dozeParameters.shouldControlUnlockedScreenOff() &&
- statusBarStateControllerImpl.state == StatusBarState.SHADE
+ fun shouldPlayUnlockedScreenOffAnimation(): Boolean {
+ // We only play the unlocked screen off animation if we are... unlocked.
+ if (statusBarStateControllerImpl.state != StatusBarState.SHADE) {
+ return false
+ }
+
+ // We currently draw both the light reveal scrim, and the AOD UI, in the shade. If it's
+ // already expanded and showing notifications/QS, the animation looks really messy. For now,
+ // disable it if the notification panel is expanded.
+ if (statusBar.notificationPanelViewController.isFullyExpanded) {
+ return false
+ }
+
+ // If we're not allowed to rotate the keyguard, then only do the screen off animation if
+ // we're in portrait. Otherwise, AOD will animate in sideways, which looks weird.
+ if (!keyguardStateController.isKeyguardScreenRotationAllowed &&
+ context.resources.configuration.orientation != Configuration.ORIENTATION_PORTRAIT) {
+ return false
+ }
+
+ // Otherwise, good to go.
+ return true
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index ef7fac311799..b295f6659f81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -25,6 +25,7 @@ import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.Chronometer
+import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dagger.SysUISingleton
@@ -179,7 +180,10 @@ class OngoingCallController @Inject constructor(
logger.logChipClicked()
activityStarter.postStartActivityDismissingKeyguard(
currentCallNotificationInfo.intent, 0,
- ActivityLaunchAnimator.Controller.fromView(backgroundView))
+ ActivityLaunchAnimator.Controller.fromView(
+ backgroundView,
+ InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP)
+ )
}
setUpUidObserver(currentCallNotificationInfo)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
index af7bf9500bf3..fcfc9670b8b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
@@ -57,6 +57,11 @@ public interface KeyguardStateController extends CallbackController<Callback> {
boolean canPerformSmartSpaceTransition();
/**
+ * Whether the keyguard is allowed to rotate, or needs to be locked to the default orientation.
+ */
+ boolean isKeyguardScreenRotationAllowed();
+
+ /**
* If the device has PIN/pattern/password or a lock screen at all.
*/
boolean isMethodSecure();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 0945a3f884d6..64750bd803d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.biometrics.BiometricSourceType;
import android.os.Build;
+import android.os.SystemProperties;
import android.os.Trace;
import androidx.annotation.VisibleForTesting;
@@ -31,6 +32,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dumpable;
+import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController;
@@ -50,6 +52,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
private static final String AUTH_BROADCAST_KEY = "debug_trigger_auth";
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
+ private final Context mContext;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final LockPatternUtils mLockPatternUtils;
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
@@ -100,6 +103,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
public KeyguardStateControllerImpl(Context context,
KeyguardUpdateMonitor keyguardUpdateMonitor, LockPatternUtils lockPatternUtils,
SmartspaceTransitionController smartspaceTransitionController) {
+ mContext = context;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
@@ -243,6 +247,12 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
}
@Override
+ public boolean isKeyguardScreenRotationAllowed() {
+ return SystemProperties.getBoolean("lockscreen.rot_override", false)
+ || mContext.getResources().getBoolean(R.bool.config_enableLockScreenRotation);
+ }
+
+ @Override
public boolean isFaceAuthEnabled() {
return mFaceAuthEnabled;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 4ab07af92006..24604849a776 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -796,6 +796,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
for (int i = 0; i < mMobileSignalControllers.size(); i++) {
MobileSignalController controller = mMobileSignalControllers.valueAt(i);
controller.setConfiguration(mConfig);
+ if (mProviderModel) {
+ controller.refreshCallIndicator(mCallbackHandler);
+ }
}
refreshLocale();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index b17028b05f78..efeeac669491 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -749,7 +749,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
super.dispatchStartTemporaryDetach();
// Detach the EditText temporarily such that it doesn't get onDetachedFromWindow and
// won't lose IME focus.
- detachViewFromParent(mEditText);
+ final int iEditText = indexOfChild(mEditText);
+ if (iEditText != -1) {
+ detachViewFromParent(iEditText);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 26f4a2b9d2b2..d97815f92964 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -68,7 +68,8 @@ public class TunerServiceImpl extends TunerService {
private static final String[] RESET_EXCEPTION_LIST = new String[] {
QSTileHost.TILES_SETTING,
Settings.Secure.DOZE_ALWAYS_ON,
- Settings.Secure.MEDIA_CONTROLS_RESUME
+ Settings.Secure.MEDIA_CONTROLS_RESUME,
+ Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION
};
private final Observer mObserver = new Observer();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 228b9c3da319..407b248cee44 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -151,12 +151,12 @@ public class VolumeDialogImpl implements VolumeDialog,
private final int mDialogShowAnimationDurationMs;
private final int mDialogHideAnimationDurationMs;
- private final int mDialogWidth;
- private final int mDialogCornerRadius;
- private final int mRingerDrawerItemSize;
- private final int mRingerRowsPadding;
- private final boolean mShowVibrate;
- private final int mRingerCount;
+ private int mDialogWidth;
+ private int mDialogCornerRadius;
+ private int mRingerDrawerItemSize;
+ private int mRingerRowsPadding;
+ private boolean mShowVibrate;
+ private int mRingerCount;
private final boolean mShowLowMediaVolumeIcon;
private final boolean mChangeVolumeRowTintWhenInactive;
@@ -288,18 +288,8 @@ public class VolumeDialogImpl implements VolumeDialog,
mDialogRowsView.invalidate();
};
}
- mDialogWidth = mContext.getResources().getDimensionPixelSize(
- R.dimen.volume_dialog_panel_width);
- mDialogCornerRadius = mContext.getResources().getDimensionPixelSize(
- R.dimen.volume_dialog_panel_width_half);
- mRingerDrawerItemSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.volume_ringer_drawer_item_size);
- mRingerRowsPadding = mContext.getResources().getDimensionPixelSize(
- R.dimen.volume_dialog_ringer_rows_padding);
- mShowVibrate = mController.hasVibrator();
- // Normal, mute, and possibly vibrate.
- mRingerCount = mShowVibrate ? 3 : 2;
+ initDimens();
}
@Override
@@ -378,6 +368,8 @@ public class VolumeDialogImpl implements VolumeDialog,
private void initDialog() {
mDialog = new CustomDialog(mContext);
+ initDimens();
+
mConfigurableTexts = new ConfigurableTexts(mContext);
mHovering = false;
mShowing = false;
@@ -569,6 +561,21 @@ public class VolumeDialogImpl implements VolumeDialog,
initODICaptionsH();
}
+ private void initDimens() {
+ mDialogWidth = mContext.getResources().getDimensionPixelSize(
+ R.dimen.volume_dialog_panel_width);
+ mDialogCornerRadius = mContext.getResources().getDimensionPixelSize(
+ R.dimen.volume_dialog_panel_width_half);
+ mRingerDrawerItemSize = mContext.getResources().getDimensionPixelSize(
+ R.dimen.volume_ringer_drawer_item_size);
+ mRingerRowsPadding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.volume_dialog_ringer_rows_padding);
+ mShowVibrate = mController.hasVibrator();
+
+ // Normal, mute, and possibly vibrate.
+ mRingerCount = mShowVibrate ? 3 : 2;
+ }
+
protected ViewGroup getDialogView() {
return mDialogView;
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 10c4a55ad240..5441bd4c958d 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -84,6 +84,7 @@ import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.wm.shell.bubbles.Bubble;
import com.android.wm.shell.bubbles.BubbleEntry;
import com.android.wm.shell.bubbles.Bubbles;
@@ -657,6 +658,22 @@ public class BubblesManager implements Dumpable {
mBubbles.expandStackAndSelectBubble(notifToBubbleEntry(entry));
}
+ /**
+ * Request the stack expand if needed, then select the specified Bubble as current.
+ *
+ * @param bubble the bubble to be selected
+ */
+ public void expandStackAndSelectBubble(Bubble bubble) {
+ mBubbles.expandStackAndSelectBubble(bubble);
+ }
+
+ /**
+ * @return a bubble that matches the provided shortcutId, if one exists.
+ */
+ public Bubble getBubbleWithShortcutId(String shortcutId) {
+ return mBubbles.getBubbleWithShortcutId(shortcutId);
+ }
+
/** See {@link NotifCallback}. */
public void addNotifCallback(NotifCallback callback) {
mCallbacks.add(callback);
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 92ef8504d123..3af82f91af1c 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -34,6 +34,7 @@ import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.view.KeyEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -57,6 +58,7 @@ import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.nano.WmShellTraceProto;
import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.onehanded.OneHandedEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
import com.android.wm.shell.pip.Pip;
@@ -253,6 +255,15 @@ public final class WMShell extends SystemUI
}
});
+ oneHanded.registerEventCallback(new OneHandedEventCallback() {
+ @Override
+ public void notifyExpandNotification() {
+ mSysUiMainExecutor.execute(
+ () -> mCommandQueue.handleSystemKey(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN));
+ }
+ });
+
mOneHandedKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardBouncerChanged(boolean bouncer) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 0342796817c3..3d4da270dd44 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -62,7 +62,6 @@ import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
-import android.os.PowerManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.telephony.ServiceState;
@@ -166,8 +165,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Mock
private AuthController mAuthController;
@Mock
- private PowerManager mPowerManager;
- @Mock
private TelephonyListenerManager mTelephonyListenerManager;
@Mock
private FeatureFlags mFeatureFlags;
@@ -526,46 +523,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
- public void testFingerprintCancelAodInterrupt_onAuthenticationFailed() {
- // GIVEN on keyguard and listening for fingerprint authentication
- mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
- mTestableLooper.processAllMessages();
-
- ArgumentCaptor<FingerprintManager.AuthenticationCallback> fingerprintCallbackCaptor =
- ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class);
- verify(mFingerprintManager).authenticate(any(), any(), fingerprintCallbackCaptor.capture(),
- any(), anyInt(), anyInt());
- FingerprintManager.AuthenticationCallback authCallback =
- fingerprintCallbackCaptor.getValue();
-
- // WHEN authentication fails
- authCallback.onAuthenticationFailed();
-
- // THEN aod interrupt is cancelled
- verify(mAuthController).onCancelUdfps();
- }
-
- @Test
- public void testFingerprintCancelAodInterrupt_onAuthenticationError() {
- // GIVEN on keyguard and listening for fingerprint authentication
- mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
- mTestableLooper.processAllMessages();
-
- ArgumentCaptor<FingerprintManager.AuthenticationCallback> fingerprintCallbackCaptor =
- ArgumentCaptor.forClass(FingerprintManager.AuthenticationCallback.class);
- verify(mFingerprintManager).authenticate(any(), any(), fingerprintCallbackCaptor.capture(),
- any(), anyInt(), anyInt());
- FingerprintManager.AuthenticationCallback authCallback =
- fingerprintCallbackCaptor.getValue();
-
- // WHEN authentication errors
- authCallback.onAuthenticationError(0, "");
-
- // THEN aod interrupt is cancelled
- verify(mAuthController).onCancelUdfps();
- }
-
- @Test
public void skipsAuthentication_whenStatusBarShadeLocked() {
mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
@@ -1022,7 +979,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mBroadcastDispatcher, mDumpManager,
mRingerModeTracker, mBackgroundExecutor,
mStatusBarStateController, mLockPatternUtils,
- mAuthController, mTelephonyListenerManager, mPowerManager, mFeatureFlags);
+ mAuthController, mTelephonyListenerManager, mFeatureFlags);
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 485df21656d3..5617f1b6316b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -59,7 +59,6 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.util.MathUtils;
import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.View;
@@ -489,20 +488,20 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void onRotationChanged_buttonIsShowing_expectedYPosition() {
final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- final int oldWindowHeight = windowBounds.height();
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ final Rect oldDraggableBounds = new Rect(mMagnificationModeSwitch.mDraggableWindowBounds);
final float windowHeightFraction =
- (float) mWindowManager.getLayoutParamsFromAttachedView().y / oldWindowHeight;
+ (float) (mWindowManager.getLayoutParamsFromAttachedView().y
+ - oldDraggableBounds.top) / oldDraggableBounds.height();
- // The window bounds are changed due to the rotation change.
+ // The window bounds and the draggable bounds are changed due to the rotation change.
final Rect newWindowBounds = new Rect(0, 0, windowBounds.height(), windowBounds.width());
mWindowManager.setWindowBounds(newWindowBounds);
mMagnificationModeSwitch.onConfigurationChanged(ActivityInfo.CONFIG_ORIENTATION);
- int expectedY = (int) (newWindowBounds.height() * windowHeightFraction);
- expectedY = MathUtils.constrain(expectedY,
- mMagnificationModeSwitch.mDraggableWindowBounds.top,
- mMagnificationModeSwitch.mDraggableWindowBounds.bottom);
+ int expectedY = (int) (windowHeightFraction
+ * mMagnificationModeSwitch.mDraggableWindowBounds.height())
+ + mMagnificationModeSwitch.mDraggableWindowBounds.top;
assertEquals(
"The Y position does not keep the same height ratio after the rotation changed.",
expectedY, mWindowManager.getLayoutParamsFromAttachedView().y);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 240fdf3a4e17..d87a26b096fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.StatusBar
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -53,6 +54,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
@Mock private lateinit var authController: AuthController
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Mock private lateinit var bypassController: KeyguardBypassController
+ @Mock private lateinit var biometricUnlockController: BiometricUnlockController
@Before
fun setUp() {
@@ -66,6 +68,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
commandRegistry,
notificationShadeWindowController,
bypassController,
+ biometricUnlockController,
rippleView
)
controller.init()
@@ -90,7 +93,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
// THEN update sensor location and show ripple
verify(rippleView).setSensorLocation(fpsLocation)
- verify(rippleView).startRipple(any())
+ verify(rippleView).startRipple(any(), any())
}
@Test
@@ -111,7 +114,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
false /* isStrongBiometric */)
// THEN no ripple
- verify(rippleView, never()).startRipple(any())
+ verify(rippleView, never()).startRipple(any(), any())
}
@Test
@@ -132,7 +135,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
false /* isStrongBiometric */)
// THEN no ripple
- verify(rippleView, never()).startRipple(any())
+ verify(rippleView, never()).startRipple(any(), any())
}
@Test
@@ -156,7 +159,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
// THEN show ripple
verify(rippleView).setSensorLocation(faceLocation)
- verify(rippleView).startRipple(any())
+ verify(rippleView).startRipple(any(), any())
}
@Test
@@ -176,7 +179,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
false /* isStrongBiometric */)
// THEN no ripple
- verify(rippleView, never()).startRipple(any())
+ verify(rippleView, never()).startRipple(any(), any())
}
@Test
@@ -191,7 +194,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
0 /* userId */,
BiometricSourceType.FACE /* type */,
false /* isStrongBiometric */)
- verify(rippleView, never()).startRipple(any())
+ verify(rippleView, never()).startRipple(any(), any())
}
@Test
@@ -206,7 +209,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
0 /* userId */,
BiometricSourceType.FINGERPRINT /* type */,
false /* isStrongBiometric */)
- verify(rippleView, never()).startRipple(any())
+ verify(rippleView, never()).startRipple(any(), any())
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 724f8a3adf80..d6226aa53f67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -73,6 +73,7 @@ public class DozeConfigurationUtil {
when(config.dozePickupSensorAvailable()).thenReturn(false);
when(config.wakeScreenGestureAvailable()).thenReturn(false);
when(config.quickPickupSensorEnabled(anyInt())).thenReturn(false);
+ when(config.screenOffUdfpsEnabled(anyInt())).thenReturn(false);
doneHolder[0] = true;
return config;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index c0b45c6d5c96..a11b9cf357a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -16,7 +16,10 @@
package com.android.systemui.doze;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -161,7 +164,7 @@ public class DozeTriggersTest extends SysuiTestCase {
clearInvocations(mSensors);
mTriggers.transitionTo(DozeMachine.State.DOZE_PULSING, DozeMachine.State.DOZE_PULSE_DONE);
- mTriggers.transitionTo(DozeMachine.State.DOZE_PULSE_DONE, DozeMachine.State.DOZE_AOD);
+ mTriggers.transitionTo(DozeMachine.State.DOZE_PULSE_DONE, DOZE_AOD);
waitForSensorManager();
verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
}
@@ -207,7 +210,7 @@ public class DozeTriggersTest extends SysuiTestCase {
mTriggers.onSensor(DozeLog.REASON_SENSOR_QUICK_PICKUP, 100, 100, null);
// THEN device goes into aod (shows clock with black background)
- verify(mMachine).requestState(DozeMachine.State.DOZE_AOD);
+ verify(mMachine).requestState(DOZE_AOD);
// THEN a log is taken that quick pick up was triggered
verify(mUiEventLogger).log(DozingUpdateUiEvent.DOZING_UPDATE_QUICK_PICKUP);
@@ -218,7 +221,7 @@ public class DozeTriggersTest extends SysuiTestCase {
// GIVEN quick pickup is triggered when device is in DOZE
when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
mTriggers.onSensor(DozeLog.REASON_SENSOR_QUICK_PICKUP, 100, 100, null);
- verify(mMachine).requestState(DozeMachine.State.DOZE_AOD);
+ verify(mMachine).requestState(DOZE_AOD);
verify(mMachine, never()).requestState(DozeMachine.State.DOZE);
// WHEN next executable is run
@@ -234,6 +237,8 @@ public class DozeTriggersTest extends SysuiTestCase {
@Test
public void testOnSensor_Fingerprint() {
+ // GIVEN dozing state
+ when(mMachine.getState()).thenReturn(DOZE_AOD);
final int screenX = 100;
final int screenY = 100;
final float misc = -1;
@@ -241,8 +246,20 @@ public class DozeTriggersTest extends SysuiTestCase {
final float major = 3f;
final int reason = DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
float[] rawValues = new float[]{screenX, screenY, misc, major, minor};
+
+ // WHEN longpress gesture is triggered
mTriggers.onSensor(reason, screenX, screenY, rawValues);
+
+ // THEN
+ // * don't immediately send interrupt
+ // * immediately extend pulse
+ verify(mAuthController, never()).onAodInterrupt(anyInt(), anyInt(), anyFloat(), anyFloat());
verify(mHost).extendPulse(reason);
+
+ // WHEN display state changes to ON
+ mTriggers.onScreenState(Display.STATE_ON);
+
+ // THEN send interrupt
verify(mAuthController).onAodInterrupt(eq(screenX), eq(screenY), eq(major), eq(minor));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index afe5c0b2edbd..1d34aac3b1cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -43,6 +43,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -77,6 +78,8 @@ public class DozeUiTest extends SysuiTestCase {
private DozeUi mDozeUi;
@Mock
private StatusBarStateController mStatusBarStateController;
+ @Mock
+ private ConfigurationController mConfigurationController;
@Before
public void setUp() throws Exception {
@@ -89,7 +92,7 @@ public class DozeUiTest extends SysuiTestCase {
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService,
- () -> mStatusBarStateController);
+ () -> mStatusBarStateController, mConfigurationController);
mDozeUi.setDozeMachine(mMachine);
}
@@ -146,7 +149,7 @@ public class DozeUiTest extends SysuiTestCase {
when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService,
- () -> mStatusBarStateController);
+ () -> mStatusBarStateController, mConfigurationController);
mDozeUi.setDozeMachine(mMachine);
// Never animate if display doesn't support it.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index 83e7b17eb746..adc8ffc1d633 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.when;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioManager;
@@ -38,8 +39,9 @@ import android.os.UserManager;
import android.service.dreams.IDreamManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.view.GestureDetector;
import android.view.IWindowManager;
-import android.view.View;
+import android.view.MotionEvent;
import android.view.WindowManagerPolicyConstants;
import androidx.test.filters.SmallTest;
@@ -57,6 +59,7 @@ import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -107,8 +110,10 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
@Mock private RingerModeTracker mRingerModeTracker;
@Mock private RingerModeLiveData mRingerModeLiveData;
@Mock private SysUiState mSysUiState;
+ @Mock private PackageManager mPackageManager;
@Mock private Handler mHandler;
@Mock private UserContextProvider mUserContextProvider;
+ @Mock private StatusBar mStatusBar;
private TestableLooper mTestableLooper;
@@ -120,6 +125,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData);
when(mUserContextProvider.getUserContext()).thenReturn(mContext);
+ when(mResources.getConfiguration()).thenReturn(
+ getContext().getResources().getConfiguration());
mGlobalActionsDialogLite = new GlobalActionsDialogLite(mContext,
mWindowManagerFuncs,
@@ -150,7 +157,9 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
mInfoProvider,
mRingerModeTracker,
mSysUiState,
- mHandler
+ mHandler,
+ mPackageManager,
+ mStatusBar
);
mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting();
@@ -194,7 +203,7 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
}
@Test
- public void testShouldLogOnTapOutside() {
+ public void testSingleTap_logAndDismiss() {
mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
@@ -207,9 +216,58 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase {
};
doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();
- View container = dialog.findViewById(com.android.systemui.R.id.global_actions_container);
- container.callOnClick();
+
+ GestureDetector.SimpleOnGestureListener gestureListener = spy(dialog.mGestureListener);
+ gestureListener.onSingleTapConfirmed(null);
+ verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
+ }
+
+ @Test
+ public void testSwipeDownLockscreen_logAndOpenQS() {
+ mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
+ doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+ doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
+ doReturn(true).when(mStatusBar).isKeyguardShowing();
+ String[] actions = {
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
+ };
+ doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
+ GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();
+
+ GestureDetector.SimpleOnGestureListener gestureListener = spy(dialog.mGestureListener);
+ MotionEvent start = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+ MotionEvent end = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 500, 0);
+ gestureListener.onFling(start, end, 0, 1000);
+ verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
+ verify(mStatusBar).animateExpandSettingsPanel(null);
+ }
+
+ @Test
+ public void testSwipeDown_logAndOpenNotificationShade() {
+ mGlobalActionsDialogLite = spy(mGlobalActionsDialogLite);
+ doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
+ doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
+ doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
+ doReturn(false).when(mStatusBar).isKeyguardShowing();
+ String[] actions = {
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_LOCKDOWN,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER,
+ GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART,
+ };
+ doReturn(actions).when(mGlobalActionsDialogLite).getDefaultActions();
+ GlobalActionsDialogLite.ActionsDialogLite dialog = mGlobalActionsDialogLite.createDialog();
+
+ GestureDetector.SimpleOnGestureListener gestureListener = spy(dialog.mGestureListener);
+ MotionEvent start = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+ MotionEvent end = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 500, 0);
+ gestureListener.onFling(start, end, 0, 1000);
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
+ verify(mStatusBar).animateExpandNotificationsPanel();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index 3130e977dc83..e5c104e7d377 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.when;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Color;
@@ -65,6 +66,7 @@ import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.telephony.TelephonyListenerManager;
@@ -123,7 +125,9 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
@Mock GlobalActionsPanelPlugin.PanelViewController mWalletController;
@Mock private Handler mHandler;
@Mock private UserTracker mUserTracker;
+ @Mock private PackageManager mPackageManager;
@Mock private SecureSettings mSecureSettings;
+ @Mock private StatusBar mStatusBar;
private TestableLooper mTestableLooper;
@@ -134,6 +138,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
allowTestableLooperAsMainThread();
when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData);
+ when(mResources.getConfiguration()).thenReturn(
+ getContext().getResources().getConfiguration());
mGlobalActionsDialog = new GlobalActionsDialog(mContext,
mWindowManagerFuncs,
@@ -164,7 +170,9 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
mUiEventLogger,
mRingerModeTracker,
mSysUiState,
- mHandler
+ mHandler,
+ mPackageManager,
+ mStatusBar
);
mGlobalActionsDialog.setZeroDialogPressDelayForTesting();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
index 2f78532b9e71..51576687880c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
@@ -34,7 +34,6 @@ import android.content.res.ColorStateList;
import android.graphics.Color;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
-import android.view.View;
import androidx.test.filters.SmallTest;
@@ -258,8 +257,8 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
// WHEN the device is dozing
mStatusBarStateListener.onDozingChanged(true);
- // THEN the view is GONE
- verify(mView).setVisibility(View.GONE);
+ // THEN switch to INDICATION_TYPE_NONE
+ verify(mView).switchIndication(null);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index 15cfee828293..3128db423a24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -9,8 +9,8 @@ import android.media.MediaDescription
import android.media.MediaMetadata
import android.media.session.MediaController
import android.media.session.MediaSession
-import android.provider.Settings
import android.os.Bundle
+import android.provider.Settings
import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
@@ -20,6 +20,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.SbnBuilder
+import com.android.systemui.tuner.TunerService
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
@@ -86,6 +87,8 @@ class MediaDataManagerTest : SysuiTestCase() {
lateinit var mediaNotification: StatusBarNotification
@Captor lateinit var mediaDataCaptor: ArgumentCaptor<MediaData>
private val clock = FakeSystemClock()
+ @Mock private lateinit var tunerService: TunerService
+ @Captor lateinit var tunableCaptor: ArgumentCaptor<TunerService.Tunable>
private val originalSmartspaceSetting = Settings.Secure.getInt(context.contentResolver,
Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, 1)
@@ -114,8 +117,11 @@ class MediaDataManagerTest : SysuiTestCase() {
smartspaceMediaDataProvider = smartspaceMediaDataProvider,
useMediaResumption = true,
useQsMediaPlayer = true,
- systemClock = clock
+ systemClock = clock,
+ tunerService = tunerService
)
+ verify(tunerService).addTunable(capture(tunableCaptor),
+ eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION))
session = MediaSession(context, "MediaDataManagerTestSession")
mediaNotification = SbnBuilder().run {
setPkg(PACKAGE_NAME)
@@ -364,6 +370,9 @@ class MediaDataManagerTest : SysuiTestCase() {
fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_callsRemoveListener() {
smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
smartspaceMediaDataProvider.onTargetsAvailable(listOf())
+ foregroundExecutor.advanceClockToLast()
+ foregroundExecutor.runAllReady()
+
verify(listener).onSmartspaceMediaDataRemoved(eq(KEY_MEDIA_SMARTSPACE), eq(false))
}
@@ -372,6 +381,8 @@ class MediaDataManagerTest : SysuiTestCase() {
// WHEN media recommendation setting is off
Settings.Secure.putInt(context.contentResolver,
Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, 0)
+ tunableCaptor.value.onTuningChanged(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, "0")
+
smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
// THEN smartspace signal is ignored
@@ -380,6 +391,24 @@ class MediaDataManagerTest : SysuiTestCase() {
}
@Test
+ fun testMediaRecommendationDisabled_removesSmartspaceData() {
+ // GIVEN a media recommendation card is present
+ smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
+ verify(listener).onSmartspaceMediaDataLoaded(eq(KEY_MEDIA_SMARTSPACE), anyObject(),
+ anyBoolean())
+
+ // WHEN the media recommendation setting is turned off
+ Settings.Secure.putInt(context.contentResolver,
+ Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, 0)
+ tunableCaptor.value.onTuningChanged(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, "0")
+
+ // THEN listeners are notified
+ foregroundExecutor.advanceClockToLast()
+ foregroundExecutor.runAllReady()
+ verify(listener).onSmartspaceMediaDataRemoved(eq(KEY_MEDIA_SMARTSPACE), eq(true))
+ }
+
+ @Test
fun testOnMediaDataChanged_updatesLastActiveTime() {
val currentTime = clock.elapsedRealtime()
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
index ccb40e116115..f6264ffc6a70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
@@ -16,11 +16,14 @@
package com.android.systemui.people.widget;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -39,11 +42,14 @@ import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.wmshell.BubblesManager;
+import com.android.wm.shell.bubbles.Bubble;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -87,6 +93,8 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
@Mock
private UserManager mUserManager;
+ private CommandQueue mCommandQueue;
+
@Captor
private ArgumentCaptor<NotificationVisibility> mNotificationVisibilityCaptor;
@@ -95,8 +103,9 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mCommandQueue = new CommandQueue(mContext);
mActivity = new LaunchConversationActivity(mNotificationEntryManager,
- Optional.of(mBubblesManager), mUserManager);
+ Optional.of(mBubblesManager), mUserManager, mCommandQueue);
mActivity.setIsForTesting(true, mIStatusBarService);
mIntent = new Intent();
mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, "tile ID");
@@ -159,9 +168,13 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
mActivity.setIntent(mIntent);
mActivity.onCreate(new Bundle());
+ assertThat(mActivity.isFinishing()).isTrue();
+ mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+
verify(mIStatusBarService, times(1)).onNotificationClear(any(),
anyInt(), any(), anyInt(), anyInt(), mNotificationVisibilityCaptor.capture());
- verify(mBubblesManager, never()).expandStackAndSelectBubble(any());
+ verify(mBubblesManager, never()).expandStackAndSelectBubble(any(Bubble.class));
+ verify(mBubblesManager, never()).expandStackAndSelectBubble(any(NotificationEntry.class));
NotificationVisibility nv = mNotificationVisibilityCaptor.getValue();
assertThat(nv.count).isEqualTo(NOTIF_COUNT);
@@ -175,6 +188,9 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
mActivity.setIntent(mIntent);
mActivity.onCreate(new Bundle());
+ assertThat(mActivity.isFinishing()).isTrue();
+ mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+
// Don't clear the notification for bubbles.
verify(mIStatusBarService, never()).onNotificationClear(any(),
anyInt(), any(), anyInt(), anyInt(), any());
@@ -190,8 +206,28 @@ public class LaunchConversationActivityTest extends SysuiTestCase {
mActivity.onCreate(new Bundle());
assertThat(mActivity.isFinishing()).isTrue();
+ mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+
verify(mIStatusBarService, never()).onNotificationClear(any(),
anyInt(), any(), anyInt(), anyInt(), any());
- verify(mBubblesManager, never()).expandStackAndSelectBubble(any());
+ verify(mBubblesManager, never()).expandStackAndSelectBubble(any(Bubble.class));
+ verify(mBubblesManager, never()).expandStackAndSelectBubble(any(NotificationEntry.class));
+ }
+
+ @Ignore
+ @Test
+ public void testBubbleWithNoNotifOpensBubble() throws Exception {
+ Bubble bubble = mock(Bubble.class);
+ when(mBubblesManager.getBubbleWithShortcutId(any())).thenReturn(bubble);
+
+ mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY,
+ EMPTY_STRING);
+ mActivity.setIntent(mIntent);
+ mActivity.onCreate(new Bundle());
+
+ assertThat(mActivity.isFinishing()).isTrue();
+ mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+
+ verify(mBubblesManager, times(1)).expandStackAndSelectBubble(eq(bubble));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index b0e3e3e936a9..2ae4cbe17ac6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -46,6 +46,7 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.dagger.QSFragmentComponent;
+import com.android.systemui.qs.external.CustomTileStatePersister;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.settings.UserTracker;
@@ -132,7 +133,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
() -> mock(AutoTileManager.class), mock(DumpManager.class),
mock(BroadcastDispatcher.class), Optional.of(mock(StatusBar.class)),
mock(QSLogger.class), mock(UiEventLogger.class), mock(UserTracker.class),
- mock(SecureSettings.class));
+ mock(SecureSettings.class), mock(CustomTileStatePersister.class));
qs.setHost(host);
qs.setListening(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 7c73b4c44e90..69bdcbcff270 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -59,6 +59,8 @@ import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.external.CustomTile;
+import com.android.systemui.qs.external.CustomTileStatePersister;
+import com.android.systemui.qs.external.TileServiceKey;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.settings.UserTracker;
@@ -125,6 +127,8 @@ public class QSTileHostTest extends SysuiTestCase {
private UserTracker mUserTracker;
@Mock
private SecureSettings mSecureSettings;
+ @Mock
+ private CustomTileStatePersister mCustomTileStatePersister;
private Handler mHandler;
private TestableLooper mLooper;
@@ -145,7 +149,7 @@ public class QSTileHostTest extends SysuiTestCase {
mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpManager,
mBroadcastDispatcher, mStatusBar, mQSLogger, mUiEventLogger, mUserTracker,
- mSecureSettings);
+ mSecureSettings, mCustomTileStatePersister);
setUpTileFactory();
when(mSecureSettings.getStringForUser(eq(QSTileHost.TILES_SETTING), anyInt()))
@@ -371,6 +375,14 @@ public class QSTileHostTest extends SysuiTestCase {
verify(mQSLogger, never()).logTileDestroyed(isNull(), anyString());
}
+ @Test
+ public void testCustomTileRemoved_stateDeleted() {
+ mQSTileHost.changeTiles(List.of(CUSTOM_TILE_SPEC), List.of());
+
+ verify(mCustomTileStatePersister)
+ .removeState(new TileServiceKey(CUSTOM_TILE, mQSTileHost.getUserId()));
+ }
+
private class TestQSTileHost extends QSTileHost {
TestQSTileHost(Context context, StatusBarIconController iconController,
QSFactory defaultFactory, Handler mainHandler, Looper bgLooper,
@@ -378,10 +390,11 @@ public class QSTileHostTest extends SysuiTestCase {
Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
BroadcastDispatcher broadcastDispatcher, StatusBar statusBar, QSLogger qsLogger,
UiEventLogger uiEventLogger, UserTracker userTracker,
- SecureSettings secureSettings) {
+ SecureSettings secureSettings, CustomTileStatePersister customTileStatePersister) {
super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
tunerService, autoTiles, dumpManager, broadcastDispatcher,
- Optional.of(statusBar), qsLogger, uiEventLogger, userTracker, secureSettings);
+ Optional.of(statusBar), qsLogger, uiEventLogger, userTracker, secureSettings,
+ customTileStatePersister);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
new file mode 100644
index 000000000000..6c96576bcbc1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.external
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.SharedPreferences
+import android.service.quicksettings.Tile
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Answers
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class CustomTileStatePersisterTest : SysuiTestCase() {
+
+ companion object {
+ private val TEST_COMPONENT = ComponentName("pkg", "cls")
+ private const val TEST_USER = 0
+ private val KEY = TileServiceKey(TEST_COMPONENT, TEST_USER)
+
+ private const val TEST_STATE = Tile.STATE_INACTIVE
+ private const val TEST_LABEL = "test_label"
+ private const val TEST_SUBTITLE = "test_subtitle"
+ private const val TEST_CONTENT_DESCRIPTION = "test_content_description"
+ private const val TEST_STATE_DESCRIPTION = "test_state_description"
+
+ private fun Tile.isEqualTo(other: Tile): Boolean {
+ return state == other.state &&
+ label == other.label &&
+ subtitle == other.subtitle &&
+ contentDescription == other.contentDescription &&
+ stateDescription == other.stateDescription
+ }
+ }
+
+ @Mock
+ private lateinit var mockContext: Context
+ @Mock
+ private lateinit var sharedPreferences: SharedPreferences
+ @Mock(answer = Answers.RETURNS_SELF)
+ private lateinit var editor: SharedPreferences.Editor
+ private lateinit var tile: Tile
+ private lateinit var customTileStatePersister: CustomTileStatePersister
+
+ @Captor
+ private lateinit var stringCaptor: ArgumentCaptor<String>
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ `when`(mockContext.getSharedPreferences(anyString(), anyInt()))
+ .thenReturn(sharedPreferences)
+ `when`(sharedPreferences.edit()).thenReturn(editor)
+
+ tile = Tile()
+ customTileStatePersister = CustomTileStatePersister(mockContext)
+ }
+
+ @Test
+ fun testWriteState() {
+ tile.apply {
+ state = TEST_STATE
+ label = TEST_LABEL
+ subtitle = TEST_SUBTITLE
+ contentDescription = TEST_CONTENT_DESCRIPTION
+ stateDescription = TEST_STATE_DESCRIPTION
+ }
+
+ customTileStatePersister.persistState(KEY, tile)
+
+ verify(editor).putString(eq(KEY.toString()), capture(stringCaptor))
+
+ assertThat(tile.isEqualTo(readTileFromString(stringCaptor.value))).isTrue()
+ }
+
+ @Test
+ fun testReadState() {
+ tile.apply {
+ state = TEST_STATE
+ label = TEST_LABEL
+ subtitle = TEST_SUBTITLE
+ contentDescription = TEST_CONTENT_DESCRIPTION
+ stateDescription = TEST_STATE_DESCRIPTION
+ }
+
+ `when`(sharedPreferences.getString(eq(KEY.toString()), any()))
+ .thenReturn(writeToString(tile))
+
+ assertThat(tile.isEqualTo(customTileStatePersister.readState(KEY)!!)).isTrue()
+ }
+
+ @Test
+ fun testReadStateDefault() {
+ `when`(sharedPreferences.getString(any(), any())).thenAnswer {
+ it.getArgument(1)
+ }
+
+ assertThat(customTileStatePersister.readState(KEY)).isNull()
+ }
+
+ @Test
+ fun testStoreNulls() {
+ assertThat(tile.label).isNull()
+
+ customTileStatePersister.persistState(KEY, tile)
+
+ verify(editor).putString(eq(KEY.toString()), capture(stringCaptor))
+
+ assertThat(readTileFromString(stringCaptor.value).label).isNull()
+ }
+
+ @Test
+ fun testReadNulls() {
+ assertThat(tile.label).isNull()
+
+ `when`(sharedPreferences.getString(eq(KEY.toString()), any()))
+ .thenReturn(writeToString(tile))
+
+ assertThat(customTileStatePersister.readState(KEY)!!.label).isNull()
+ }
+
+ @Test
+ fun testRemoveState() {
+ customTileStatePersister.removeState(KEY)
+
+ verify(editor).remove(KEY.toString())
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
index b1c3d1da8fea..9b5c1619ef31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
@@ -38,6 +38,7 @@ import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.util.mockito.any
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -48,8 +49,9 @@ import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.`when`
-import org.mockito.Mockito.any
import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@@ -76,6 +78,7 @@ class CustomTileTest : SysuiTestCase() {
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var applicationInfo: ApplicationInfo
@Mock private lateinit var serviceInfo: ServiceInfo
+ @Mock private lateinit var customTileStatePersister: CustomTileStatePersister
private lateinit var customTile: CustomTile
private lateinit var testableLooper: TestableLooper
@@ -108,10 +111,13 @@ class CustomTileTest : SysuiTestCase() {
metricsLogger,
statusBarStateController,
activityStarter,
- qsLogger
+ qsLogger,
+ customTileStatePersister
)
customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ customTile.initialize()
+ testableLooper.processAllMessages()
}
@Test
@@ -123,6 +129,8 @@ class CustomTileTest : SysuiTestCase() {
`when`(userContext.userId).thenReturn(10)
val tile = CustomTile.create(customTileBuilder, TILE_SPEC, userContext)
+ tile.initialize()
+ testableLooper.processAllMessages()
assertEquals(10, tile.user)
}
@@ -131,6 +139,8 @@ class CustomTileTest : SysuiTestCase() {
fun testToggleableTileHasBooleanState() {
`when`(tileServiceManager.isToggleableTile).thenReturn(true)
customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ customTile.initialize()
+ testableLooper.processAllMessages()
assertTrue(customTile.state is QSTile.BooleanState)
assertTrue(customTile.newTileState() is QSTile.BooleanState)
@@ -146,6 +156,9 @@ class CustomTileTest : SysuiTestCase() {
fun testValueUpdatedInBooleanTile() {
`when`(tileServiceManager.isToggleableTile).thenReturn(true)
customTile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ customTile.initialize()
+ testableLooper.processAllMessages()
+
customTile.qsTile.icon = mock(Icon::class.java)
`when`(customTile.qsTile.icon.loadDrawable(any(Context::class.java)))
.thenReturn(mock(Drawable::class.java))
@@ -173,4 +186,88 @@ class CustomTileTest : SysuiTestCase() {
.thenReturn(null)
customTile.handleUpdateState(customTile.newTileState(), null)
}
+
+ @Test
+ fun testNoLoadStateTileNotActive() {
+ // Not active by default
+ testableLooper.processAllMessages()
+
+ verify(customTileStatePersister, never()).readState(any())
+ }
+
+ @Test
+ fun testNoPersistedStateTileNotActive() {
+ // Not active by default
+ val t = Tile().apply {
+ state = Tile.STATE_INACTIVE
+ }
+ customTile.updateTileState(t)
+ testableLooper.processAllMessages()
+
+ verify(customTileStatePersister, never()).persistState(any(), any())
+ }
+
+ @Test
+ fun testPersistedStateRetrieved() {
+ val state = Tile.STATE_INACTIVE
+ val label = "test_label"
+ val subtitle = "test_subtitle"
+ val contentDescription = "test_content_description"
+ val stateDescription = "test_state_description"
+
+ val t = Tile().apply {
+ this.state = state
+ this.label = label
+ this.subtitle = subtitle
+ this.contentDescription = contentDescription
+ this.stateDescription = stateDescription
+ }
+ `when`(tileServiceManager.isActiveTile).thenReturn(true)
+ `when`(customTileStatePersister
+ .readState(TileServiceKey(componentName, customTile.user))).thenReturn(t)
+ val tile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ tile.initialize()
+ testableLooper.processAllMessages()
+
+ // Make sure we have an icon in the tile because we don't have a default icon
+ // This should not be overridden by the retrieved tile that has null icon.
+ tile.qsTile.icon = mock(Icon::class.java)
+ `when`(tile.qsTile.icon.loadDrawable(any(Context::class.java)))
+ .thenReturn(mock(Drawable::class.java))
+
+ tile.refreshState()
+
+ testableLooper.processAllMessages()
+
+ val tileState = tile.state
+
+ assertEquals(state, tileState.state)
+ assertEquals(label, tileState.label)
+ assertEquals(subtitle, tileState.secondaryLabel)
+ assertEquals(contentDescription, tileState.contentDescription)
+ assertEquals(stateDescription, tileState.stateDescription)
+ }
+
+ @Test
+ fun testStoreStateOnChange() {
+ val t = Tile().apply {
+ state = Tile.STATE_INACTIVE
+ label = "test_label"
+ subtitle = "test_subtitle"
+ contentDescription = "test_content_description"
+ stateDescription = "test_state_description"
+ }
+ `when`(tileServiceManager.isActiveTile).thenReturn(true)
+
+ val tile = CustomTile.create(customTileBuilder, TILE_SPEC, mContext)
+ tile.initialize()
+ testableLooper.processAllMessages()
+
+ tile.updateTileState(t)
+
+ testableLooper.processAllMessages()
+
+ verify(customTileStatePersister)
+ .persistState(TileServiceKey(componentName, customTile.user), t)
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 641f917bcfbe..2b1840462291 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -118,7 +118,8 @@ public class TileServicesTest extends SysuiTestCase {
mQSLogger,
mUiEventLogger,
mUserTracker,
- mSecureSettings);
+ mSecureSettings,
+ mock(CustomTileStatePersister.class));
mTileService = new TestTileServices(host, Looper.getMainLooper(), mBroadcastDispatcher,
mUserTracker);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index 80231a49bb44..ea4d7cc2529c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -121,6 +121,9 @@ public class QSTileImplTest extends SysuiTestCase {
mTile = new TileImpl(mHost, mTestableLooper.getLooper(), mainHandler, mFalsingManager,
mMetricsLogger, mStatusBarStateController, mActivityStarter, mQsLogger);
+ mTile.initialize();
+ mTestableLooper.processAllMessages();
+
mTile.setTileSpec(SPEC);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
index 32b1f433dfcf..5e2d8fde84da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
@@ -80,6 +80,8 @@ class AlarmTileTest : SysuiTestCase() {
nextAlarmController
)
+ tile.initialize()
+
verify(nextAlarmController).observe(eq(tile), capture(callbackCaptor))
tile.refreshState()
testableLooper.processAllMessages()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index f17bd56d0052..1bf83513d472 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -87,6 +87,9 @@ class BatterySaverTileTest : SysuiTestCase() {
qsLogger,
batteryController,
secureSettings)
+
+ tile.initialize()
+ testableLooper.processAllMessages()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
index 7c1a5f5ebf30..d44a52607707 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -112,11 +112,14 @@ public class CastTileTest extends SysuiTestCase {
mNetworkController,
mHotspotController
);
+ mCastTile.initialize();
// We are not setting the mocks to listening, so we trigger a first refresh state to
// set the initial state
mCastTile.refreshState();
+ mTestableLooper.processAllMessages();
+
mCastTile.handleSetListening(true);
ArgumentCaptor<NetworkController.SignalCallback> signalCallbackArgumentCaptor =
ArgumentCaptor.forClass(NetworkController.SignalCallback.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 6d1bbd9708ea..94af10a485fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -378,7 +378,10 @@ class DeviceControlsTileTest : SysuiTestCase() {
qsLogger,
controlsComponent,
keyguardStateController
- )
+ ).also {
+ it.initialize()
+ testableLooper.processAllMessages()
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
index 99d028cd8c5c..cfd37358dcff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
@@ -92,6 +92,9 @@ public class NfcTileTest extends SysuiTestCase {
mQSLogger,
mBroadcastDispatcher
);
+
+ mNfcTile.initialize();
+ mTestableLooper.processAllMessages();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index e4a9aacb57ab..a50cbe5adc48 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -155,6 +155,9 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
mPackageManager,
mSecureSettings,
mController);
+
+ mTile.initialize();
+ mTestableLooper.processAllMessages();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index df4908ddc4ef..9eb688de3511 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -89,6 +89,9 @@ public class ReduceBrightColorsTileTest extends SysuiTestCase {
mActivityStarter,
mQSLogger
);
+
+ mTile.initialize();
+ mTestableLooper.processAllMessages();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index e4af21aa7cd4..964ce01312bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -19,6 +19,7 @@ package com.android.systemui.qs.tiles;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -90,6 +91,9 @@ public class ScreenRecordTileTest extends SysuiTestCase {
mController,
mKeyguardDismissUtil
);
+
+ mTile.initialize();
+ mTestableLooper.processAllMessages();
}
// Test that the tile is inactive and labeled correctly when the controller is neither starting
@@ -167,4 +171,37 @@ public class ScreenRecordTileTest extends SysuiTestCase {
assertTrue(mTile.getState().contentDescription.toString().contains(mTile.getState().label));
}
+
+ @Test
+ public void testForceExpandIcon_notRecordingNotStarting() {
+ when(mController.isStarting()).thenReturn(false);
+ when(mController.isRecording()).thenReturn(false);
+
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+
+ assertTrue(mTile.getState().forceExpandIcon);
+ }
+
+ @Test
+ public void testForceExpandIcon_recordingNotStarting() {
+ when(mController.isStarting()).thenReturn(false);
+ when(mController.isRecording()).thenReturn(true);
+
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+
+ assertFalse(mTile.getState().forceExpandIcon);
+ }
+
+ @Test
+ public void testForceExpandIcon_startingNotRecording() {
+ when(mController.isStarting()).thenReturn(true);
+ when(mController.isRecording()).thenReturn(false);
+
+ mTile.refreshState();
+ mTestableLooper.processAllMessages();
+
+ assertFalse(mTile.getState().forceExpandIcon);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 2e0827f24bf8..fa25c3f1e005 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -289,6 +289,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
@Test
public void testIconScrollXAfterTranslationAndReset() throws Exception {
+ mGroupRow.setDismissUsingRowTranslationX(false);
mGroupRow.setTranslation(50);
assertEquals(50, -mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 9ac600afe990..5bf1bb3c573f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -63,6 +63,7 @@ public class DozeParametersTest extends SysuiTestCase {
@Mock private BatteryController mBatteryController;
@Mock private FeatureFlags mFeatureFlags;
@Mock private DumpManager mDumpManager;
+ @Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@Before
public void setup() {
@@ -75,7 +76,8 @@ public class DozeParametersTest extends SysuiTestCase {
mBatteryController,
mTunerService,
mDumpManager,
- mFeatureFlags
+ mFeatureFlags,
+ mUnlockedScreenOffAnimationController
);
}
@Test
@@ -125,7 +127,8 @@ public class DozeParametersTest extends SysuiTestCase {
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
mDozeParameters.onTuningChanged(Settings.Secure.DOZE_ALWAYS_ON, "1");
when(mFeatureFlags.useNewLockscreenAnimations()).thenReturn(true);
-
+ when(mUnlockedScreenOffAnimationController.shouldPlayUnlockedScreenOffAnimation())
+ .thenReturn(true);
assertTrue(mDozeParameters.shouldControlUnlockedScreenOff());
// Trigger the setter for the current value.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index c6e5697ac199..2d51683c8ae5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -82,8 +82,8 @@ import com.android.systemui.fragments.FragmentService;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
@@ -261,6 +261,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private PrivacyDotViewController mPrivacyDotViewController;
@Mock
+ private NavigationModeController mNavigationModeController;
+ @Mock
private SecureSettings mSecureSettings;
@Mock
private TapAgainViewController mTapAgainViewController;
@@ -391,6 +393,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardMediaController,
mPrivacyDotViewController,
mTapAgainViewController,
+ mNavigationModeController,
mFragmentService,
mQuickAccessWalletController,
new FakeExecutor(new FakeSystemClock()),
@@ -671,21 +674,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
verify(mTapAgainViewController).show();
}
- @Test
- public void testNotificationClipping_isAlignedWithNotificationScrimInSplitShade() {
- mStatusBarStateController.setState(SHADE);
- QS qs = mock(QS.class);
- when(qs.getHeader()).thenReturn(mock(View.class));
- mNotificationPanelViewController.mQs = qs;
- enableSplitShade();
-
- // hacky way to refresh notification scrim top with non-zero qsPanelBottom value
- mNotificationPanelViewController.setTransitionToFullShadeAmount(200, false, 0);
-
- verify(mAmbientState)
- .setNotificationScrimTop(NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE);
- }
-
private FalsingManager.FalsingTapListener getFalsingTapListener() {
for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
listener.onViewAttachedToWindow(mView);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index 323843098a1a..9fe47eceff1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -45,6 +45,7 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
import org.junit.Test;
@@ -70,6 +71,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
@Mock private SysuiColorExtractor mColorExtractor;
@Mock ColorExtractor.GradientColors mGradientColors;
@Mock private DumpManager mDumpManager;
+ @Mock private KeyguardStateController mKeyguardStateController;
@Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
@@ -83,7 +85,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
- mColorExtractor, mDumpManager);
+ mColorExtractor, mDumpManager, mKeyguardStateController);
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index b2efd682bc62..cbc7c6dd0447 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -777,6 +777,12 @@ public class StatusBarTest extends SysuiTestCase {
}
@Test
+ public void testDumpBarTransitions_DoesNotCrash() {
+ StatusBar.dumpBarTransitions(
+ new PrintWriter(new ByteArrayOutputStream()), "var", /* transitions= */ null);
+ }
+
+ @Test
@RunWithLooper(setAsMainLooper = true)
public void testUpdateKeyguardState_DoesNotCrash() {
mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
@@ -843,12 +849,14 @@ public class StatusBarTest extends SysuiTestCase {
// By default, showKeyguardImpl sets state to KEYGUARD.
mStatusBar.showKeyguardImpl();
- verify(mStatusBarStateController).setState(eq(StatusBarState.KEYGUARD));
+ verify(mStatusBarStateController).setState(
+ eq(StatusBarState.KEYGUARD), eq(false) /* force */);
// If useFullscreenUserSwitcher is true, state is set to FULLSCREEN_USER_SWITCHER.
when(mUserSwitcherController.useFullscreenUserSwitcher()).thenReturn(true);
mStatusBar.showKeyguardImpl();
- verify(mStatusBarStateController).setState(eq(StatusBarState.FULLSCREEN_USER_SWITCHER));
+ verify(mStatusBarStateController).setState(
+ eq(StatusBarState.FULLSCREEN_USER_SWITCHER), eq(false) /* force */);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
index 1aebf1c1c80d..e136d00b86f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
@@ -132,4 +132,9 @@ public class FakeKeyguardStateController implements KeyguardStateController {
public boolean canPerformSmartSpaceTransition() {
return false;
}
+
+ @Override
+ public boolean isKeyguardScreenRotationAllowed() {
+ return false;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 6e2e4cb9ecfa..496976e8f55c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -98,6 +98,7 @@ import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -227,6 +228,8 @@ public class BubblesTest extends SysuiTestCase {
private TaskStackListenerImpl mTaskStackListener;
@Mock
private ShellTaskOrganizer mShellTaskOrganizer;
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
private TestableBubblePositioner mPositioner;
@@ -249,7 +252,7 @@ public class BubblesTest extends SysuiTestCase {
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
- mColorExtractor, mDumpManager);
+ mColorExtractor, mDumpManager, mKeyguardStateController);
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
@@ -287,6 +290,7 @@ public class BubblesTest extends SysuiTestCase {
// TODO: Fix
mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
+ mPositioner.setMaxBubbles(5);
mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index 9339f81940d9..9114b7a35fd2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -82,6 +82,7 @@ import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
@@ -192,6 +193,8 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
private TaskStackListenerImpl mTaskStackListener;
@Mock
private ShellTaskOrganizer mShellTaskOrganizer;
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
private TestableBubblePositioner mPositioner;
@@ -213,7 +216,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
- mColorExtractor, mDumpManager);
+ mColorExtractor, mDumpManager, mKeyguardStateController);
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
@@ -232,6 +235,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
+ mPositioner.setMaxBubbles(5);
mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
index 24a7cd5c89ac..6edc373d2926 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
@@ -22,9 +22,11 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.view.WindowManager;
+import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.BubblePositioner;
public class TestableBubblePositioner extends BubblePositioner {
+ private int mMaxBubbles;
public TestableBubblePositioner(Context context,
WindowManager windowManager) {
@@ -33,5 +35,15 @@ public class TestableBubblePositioner extends BubblePositioner {
updateInternal(Configuration.ORIENTATION_PORTRAIT,
Insets.of(0, 0, 0, 0),
new Rect(0, 0, 500, 1000));
+ mMaxBubbles = context.getResources().getInteger(R.integer.bubbles_max_rendered);
+ }
+
+ public void setMaxBubbles(int max) {
+ mMaxBubbles = max;
+ }
+
+ @Override
+ public int getMaxBubbles() {
+ return mMaxBubbles;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 1dd0b21bda30..ff15d0151ea4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -37,6 +37,7 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded;
+import com.android.wm.shell.onehanded.OneHandedEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.pip.Pip;
@@ -106,6 +107,7 @@ public class WMShellTest extends SysuiTestCase {
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
+ verify(mOneHanded).registerEventCallback(any(OneHandedEventCallback.class));
}
@Test
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-bn/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-bn/strings.xml
new file mode 100644
index 000000000000..d13c777fe468
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-bn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"কাটআউট এরিয়ার নিচে অ্যাপ রেন্ডার করুন"</string>
+</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-gu/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-gu/strings.xml
new file mode 100644
index 000000000000..d578d9286d4c
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-gu/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"ઍપને કટઆઉટ ક્ષેત્રની નીચે રેન્ડર કરો"</string>
+</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-kn/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-kn/strings.xml
new file mode 100644
index 000000000000..7a929d13d83f
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-kn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"ಕಟೌಟ್ ಪ್ರದೇಶದ ಕೆಳಗಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ರೆಂಡರ್ ಮಾಡಿ"</string>
+</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-mr/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-mr/strings.xml
new file mode 100644
index 000000000000..42f09cb1a1f0
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-mr/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"कटआउट क्षेत्राच्या खाली असलेली ॲप्स रेंडर करा"</string>
+</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-ne/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-ne/strings.xml
new file mode 100644
index 000000000000..bd213bb64a0d
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-ne/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"कटआउट गरिएको क्षेत्रभन्दा तल पर्ने एपहरू रेन्डर गर्नुहोस्"</string>
+</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-pa/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-pa/strings.xml
new file mode 100644
index 000000000000..908393b1abb0
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-pa/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"ਕੱਟਆਊਟ ਖੇਤਰ ਹੇਠ ਐਪਾਂ ਨੂੰ ਰੈਂਡਰ ਕਰੋ"</string>
+</resources>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-te/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-te/strings.xml
new file mode 100644
index 000000000000..08fa4ae7669b
--- /dev/null
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-te/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"కట్అవుట్ ఏరియా కింద యాప్‌లను రెండర్ చేయండి"</string>
+</resources>
diff --git a/packages/SystemUI/res/drawable/people_space_activity_card.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-ur/strings.xml
index 7e2db635702c..711b5389b26c 100644
--- a/packages/SystemUI/res/drawable/people_space_activity_card.xml
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-ur/strings.xml
@@ -1,5 +1,6 @@
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -12,7 +13,9 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
- -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/people_tile_background" />
-</shape> \ No newline at end of file
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"کٹ آؤٹ ایریا کے نیچے رینڈر ایپس"</string>
+</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values/config.xml
index b9c5f1ded3d5..8d0227eed875 100644
--- a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values/config.xml
@@ -25,9 +25,9 @@
<!-- Max((28 + 20), 0) = 48 -->
<dimen name="status_bar_height_landscape">48dp</dimen>
<!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
- <dimen name="quick_qs_offset_height">28dp</dimen>
+ <dimen name="quick_qs_offset_height">48dp</dimen>
<!-- Total height of QQS (quick_qs_offset_height + 128) -->
- <dimen name="quick_qs_total_height">156dp</dimen>
+ <dimen name="quick_qs_total_height">176dp</dimen>
<dimen name="waterfall_display_left_edge_size">20dp</dimen>
<dimen name="waterfall_display_top_edge_size">0dp</dimen>
diff --git a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
index 3310cb4e3e79..ea2c7d2a41e9 100644
--- a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
+++ b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java
@@ -31,9 +31,9 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.InputDevice;
import android.view.MotionEvent;
+import android.view.WindowManagerPolicyConstants;
import com.android.internal.os.SomeArgs;
-import com.android.server.policy.WindowManagerPolicy;
import java.util.ArrayList;
import java.util.Arrays;
@@ -122,6 +122,12 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement
return;
}
cancelAnyPendingInjectedEvents();
+ // The events injected from outside of system_server are not trusted. Remove the flag to
+ // prevent accessibility service from impersonating a real input device.
+ policyFlags &= ~WindowManagerPolicyConstants.FLAG_INPUTFILTER_TRUSTED;
+ // Indicate that the input event is injected from accessibility, to let applications
+ // distinguish it from events injected by other means.
+ policyFlags |= WindowManagerPolicyConstants.FLAG_INJECTED_FROM_ACCESSIBILITY;
sendMotionEventToNext(event, rawEvent, policyFlags);
}
@@ -156,7 +162,9 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement
return false;
}
MotionEvent motionEvent = (MotionEvent) message.obj;
- sendMotionEventToNext(motionEvent, motionEvent, WindowManagerPolicy.FLAG_PASS_TO_USER);
+ sendMotionEventToNext(motionEvent, motionEvent,
+ WindowManagerPolicyConstants.FLAG_PASS_TO_USER
+ | WindowManagerPolicyConstants.FLAG_INJECTED_FROM_ACCESSIBILITY);
boolean isEndOfSequence = message.arg1 != 0;
if (isEndOfSequence) {
notifyService(mServiceInterfaceForCurrentGesture, mSequencesInProgress.get(0), true);
@@ -308,7 +316,8 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement
MotionEvent cancelEvent =
obtainMotionEvent(now, now, MotionEvent.ACTION_CANCEL, getLastTouchPoints(), 1);
sendMotionEventToNext(cancelEvent, cancelEvent,
- WindowManagerPolicy.FLAG_PASS_TO_USER);
+ WindowManagerPolicyConstants.FLAG_PASS_TO_USER
+ | WindowManagerPolicyConstants.FLAG_INJECTED_FROM_ACCESSIBILITY);
mOpenGesturesInProgress.put(source, false);
}
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 83dfe8ed2576..05131d44b01e 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -454,19 +454,13 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}).cancelTimeout();
}, FgThread.getExecutor()).whenComplete(uncheckExceptions((association, err) -> {
-
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- if (err == null) {
- addAssociation(association);
- } else {
- Slog.e(LOG_TAG, "Failed to discover device(s)", err);
- callback.onFailure("No devices found: " + err.getMessage());
- }
- cleanup();
- } finally {
- Binder.restoreCallingIdentity(callingIdentity);
+ if (err == null) {
+ addAssociation(association);
+ } else {
+ Slog.e(LOG_TAG, "Failed to discover device(s)", err);
+ callback.onFailure("No devices found: " + err.getMessage());
}
+ cleanup();
}));
}
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 84f40cb4b84f..a481a6a5d339 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -61,6 +61,7 @@ public class NsdService extends INsdManager.Stub {
private static final String MDNS_TAG = "mDnsConnector";
private static final boolean DBG = true;
+ private static final long CLEANUP_DELAY_MS = 3000;
private final Context mContext;
private final NsdSettings mNsdSettings;
@@ -77,6 +78,7 @@ public class NsdService extends INsdManager.Stub {
private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();
private final AsyncChannel mReplyChannel = new AsyncChannel();
+ private final long mCleanupDelayMs;
private static final int INVALID_ID = 0;
private int mUniqueId = 1;
@@ -92,6 +94,22 @@ public class NsdService extends INsdManager.Stub {
return NsdManager.nameOf(what);
}
+ void maybeStartDaemon() {
+ mDaemon.maybeStart();
+ maybeScheduleStop();
+ }
+
+ void maybeScheduleStop() {
+ if (!isAnyRequestActive()) {
+ cancelStop();
+ sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
+ }
+ }
+
+ void cancelStop() {
+ this.removeMessages(NsdManager.DAEMON_CLEANUP);
+ }
+
/**
* Observes the NSD on/off setting, and takes action when changed.
*/
@@ -151,10 +169,6 @@ public class NsdService extends INsdManager.Stub {
cInfo.expungeAllRequests();
mClients.remove(msg.replyTo);
}
- //Last client
- if (mClients.size() == 0) {
- mDaemon.stop();
- }
break;
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
AsyncChannel ac = new AsyncChannel();
@@ -180,6 +194,9 @@ public class NsdService extends INsdManager.Stub {
replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
NsdManager.FAILURE_INTERNAL_ERROR);
break;
+ case NsdManager.DAEMON_CLEANUP:
+ mDaemon.maybeStop();
+ break;
case NsdManager.NATIVE_DAEMON_EVENT:
default:
Slog.e(TAG, "Unhandled " + msg);
@@ -212,16 +229,13 @@ public class NsdService extends INsdManager.Stub {
@Override
public void enter() {
sendNsdStateChangeBroadcast(true);
- if (mClients.size() > 0) {
- mDaemon.start();
- }
}
@Override
public void exit() {
- if (mClients.size() > 0) {
- mDaemon.stop();
- }
+ // TODO: it is incorrect to stop the daemon without expunging all requests
+ // and sending error callbacks to clients.
+ maybeScheduleStop();
}
private boolean requestLimitReached(ClientInfo clientInfo) {
@@ -236,12 +250,15 @@ public class NsdService extends INsdManager.Stub {
clientInfo.mClientIds.put(clientId, globalId);
clientInfo.mClientRequests.put(clientId, what);
mIdToClientInfoMap.put(globalId, clientInfo);
+ // Remove the cleanup event because here comes a new request.
+ cancelStop();
}
private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
clientInfo.mClientIds.delete(clientId);
clientInfo.mClientRequests.delete(clientId);
mIdToClientInfoMap.remove(globalId);
+ maybeScheduleStop();
}
@Override
@@ -251,14 +268,12 @@ public class NsdService extends INsdManager.Stub {
int id;
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- //First client
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL &&
- mClients.size() == 0) {
- mDaemon.start();
- }
return NOT_HANDLED;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
return NOT_HANDLED;
+ }
+
+ switch (msg.what) {
case NsdManager.DISABLE:
//TODO: cleanup clients
transitionTo(mDisabledState);
@@ -274,6 +289,7 @@ public class NsdService extends INsdManager.Stub {
break;
}
+ maybeStartDaemon();
id = getUniqueId();
if (discoverServices(id, servInfo.getServiceType())) {
if (DBG) {
@@ -316,6 +332,7 @@ public class NsdService extends INsdManager.Stub {
break;
}
+ maybeStartDaemon();
id = getUniqueId();
if (registerService(id, (NsdServiceInfo) msg.obj)) {
if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
@@ -357,6 +374,7 @@ public class NsdService extends INsdManager.Stub {
break;
}
+ maybeStartDaemon();
id = getUniqueId();
if (resolveService(id, servInfo)) {
clientInfo.mResolvedService = new NsdServiceInfo();
@@ -513,6 +531,10 @@ public class NsdService extends INsdManager.Stub {
}
}
+ private boolean isAnyRequestActive() {
+ return mIdToClientInfoMap.size() != 0;
+ }
+
private String unescape(String s) {
StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); ++i) {
@@ -538,7 +560,9 @@ public class NsdService extends INsdManager.Stub {
}
@VisibleForTesting
- NsdService(Context ctx, NsdSettings settings, Handler handler, DaemonConnectionSupplier fn) {
+ NsdService(Context ctx, NsdSettings settings, Handler handler,
+ DaemonConnectionSupplier fn, long cleanupDelayMs) {
+ mCleanupDelayMs = cleanupDelayMs;
mContext = ctx;
mNsdSettings = settings;
mNsdStateMachine = new NsdStateMachine(TAG, handler);
@@ -552,7 +576,8 @@ public class NsdService extends INsdManager.Stub {
HandlerThread thread = new HandlerThread(TAG);
thread.start();
Handler handler = new Handler(thread.getLooper());
- NsdService service = new NsdService(context, settings, handler, DaemonConnection::new);
+ NsdService service = new NsdService(context, settings, handler,
+ DaemonConnection::new, CLEANUP_DELAY_MS);
service.mDaemonCallback.awaitConnection();
return service;
}
@@ -681,12 +706,16 @@ public class NsdService extends INsdManager.Stub {
@VisibleForTesting
public static class DaemonConnection {
final NativeDaemonConnector mNativeConnector;
+ boolean mIsStarted = false;
DaemonConnection(NativeCallbackReceiver callback) {
mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
new Thread(mNativeConnector, MDNS_TAG).start();
}
+ /**
+ * Executes the specified cmd on the daemon.
+ */
public boolean execute(Object... args) {
if (DBG) {
Slog.d(TAG, "mdnssd " + Arrays.toString(args));
@@ -700,12 +729,26 @@ public class NsdService extends INsdManager.Stub {
return true;
}
- public void start() {
+ /**
+ * Starts the daemon if it is not already started.
+ */
+ public void maybeStart() {
+ if (mIsStarted) {
+ return;
+ }
execute("start-service");
+ mIsStarted = true;
}
- public void stop() {
+ /**
+ * Stops the daemon if it is started.
+ */
+ public void maybeStop() {
+ if (!mIsStarted) {
+ return;
+ }
execute("stop-service");
+ mIsStarted = false;
}
}
@@ -864,6 +907,7 @@ public class NsdService extends INsdManager.Stub {
}
mClientIds.clear();
mClientRequests.clear();
+ mNsdStateMachine.maybeScheduleStop();
}
// mClientIds is a sparse array of listener id -> mDnsClient id. For a given mDnsClient id,
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 7e2274b65f55..f9fd10817627 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -18,6 +18,7 @@ package com.android.server;
import static android.Manifest.permission.DUMP;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
@@ -36,6 +37,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
@@ -73,6 +75,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.LocationPermissionChecker;
+import com.android.net.module.util.PermissionUtils;
import com.android.server.vcn.TelephonySubscriptionTracker;
import com.android.server.vcn.Vcn;
import com.android.server.vcn.VcnContext;
@@ -739,9 +742,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
requireNonNull(listener, "listener was null");
- mContext.enforceCallingOrSelfPermission(
+ PermissionUtils.enforceAnyPermissionOf(
+ mContext,
android.Manifest.permission.NETWORK_FACTORY,
- "Must have permission NETWORK_FACTORY to register a policy listener");
+ android.Manifest.permission.MANAGE_TEST_NETWORKS);
Binder.withCleanCallingIdentity(() -> {
PolicyListenerBinderDeath listenerBinderDeath = new PolicyListenerBinderDeath(listener);
@@ -766,9 +770,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
@NonNull IVcnUnderlyingNetworkPolicyListener listener) {
requireNonNull(listener, "listener was null");
- mContext.enforceCallingOrSelfPermission(
+ PermissionUtils.enforceAnyPermissionOf(
+ mContext,
android.Manifest.permission.NETWORK_FACTORY,
- "Must have permission NETWORK_FACTORY to unregister a policy listener");
+ android.Manifest.permission.MANAGE_TEST_NETWORKS);
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
@@ -819,10 +824,20 @@ public class VcnManagementService extends IVcnManagementService.Stub {
requireNonNull(networkCapabilities, "networkCapabilities was null");
requireNonNull(linkProperties, "linkProperties was null");
- mContext.enforceCallingOrSelfPermission(
+ PermissionUtils.enforceAnyPermissionOf(
+ mContext,
android.Manifest.permission.NETWORK_FACTORY,
- "Must have permission NETWORK_FACTORY or be the SystemServer to get underlying"
- + " Network policies");
+ android.Manifest.permission.MANAGE_TEST_NETWORKS);
+
+ final boolean isUsingManageTestNetworks =
+ mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_FACTORY)
+ != PackageManager.PERMISSION_GRANTED;
+
+ if (isUsingManageTestNetworks && !networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+ throw new IllegalStateException(
+ "NetworkCapabilities must be for Test Network if using permission"
+ + " MANAGE_TEST_NETWORKS");
+ }
return Binder.withCleanCallingIdentity(() -> {
// Defensive copy in case this call is in-process and the given NetworkCapabilities
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8aea4a948299..5e388d94869d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -122,6 +122,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.Process;
import android.os.RemoteCallback;
@@ -1790,6 +1791,7 @@ public final class ActiveServices {
if (!r.fgRequired) {
final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime;
if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
+ resetFgsRestrictionLocked(r);
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
r.appInfo.uid, r.intent.getIntent(), r, r.userId,false);
final String temp = "startForegroundDelayMs:" + delayMs;
@@ -1850,7 +1852,6 @@ public final class ActiveServices {
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
r.foregroundNoti = notification;
r.foregroundServiceType = foregroundServiceType;
- boolean enterForeground = false;
if (!r.isForeground) {
final ServiceMap smap = getServiceMapLocked(r.userId);
if (smap != null) {
@@ -1876,8 +1877,12 @@ public final class ActiveServices {
active.mNumActive++;
}
r.isForeground = true;
- r.mLogEntering = true;
- enterForeground = true;
+ // The logging of FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER event could
+ // be deferred, make a copy of mAllowStartForeground and
+ // mAllowWhileInUsePermissionInFgs.
+ r.mAllowStartForegroundAtEntering = r.mAllowStartForeground;
+ r.mAllowWhileInUsePermissionInFgsAtEntering =
+ r.mAllowWhileInUsePermissionInFgs;
r.mStartForegroundCount++;
r.mFgsEnterTime = SystemClock.uptimeMillis();
if (!stopProcStatsOp) {
@@ -1897,6 +1902,9 @@ public final class ActiveServices {
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
registerAppOpCallbackLocked(r);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, true);
+ logFGSStateChangeLocked(r,
+ FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER,
+ 0);
}
// Even if the service is already a FGS, we need to update the notification,
// so we need to call it again.
@@ -1952,6 +1960,7 @@ public final class ActiveServices {
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT,
r.mFgsExitTime > r.mFgsEnterTime
? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0);
+ r.mFgsNotificationWasDeferred = false;
resetFgsRestrictionLocked(r);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
if (r.app != null) {
@@ -2156,6 +2165,7 @@ public final class ActiveServices {
}
r.fgDisplayTime = when;
r.mFgsNotificationDeferred = true;
+ r.mFgsNotificationWasDeferred = true;
r.mFgsNotificationShown = false;
mPendingFgsNotifications.add(r);
if (DEBUG_FOREGROUND_SERVICE) {
@@ -2199,11 +2209,6 @@ public final class ActiveServices {
Slog.d(TAG_SERVICE, " - service no longer running/fg, ignoring");
}
}
- // Regardless of whether we needed to post the notification or the
- // service is no longer running, we may not have logged its FGS
- // transition yet depending on the timing and API sequence that led
- // to this point - so make sure to do so.
- maybeLogFGSStateEnteredLocked(r);
}
}
if (DEBUG_FOREGROUND_SERVICE) {
@@ -2246,16 +2251,6 @@ public final class ActiveServices {
}
}
- private void maybeLogFGSStateEnteredLocked(ServiceRecord r) {
- if (r.mLogEntering) {
- logFGSStateChangeLocked(r,
- FrameworkStatsLog
- .FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER,
- 0);
- r.mLogEntering = false;
- }
- }
-
/**
* Callback from NotificationManagerService whenever it posts a notification
* associated with a foreground service. This is the unified handling point
@@ -2274,9 +2269,7 @@ public final class ActiveServices {
&& id == sr.foregroundId
&& sr.appInfo.packageName.equals(pkg)) {
// Found it. If 'shown' is false, it means that the notification
- // subsystem will not be displaying it yet, so all we do is log
- // the "fgs entered" transition noting deferral, then we're done.
- maybeLogFGSStateEnteredLocked(sr);
+ // subsystem will not be displaying it yet.
if (shown) {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.d(TAG_SERVICE, "Notification shown; canceling deferral of "
@@ -4234,6 +4227,7 @@ public final class ActiveServices {
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
+ r.mFgsNotificationWasDeferred = false;
resetFgsRestrictionLocked(r);
// Clear start entries.
@@ -6235,19 +6229,29 @@ public final class ActiveServices {
r.packageName, mAm.mConstants.mFgsAtomSampleRate)) {
return;
}
+ boolean allowWhileInUsePermissionInFgs;
+ @PowerExemptionManager.ReasonCode int fgsStartReasonCode;
+ if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER
+ || state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT) {
+ allowWhileInUsePermissionInFgs = r.mAllowWhileInUsePermissionInFgsAtEntering;
+ fgsStartReasonCode = r.mAllowStartForegroundAtEntering;
+ } else {
+ allowWhileInUsePermissionInFgs = r.mAllowWhileInUsePermissionInFgs;
+ fgsStartReasonCode = r.mAllowStartForeground;
+ }
FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid,
r.shortInstanceName,
state,
- r.mAllowWhileInUsePermissionInFgs,
- r.mAllowStartForeground,
+ allowWhileInUsePermissionInFgs,
+ fgsStartReasonCode,
r.appInfo.targetSdkVersion,
r.mRecentCallingUid,
r.mRecentCallerApplicationInfo != null
? r.mRecentCallerApplicationInfo.targetSdkVersion : 0,
r.mInfoTempFgsAllowListReason != null
? r.mInfoTempFgsAllowListReason.mCallingUid : INVALID_UID,
- r.mFgsNotificationDeferred,
+ r.mFgsNotificationWasDeferred,
r.mFgsNotificationShown,
durationMs,
r.mStartForegroundCount,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c841fa3b057c..2de091bb34bf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7124,54 +7124,61 @@ public class ActivityManagerService extends IActivityManager.Stub
if (Binder.getCallingUid() != SYSTEM_UID) {
throw new SecurityException("killPids only available to the system");
}
- String reason = (pReason == null) ? "Unknown" : pReason;
+ final String reason = (pReason == null) ? "Unknown" : pReason;
// XXX Note: don't acquire main activity lock here, because the window
// manager calls in with its locks held.
boolean killed = false;
- synchronized (this) {
- synchronized (mProcLock) {
- synchronized (mPidsSelfLocked) {
- int worstType = 0;
- for (int i = 0; i < pids.length; i++) {
- ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
- if (proc != null) {
- int type = proc.mState.getSetAdj();
- if (type > worstType) {
- worstType = type;
- }
- }
+ final ArrayList<ProcessRecord> killCandidates = new ArrayList<>();
+ synchronized (mPidsSelfLocked) {
+ int worstType = 0;
+ for (int i = 0; i < pids.length; i++) {
+ ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
+ if (proc != null) {
+ int type = proc.mState.getSetAdj();
+ if (type > worstType) {
+ worstType = type;
}
+ }
+ }
- // If the worst oom_adj is somewhere in the cached proc LRU range,
- // then constrain it so we will kill all cached procs.
- if (worstType < ProcessList.CACHED_APP_MAX_ADJ
- && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
- worstType = ProcessList.CACHED_APP_MIN_ADJ;
- }
+ // If the worst oom_adj is somewhere in the cached proc LRU range,
+ // then constrain it so we will kill all cached procs.
+ if (worstType < ProcessList.CACHED_APP_MAX_ADJ
+ && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
+ worstType = ProcessList.CACHED_APP_MIN_ADJ;
+ }
- // If this is not a secure call, don't let it kill processes that
- // are important.
- if (!secure && worstType < ProcessList.SERVICE_ADJ) {
- worstType = ProcessList.SERVICE_ADJ;
- }
+ // If this is not a secure call, don't let it kill processes that
+ // are important.
+ if (!secure && worstType < ProcessList.SERVICE_ADJ) {
+ worstType = ProcessList.SERVICE_ADJ;
+ }
- Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
- for (int i = 0; i < pids.length; i++) {
- ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
- if (proc == null) {
- continue;
- }
- int adj = proc.mState.getSetAdj();
- if (adj >= worstType && !proc.isKilledByAm()) {
- proc.killLocked(reason, ApplicationExitInfo.REASON_OTHER,
- ApplicationExitInfo.SUBREASON_KILL_PID, true);
- killed = true;
- }
- }
+ Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
+ for (int i = 0; i < pids.length; i++) {
+ ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
+ if (proc == null) {
+ continue;
+ }
+ int adj = proc.mState.getSetAdj();
+ if (adj >= worstType && !proc.isKilledByAm()) {
+ killCandidates.add(proc);
+ killed = true;
}
}
}
+ if (!killCandidates.isEmpty()) {
+ mHandler.post(() -> {
+ synchronized (ActivityManagerService.this) {
+ for (int i = 0, size = killCandidates.size(); i < size; i++) {
+ killCandidates.get(i).killLocked(reason,
+ ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_KILL_PID, true);
+ }
+ }
+ });
+ }
return killed;
}
@@ -14309,7 +14316,7 @@ public class ActivityManagerService extends IActivityManager.Stub
private boolean checkExcessivePowerUsageLPr(final long uptimeSince, boolean doCpuKills,
final long cputimeUsed, final String processName, final String description,
final int cpuLimit, final ProcessRecord app) {
- if (DEBUG_POWER) {
+ if (DEBUG_POWER && (uptimeSince > 0)) {
StringBuilder sb = new StringBuilder(128);
sb.append("CPU for ");
sb.append(description);
@@ -15349,6 +15356,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public int[] getStartedUserIds() {
+ return mUserController.getStartedUserArray();
+ }
+
+ @Override
public void setPendingIntentAllowBgActivityStarts(IIntentSender target,
IBinder allowlistToken, int flags) {
if (!(target instanceof PendingIntentRecord)) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 0757e7b6bd7d..d71919e1274c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -102,7 +102,6 @@ import com.android.server.am.LowMemDetector.MemFactor;
import com.android.server.compat.PlatformCompat;
import java.io.BufferedReader;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -806,8 +805,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
return -1;
}
- File file = new File(filename);
- file.delete();
+ // Writes an error message to stderr on failure
ParcelFileDescriptor fd = openFileForSystem(filename, "w");
if (fd == null) {
return -1;
@@ -961,16 +959,16 @@ final class ActivityManagerShellCommand extends ShellCommand {
String logNameTimeString = LOG_NAME_TIME_FORMATTER.format(localDateTime);
heapFile = "/data/local/tmp/heapdump-" + logNameTimeString + ".prof";
}
- pw.println("File: " + heapFile);
- pw.flush();
- File file = new File(heapFile);
- file.delete();
+ // Writes an error message to stderr on failure
ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
if (fd == null) {
return -1;
}
+ pw.println("File: " + heapFile);
+ pw.flush();
+
final CountDownLatch latch = new CountDownLatch(1);
final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 4e6e91ac7b5d..7f6e6687625c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -78,6 +78,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.BatteryUsageStatsProvider;
+import com.android.internal.os.BatteryUsageStatsStore;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.PowerProfile;
import com.android.internal.os.RailStats;
@@ -124,10 +125,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub
Watchdog.Monitor {
static final String TAG = "BatteryStatsService";
static final boolean DBG = false;
+ private static final boolean BATTERY_USAGE_STORE_ENABLED = true;
private static IBatteryStats sService;
final BatteryStatsImpl mStats;
+ private final BatteryUsageStatsStore mBatteryUsageStatsStore;
private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
private final Context mContext;
private final BatteryExternalStatsWorker mWorker;
@@ -348,7 +351,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mStats.setPowerProfileLocked(new PowerProfile(context));
mStats.startTrackingSystemServerCpuTime();
- mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats);
+ if (BATTERY_USAGE_STORE_ENABLED) {
+ mBatteryUsageStatsStore =
+ new BatteryUsageStatsStore(context, mStats, systemDir, mHandler);
+ } else {
+ mBatteryUsageStatsStore = null;
+ }
+ mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats,
+ mBatteryUsageStatsStore);
}
public void publish() {
@@ -752,6 +762,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub
FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL,
null, // use default PullAtomMetadata values
BackgroundThread.getExecutor(), pullAtomCallback);
+ statsManager.setPullAtomCallback(
+ FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET,
+ null, // use default PullAtomMetadata values
+ BackgroundThread.getExecutor(), pullAtomCallback);
}
/** StatsPullAtomCallback for pulling BatteryUsageStats data. */
@@ -768,6 +782,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub
new BatteryUsageStatsQuery.Builder().powerProfileModeledOnly().build();
bus = getBatteryUsageStats(List.of(powerProfileQuery)).get(0);
break;
+ case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET:
+ final long sessionStart = mBatteryUsageStatsStore
+ .getLastBatteryUsageStatsBeforeResetAtomPullTimestamp();
+ final long sessionEnd = mStats.getStartClockTime();
+ final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
+ .aggregateSnapshots(sessionStart, sessionEnd)
+ .build();
+ bus = getBatteryUsageStats(List.of(query)).get(0);
+ mBatteryUsageStatsStore
+ .setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(sessionEnd);
+ break;
default:
throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 62286379ba33..aef402ac3213 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -328,7 +328,8 @@ public class OomAdjuster {
final int index = mCache.indexOfKey(app.packageName);
Pair<Boolean, WeakReference<ApplicationInfo>> p;
if (index < 0) {
- p = new Pair<>(mPlatformCompat.isChangeEnabled(mChangeId, app),
+ p = new Pair<>(mPlatformCompat.isChangeEnabledInternalNoLogging(mChangeId,
+ app),
new WeakReference<>(app));
mCache.put(app.packageName, p);
return p.first;
@@ -338,7 +339,8 @@ public class OomAdjuster {
return p.first;
}
// Cache is invalid, regenerate it
- p = new Pair<>(mPlatformCompat.isChangeEnabled(mChangeId, app),
+ p = new Pair<>(mPlatformCompat.isChangeEnabledInternalNoLogging(mChangeId,
+ app),
new WeakReference<>(app));
mCache.setValueAt(index, p);
return p.first;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 3bfd62b60c89..8ebc987a59f4 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -4289,8 +4289,8 @@ public final class ProcessList {
if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
long lastCpuTime = r.mProfile.mLastCpuTime.get();
- if (lastCpuTime != 0) {
- long uptimeSince = curUptime - service.mLastPowerCheckUptime;
+ long uptimeSince = curUptime - service.mLastPowerCheckUptime;
+ if (lastCpuTime != 0 && uptimeSince > 0) {
long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime;
long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
@@ -4427,7 +4427,7 @@ public final class ProcessList {
if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
long lastCpuTime = r.mProfile.mLastCpuTime.get();
- if (lastCpuTime != 0) {
+ if (lastCpuTime != 0 && uptimeSince > 0) {
long timeUsed = r.mProfile.mCurCpuTime.get() - lastCpuTime;
pw.print(prefix);
pw.print(" ");
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dd1ddd73a84f..141f081ab9a7 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -18,7 +18,7 @@ package com.android.server.am;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-import static android.os.PowerWhitelistManager.REASON_DENIED;
+import static android.os.PowerExemptionManager.REASON_DENIED;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -37,7 +37,7 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
-import android.os.PowerWhitelistManager;
+import android.os.PowerExemptionManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -109,7 +109,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
boolean fgWaiting; // is a timeout for going foreground already scheduled?
boolean isNotAppComponentUsage; // is service binding not considered component/package usage?
boolean isForeground; // is service currently in foreground mode?
- boolean mLogEntering; // need to report fgs transition once deferral policy is known
int foregroundId; // Notification ID of last foreground req.
Notification foregroundNoti; // Notification record of foreground state.
long fgDisplayTime; // time at which the FGS notification should become visible
@@ -153,6 +152,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// allow while-in-use permissions in foreground service or not.
// while-in-use permissions in FGS started from background might be restricted.
boolean mAllowWhileInUsePermissionInFgs;
+ // A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state.
+ boolean mAllowWhileInUsePermissionInFgsAtEntering;
// the most recent package that start/bind this service.
String mRecentCallingPackage;
@@ -165,14 +166,18 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
long mFgsEnterTime = 0;
// The uptime when the service exits FGS state.
long mFgsExitTime = 0;
- // FGS notification was deferred.
+ // FGS notification is deferred.
boolean mFgsNotificationDeferred;
+ // FGS notification was deferred.
+ boolean mFgsNotificationWasDeferred;
// FGS notification was shown before the FGS finishes, or it wasn't deferred in the first place.
boolean mFgsNotificationShown;
// allow the service becomes foreground service? Service started from background may not be
// allowed to become a foreground service.
- @PowerWhitelistManager.ReasonCode int mAllowStartForeground = REASON_DENIED;
+ @PowerExemptionManager.ReasonCode int mAllowStartForeground = REASON_DENIED;
+ // A copy of mAllowStartForeground's value when the service is entering FGS state.
+ @PowerExemptionManager.ReasonCode int mAllowStartForegroundAtEntering = REASON_DENIED;
// Debug info why mAllowStartForeground is allowed or denied.
String mInfoAllowStartForeground;
// Debug info if mAllowStartForeground is allowed because of a temp-allowlist.
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index ce8cbafeba33..99a33e4462e2 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -848,7 +848,7 @@ public class AppOpsService extends IAppOpsService.Stub {
return mAttributionFlags;
}
- /** @return attributoin chiang id for the access */
+ /** @return attribution chain id for the access */
public int getAttributionChainId() {
return mAttributionChainId;
}
@@ -912,7 +912,8 @@ public class AppOpsService extends IAppOpsService.Stub {
proxyAttributionTag, uidState, flags);
mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid, parent.packageName,
- tag, uidState, flags, accessTime);
+ tag, uidState, flags, accessTime, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
+ AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
}
/**
@@ -1029,7 +1030,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (isStarted && mInProgressEvents == null) {
mInProgressEvents = new ArrayMap<>(1);
- } else if (mPausedInProgressEvents == null) {
+ } else if (!isStarted && mPausedInProgressEvents == null) {
mPausedInProgressEvents = new ArrayMap<>(1);
}
ArrayMap<IBinder, InProgressStartOpEvent> events = isStarted
@@ -1053,9 +1054,9 @@ public class AppOpsService extends IAppOpsService.Stub {
event.numUnfinishedStarts++;
if (isStarted) {
- // TODO: Consider storing the attribution chain flags and id
mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
- parent.packageName, tag, uidState, flags, startTime);
+ parent.packageName, tag, uidState, flags, startTime, attributionFlags,
+ attributionChainId);
}
}
@@ -1112,7 +1113,8 @@ public class AppOpsService extends IAppOpsService.Stub {
mHistoricalRegistry.increaseOpAccessDuration(parent.op, parent.uid,
parent.packageName, tag, event.getUidState(),
- event.getFlags(), finishedEvent.getNoteTime(), finishedEvent.getDuration());
+ event.getFlags(), finishedEvent.getNoteTime(), finishedEvent.getDuration(),
+ event.getAttributionFlags(), event.getAttributionChainId());
if (!isPausing) {
mInProgressStartOpEventPool.release(event);
@@ -1215,7 +1217,8 @@ public class AppOpsService extends IAppOpsService.Stub {
event.mStartElapsedTime = SystemClock.elapsedRealtime();
event.mStartTime = startTime;
mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
- parent.packageName, tag, event.mUidState, event.mFlags, startTime);
+ parent.packageName, tag, event.mUidState, event.mFlags, startTime,
+ event.getAttributionFlags(), event.getAttributionChainId());
if (shouldSendActive) {
scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName,
tag, true, event.getAttributionFlags(), event.getAttributionChainId());
@@ -1231,11 +1234,13 @@ public class AppOpsService extends IAppOpsService.Stub {
*/
void onClientDeath(@NonNull IBinder clientId) {
synchronized (AppOpsService.this) {
- if (mInProgressEvents == null) {
+ if (mInProgressEvents == null && mPausedInProgressEvents == null) {
return;
}
- InProgressStartOpEvent deadEvent = mInProgressEvents.get(clientId);
+ ArrayMap<IBinder, InProgressStartOpEvent> events = isPaused()
+ ? mPausedInProgressEvents : mInProgressEvents;
+ InProgressStartOpEvent deadEvent = events.get(clientId);
if (deadEvent != null) {
deadEvent.numUnfinishedStarts = 1;
}
@@ -1250,14 +1255,18 @@ public class AppOpsService extends IAppOpsService.Stub {
* @param newState The new state
*/
public void onUidStateChanged(@AppOpsManager.UidState int newState) {
- if (mInProgressEvents == null) {
+ if (mInProgressEvents == null && mPausedInProgressEvents == null) {
return;
}
- int numInProgressEvents = mInProgressEvents.size();
- List<IBinder> binders = new ArrayList<>(mInProgressEvents.keySet());
+ boolean isRunning = isRunning();
+ ArrayMap<IBinder, AppOpsService.InProgressStartOpEvent> events =
+ isRunning ? mInProgressEvents : mPausedInProgressEvents;
+
+ int numInProgressEvents = events.size();
+ List<IBinder> binders = new ArrayList<>(events.keySet());
for (int i = 0; i < numInProgressEvents; i++) {
- InProgressStartOpEvent event = mInProgressEvents.get(binders.get(i));
+ InProgressStartOpEvent event = events.get(binders.get(i));
if (event != null && event.getUidState() != newState) {
try {
@@ -1272,16 +1281,17 @@ public class AppOpsService extends IAppOpsService.Stub {
// Call started() to add a new start event object and then add the
// previously removed unfinished start counts back
if (proxy != null) {
- started(event.getClientId(), proxy.getUid(), proxy.getPackageName(),
- proxy.getAttributionTag(), newState, event.getFlags(), false,
+ startedOrPaused(event.getClientId(), proxy.getUid(),
+ proxy.getPackageName(), proxy.getAttributionTag(), newState,
+ event.getFlags(), false, isRunning,
event.getAttributionFlags(), event.getAttributionChainId());
} else {
- started(event.getClientId(), Process.INVALID_UID, null, null, newState,
- OP_FLAG_SELF, false, event.getAttributionFlags(),
- event.getAttributionChainId());
+ startedOrPaused(event.getClientId(), Process.INVALID_UID, null, null,
+ newState, event.getFlags(), false, isRunning,
+ event.getAttributionFlags(), event.getAttributionChainId());
}
- InProgressStartOpEvent newEvent = mInProgressEvents.get(binders.get(i));
+ InProgressStartOpEvent newEvent = events.get(binders.get(i));
if (newEvent != null) {
newEvent.numUnfinishedStarts += numPreviousUnfinishedStarts - 1;
}
@@ -4551,15 +4561,15 @@ public class AppOpsService extends IAppOpsService.Stub {
}
try {
- if (mPlatformCompat.isChangeEnabledByPackageName(
+ if (!mPlatformCompat.isChangeEnabledByPackageName(
SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, packageName,
- userId) && mPlatformCompat.isChangeEnabledByUid(
+ userId) || !mPlatformCompat.isChangeEnabledByUid(
SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE,
- callingUid) && !isAttributionTagValid) {
- Slog.e(TAG, msg);
- } else {
- Slog.e(TAG, msg);
+ callingUid)) {
+ // Do not override tags if overriding is not enabled for this package
+ isAttributionTagValid = true;
}
+ Slog.e(TAG, msg);
} catch (RemoteException neverHappens) {
}
}
@@ -6494,9 +6504,9 @@ public class AppOpsService extends IAppOpsService.Stub {
int numAttrTags = op.mAttributions.size();
for (int attrNum = 0; attrNum < numAttrTags; attrNum++) {
AttributedOp attrOp = op.mAttributions.valueAt(attrNum);
- if (restricted) {
+ if (restricted && attrOp.isRunning()) {
attrOp.pause();
- } else {
+ } else if (attrOp.isPaused()) {
attrOp.resume();
}
}
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index 10cfddfb3ae4..49469cc8a597 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -26,6 +26,7 @@ import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_FLAG_SELF;
import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
+import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA;
import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE;
@@ -156,8 +157,11 @@ final class DiscreteRegistry {
private static final String ATTR_NOTE_DURATION = "nd";
private static final String ATTR_UID_STATE = "us";
private static final String ATTR_FLAGS = "f";
+ private static final String ATTR_ATTRIBUTION_FLAGS = "af";
+ private static final String ATTR_CHAIN_ID = "ci";
- private static final int OP_FLAGS_DISCRETE = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED;
+ private static final int OP_FLAGS_DISCRETE = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED
+ | OP_FLAG_TRUSTED_PROXY;
// Lock for read/write access to on disk state
private final Object mOnDiskLock = new Object();
@@ -227,13 +231,14 @@ final class DiscreteRegistry {
void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime,
- long accessDuration) {
+ long accessDuration, @AppOpsManager.AttributionFlags int attributionFlags,
+ int attributionChainId) {
if (!isDiscreteOp(op, flags)) {
return;
}
synchronized (mInMemoryLock) {
mDiscreteOps.addDiscreteAccess(op, uid, packageName, attributionTag, flags, uidState,
- accessTime, accessDuration);
+ accessTime, accessDuration, attributionFlags, attributionChainId);
}
}
@@ -383,9 +388,10 @@ final class DiscreteRegistry {
void addDiscreteAccess(int op, int uid, @NonNull String packageName,
@Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
- @AppOpsManager.UidState int uidState, long accessTime, long accessDuration) {
+ @AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags,
- uidState, accessTime, accessDuration);
+ uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
}
private void filter(long beginTimeMillis, long endTimeMillis,
@@ -613,9 +619,10 @@ final class DiscreteRegistry {
void addDiscreteAccess(int op, @NonNull String packageName, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
- long accessTime, long accessDuration) {
+ long accessTime, long accessDuration,
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
getOrCreateDiscretePackageOps(packageName).addDiscreteAccess(op, attributionTag, flags,
- uidState, accessTime, accessDuration);
+ uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
}
private DiscretePackageOps getOrCreateDiscretePackageOps(String packageName) {
@@ -680,9 +687,10 @@ final class DiscreteRegistry {
void addDiscreteAccess(int op, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
- long accessTime, long accessDuration) {
+ long accessTime, long accessDuration,
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
getOrCreateDiscreteOp(op).addDiscreteAccess(attributionTag, flags, uidState, accessTime,
- accessDuration);
+ accessDuration, attributionFlags, attributionChainId);
}
void merge(DiscretePackageOps other) {
@@ -823,37 +831,39 @@ final class DiscreteRegistry {
for (int j = 0; j < n; j++) {
DiscreteOpEvent event = list.get(j);
list.set(j, new DiscreteOpEvent(event.mNoteTime - offset, event.mNoteDuration,
- event.mUidState, event.mOpFlag));
+ event.mUidState, event.mOpFlag, event.mAttributionFlags,
+ event.mAttributionChainId));
}
}
}
void addDiscreteAccess(@Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
- long accessTime, long accessDuration) {
+ long accessTime, long accessDuration,
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
List<DiscreteOpEvent> attributedOps = getOrCreateDiscreteOpEventsList(
attributionTag);
- accessTime = accessTime / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
- accessDuration = accessDuration == -1 ? -1
- : (accessDuration + sDiscreteHistoryQuantization - 1)
- / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
int nAttributedOps = attributedOps.size();
int i = nAttributedOps;
for (; i > 0; i--) {
DiscreteOpEvent previousOp = attributedOps.get(i - 1);
- if (previousOp.mNoteTime < accessTime) {
+ if (discretizeTimeStamp(previousOp.mNoteTime) < discretizeTimeStamp(accessTime)) {
break;
}
- if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState) {
- if (accessDuration != previousOp.mNoteDuration) {
+ if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState
+ && previousOp.mAttributionFlags == attributionFlags
+ && previousOp.mAttributionChainId == attributionChainId) {
+ if (discretizeDuration(accessDuration) != discretizeDuration(
+ previousOp.mNoteDuration)) {
break;
} else {
return;
}
}
}
- attributedOps.add(i, new DiscreteOpEvent(accessTime, accessDuration, uidState, flags));
+ attributedOps.add(i, new DiscreteOpEvent(accessTime, accessDuration, uidState, flags,
+ attributionFlags, attributionChainId));
}
private List<DiscreteOpEvent> getOrCreateDiscreteOpEventsList(String attributionTag) {
@@ -875,7 +885,8 @@ final class DiscreteRegistry {
for (int j = 0; j < nEvents; j++) {
DiscreteOpEvent event = events.get(j);
result.addDiscreteAccess(op, uid, packageName, tag, event.mUidState,
- event.mOpFlag, event.mNoteTime, event.mNoteDuration);
+ event.mOpFlag, discretizeTimeStamp(event.mNoteTime),
+ discretizeDuration(event.mNoteDuration));
}
}
}
@@ -932,11 +943,15 @@ final class DiscreteRegistry {
-1);
int uidState = parser.getAttributeInt(null, ATTR_UID_STATE);
int opFlags = parser.getAttributeInt(null, ATTR_FLAGS);
+ int attributionFlags = parser.getAttributeInt(null,
+ ATTR_ATTRIBUTION_FLAGS, AppOpsManager.ATTRIBUTION_FLAGS_NONE);
+ int attributionChainId = parser.getAttributeInt(null, ATTR_CHAIN_ID,
+ AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
if (noteTime + noteDuration < beginTimeMillis) {
continue;
}
DiscreteOpEvent event = new DiscreteOpEvent(noteTime, noteDuration,
- uidState, opFlags);
+ uidState, opFlags, attributionFlags, attributionChainId);
events.add(event);
}
}
@@ -952,13 +967,18 @@ final class DiscreteRegistry {
final long mNoteDuration;
final @AppOpsManager.UidState int mUidState;
final @AppOpsManager.OpFlags int mOpFlag;
+ final @AppOpsManager.AttributionFlags int mAttributionFlags;
+ final int mAttributionChainId;
DiscreteOpEvent(long noteTime, long noteDuration, @AppOpsManager.UidState int uidState,
- @AppOpsManager.OpFlags int opFlag) {
+ @AppOpsManager.OpFlags int opFlag,
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
mNoteTime = noteTime;
mNoteDuration = noteDuration;
mUidState = uidState;
mOpFlag = opFlag;
+ mAttributionFlags = attributionFlags;
+ mAttributionChainId = attributionChainId;
}
private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
@@ -969,13 +989,19 @@ final class DiscreteRegistry {
pw.print("-");
pw.print(flagsToString(mOpFlag));
pw.print("] at ");
- date.setTime(mNoteTime);
+ date.setTime(discretizeTimeStamp(mNoteTime));
pw.print(sdf.format(date));
if (mNoteDuration != -1) {
pw.print(" for ");
- pw.print(mNoteDuration);
+ pw.print(discretizeDuration(mNoteDuration));
pw.print(" milliseconds ");
}
+ if (mAttributionFlags != AppOpsManager.ATTRIBUTION_FLAGS_NONE) {
+ pw.print(" attribution flags=");
+ pw.print(mAttributionFlags);
+ pw.print(" with chainId=");
+ pw.print(mAttributionChainId);
+ }
pw.println();
}
@@ -984,6 +1010,12 @@ final class DiscreteRegistry {
if (mNoteDuration != -1) {
out.attributeLong(null, ATTR_NOTE_DURATION, mNoteDuration);
}
+ if (mAttributionFlags != AppOpsManager.ATTRIBUTION_FLAGS_NONE) {
+ out.attributeInt(null, ATTR_ATTRIBUTION_FLAGS, mAttributionFlags);
+ }
+ if (mAttributionChainId != AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE) {
+ out.attributeInt(null, ATTR_CHAIN_ID, mAttributionChainId);
+ }
out.attributeInt(null, ATTR_UID_STATE, mUidState);
out.attributeInt(null, ATTR_FLAGS, mOpFlag);
}
@@ -1055,6 +1087,16 @@ final class DiscreteRegistry {
return true;
}
+ private static long discretizeTimeStamp(long timeStamp) {
+ return timeStamp / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
+
+ }
+
+ private static long discretizeDuration(long duration) {
+ return duration == -1 ? -1 : (duration + sDiscreteHistoryQuantization - 1)
+ / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
+ }
+
void setDebugMode(boolean debugMode) {
this.mDebugMode = debugMode;
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 8b72be78a7f6..dd5df503d936 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -487,7 +487,8 @@ final class HistoricalRegistry {
void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
@Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
- long accessTime) {
+ long accessTime, @AppOpsManager.AttributionFlags int attributionFlags,
+ int attributionChainId) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) {
@@ -499,7 +500,7 @@ final class HistoricalRegistry {
attributionTag, uidState, flags, 1);
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, op, attributionTag,
- flags, uidState, accessTime, -1);
+ flags, uidState, accessTime, -1, attributionFlags, attributionChainId);
}
}
}
@@ -521,7 +522,8 @@ final class HistoricalRegistry {
void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
@Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
- long eventStartTime, long increment) {
+ long eventStartTime, long increment,
+ @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) {
@@ -532,7 +534,8 @@ final class HistoricalRegistry {
System.currentTimeMillis()).increaseAccessDuration(op, uid, packageName,
attributionTag, uidState, flags, increment);
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, op, attributionTag,
- flags, uidState, eventStartTime, increment);
+ flags, uidState, eventStartTime, increment, attributionFlags,
+ attributionChainId);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
index 0ba731ee8b4b..cb966e7b47a9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -59,11 +59,13 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det
@Override
protected void stopHalOperation() {
- try {
- mCancellationSignal.cancel();
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception", e);
- mCallback.onClientFinished(this, false /* success */);
+ if (mCancellationSignal != null) {
+ try {
+ mCancellationSignal.cancel();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ mCallback.onClientFinished(this, false /* success */);
+ }
}
}
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 909ed11e9d69..6dca00191b24 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -235,13 +235,11 @@ final class CompatConfig {
* @param packageName app for which the overrides will be applied.
*/
void addOverrides(CompatibilityOverrideConfig overrides, String packageName) {
- synchronized (mChanges) {
- for (Long changeId : overrides.overrides.keySet()) {
- addOverrideUnsafe(changeId, packageName, overrides.overrides.get(changeId));
- }
- saveOverrides();
- invalidateCache();
+ for (Long changeId : overrides.overrides.keySet()) {
+ addOverrideUnsafe(changeId, packageName, overrides.overrides.get(changeId));
}
+ saveOverrides();
+ invalidateCache();
}
private boolean addOverrideUnsafe(long changeId, String packageName,
@@ -335,27 +333,38 @@ final class CompatConfig {
/**
* Unsafe version of {@link #removeOverride(long, String)}.
- * It does not invalidate the cache nor save the overrides.
+ * It does not save the overrides.
*/
private boolean removeOverrideUnsafe(long changeId, String packageName) {
Long versionCode = getVersionCodeOrNull(packageName);
synchronized (mChanges) {
CompatChange c = mChanges.get(changeId);
if (c != null) {
- OverrideAllowedState allowedState =
- mOverrideValidator.getOverrideAllowedState(changeId, packageName);
- if (c.hasPackageOverride(packageName)) {
- allowedState.enforce(changeId, packageName);
- c.removePackageOverride(packageName, allowedState, versionCode);
- invalidateCache();
- return true;
- }
+ return removeOverrideUnsafe(c, packageName, versionCode);
}
}
return false;
}
/**
+ * Similar to {@link #removeOverrideUnsafe(long, String)} except this method receives a {@link
+ * CompatChange} directly as well as the package's version code.
+ */
+ private boolean removeOverrideUnsafe(CompatChange change, String packageName,
+ @Nullable Long versionCode) {
+ long changeId = change.getId();
+ OverrideAllowedState allowedState =
+ mOverrideValidator.getOverrideAllowedState(changeId, packageName);
+ if (change.hasPackageOverride(packageName)) {
+ allowedState.enforce(changeId, packageName);
+ change.removePackageOverride(packageName, allowedState, versionCode);
+ invalidateCache();
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Removes all overrides previously added via {@link #addOverride(long, String, boolean)} or
* {@link #addOverrides(CompatibilityOverrideConfig, String)} for a certain package.
*
@@ -364,10 +373,11 @@ final class CompatConfig {
* @param packageName the package for which the overrides should be purged
*/
void removePackageOverrides(String packageName) {
+ Long versionCode = getVersionCodeOrNull(packageName);
synchronized (mChanges) {
for (int i = 0; i < mChanges.size(); ++i) {
CompatChange change = mChanges.valueAt(i);
- removeOverrideUnsafe(change.getId(), packageName);
+ removeOverrideUnsafe(change, packageName, versionCode);
}
saveOverrides();
invalidateCache();
@@ -386,13 +396,11 @@ final class CompatConfig {
*/
void removePackageOverrides(CompatibilityOverridesToRemoveConfig overridesToRemove,
String packageName) {
- synchronized (mChanges) {
- for (Long changeId : overridesToRemove.changeIds) {
- removeOverrideUnsafe(changeId, packageName);
- }
- saveOverrides();
- invalidateCache();
+ for (Long changeId : overridesToRemove.changeIds) {
+ removeOverrideUnsafe(changeId, packageName);
}
+ saveOverrides();
+ invalidateCache();
}
private long[] getAllowedChangesSinceTargetSdkForPackage(String packageName,
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 2cd68b086453..19e858c25c41 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -91,15 +91,17 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void reportChange(long changeId, ApplicationInfo appInfo) {
- reportChangeByUid(changeId, appInfo.uid);
+ checkCompatChangeLogPermission();
+ reportChangeInternal(changeId, appInfo.uid, ChangeReporter.STATE_LOGGED);
}
@Override
public void reportChangeByPackageName(long changeId, String packageName,
@UserIdInt int userId) {
+ checkCompatChangeLogPermission();
ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
if (appInfo != null) {
- reportChangeByUid(changeId, appInfo.uid);
+ reportChangeInternal(changeId, appInfo.uid, ChangeReporter.STATE_LOGGED);
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 13b7ebc47301..fe5ee78bca31 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -512,6 +512,8 @@ public final class DisplayManagerService extends SystemService {
}
}
}
+ } else if (phase == PHASE_BOOT_COMPLETED) {
+ mDisplayModeDirector.onBootCompleted();
}
}
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 997f0e5aa70c..07d13c251f26 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -155,7 +155,6 @@ public class DisplayModeDirector {
mSettingsObserver.observe();
mDisplayObserver.observe();
mBrightnessObserver.observe(sensorManager);
- mUdfpsObserver.observe();
synchronized (mLock) {
// We may have a listener already registered before the call to start, so go ahead and
// notify them to pick up our newly initialized state.
@@ -163,6 +162,16 @@ public class DisplayModeDirector {
}
}
+ /**
+ * Same as {@link #start(SensorManager)}, but for observers that need to be delayed even more,
+ * for example until SystemUI is ready.
+ */
+ public void onBootCompleted() {
+ // UDFPS observer registers a listener with SystemUI which might not be ready until the
+ // system is fully booted.
+ mUdfpsObserver.observe();
+ }
+
public void setLoggingEnabled(boolean loggingEnabled) {
if (mLoggingEnabled == loggingEnabled) {
return;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index c14acd7b60d7..1b50f0388f9d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -365,7 +365,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
@Nullable
private final ColorDisplayServiceInternal mCdsi;
- private final float[] mNitsRange;
+ private float[] mNitsRange;
private final HighBrightnessModeController mHbmController;
@@ -447,6 +447,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mLogicalDisplay = logicalDisplay;
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
+ mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
mHandler = new DisplayControllerHandler(handler.getLooper());
if (mDisplayId == Display.DEFAULT_DISPLAY) {
@@ -462,6 +463,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBlanker = blanker;
mContext = context;
mBrightnessTracker = brightnessTracker;
+ // TODO: b/186428377 update brightness setting when display changes
mBrightnessSetting = brightnessSetting;
mOnBrightnessChangeRunnable = onBrightnessChangeRunnable;
@@ -498,13 +500,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
+ mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
+ .getDisplayDeviceConfig();
- mDisplayDeviceConfig = logicalDisplay
- .getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig();
- mBrightnessRampRateFastDecrease = mDisplayDeviceConfig.getBrightnessRampFastDecrease();
- mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease();
- mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease();
- mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease();
+ loadBrightnessRampRates();
mSkipScreenOnBrightnessRamp = resources.getBoolean(
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
@@ -513,66 +512,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Seed the cached brightness
saveBrightnessInfo(getScreenBrightnessSetting());
- if (mUseSoftwareAutoBrightnessConfig) {
- final float dozeScaleFactor = resources.getFraction(
- com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
- 1, 1);
-
- int[] ambientBrighteningThresholds = resources.getIntArray(
- com.android.internal.R.array.config_ambientBrighteningThresholds);
- int[] ambientDarkeningThresholds = resources.getIntArray(
- com.android.internal.R.array.config_ambientDarkeningThresholds);
- int[] ambientThresholdLevels = resources.getIntArray(
- com.android.internal.R.array.config_ambientThresholdLevels);
- HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
- ambientBrighteningThresholds, ambientDarkeningThresholds,
- ambientThresholdLevels);
-
- int[] screenBrighteningThresholds = resources.getIntArray(
- com.android.internal.R.array.config_screenBrighteningThresholds);
- int[] screenDarkeningThresholds = resources.getIntArray(
- com.android.internal.R.array.config_screenDarkeningThresholds);
- int[] screenThresholdLevels = resources.getIntArray(
- com.android.internal.R.array.config_screenThresholdLevels);
- HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
- screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels);
-
- long brighteningLightDebounce = resources.getInteger(
- com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
- long darkeningLightDebounce = resources.getInteger(
- com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
- boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
- com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
-
- int lightSensorWarmUpTimeConfig = resources.getInteger(
- com.android.internal.R.integer.config_lightSensorWarmupTime);
- int lightSensorRate = resources.getInteger(
- com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
- int initialLightSensorRate = resources.getInteger(
- com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
- if (initialLightSensorRate == -1) {
- initialLightSensorRate = lightSensorRate;
- } else if (initialLightSensorRate > lightSensorRate) {
- Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
- + initialLightSensorRate + ") to be less than or equal to "
- + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
- }
-
- loadAmbientLightSensor();
-
- mBrightnessMapper = BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig);
- if (mBrightnessMapper != null) {
- mAutomaticBrightnessController = new AutomaticBrightnessController(this,
- handler.getLooper(), sensorManager, mLightSensor, mBrightnessMapper,
- lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate,
- initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
- autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
- screenBrightnessThresholds, logicalDisplay, context, mHbmController);
- } else {
- mUseSoftwareAutoBrightnessConfig = false;
- }
- }
+ setUpAutoBrightness(resources, handler);
mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();
mColorFadeFadesConfig = resources.getBoolean(
@@ -610,13 +550,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings;
mDisplayWhiteBalanceController = displayWhiteBalanceController;
- if (mDisplayDeviceConfig != null && mDisplayDeviceConfig.getNits() != null) {
- mNitsRange = mDisplayDeviceConfig.getNits();
- } else {
- Slog.w(TAG, "Screen brightness nits configuration is unavailable; falling back");
- mNitsRange = BrightnessMappingStrategy.getFloatArray(context.getResources()
- .obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits));
- }
+ loadNitsRange(resources);
+
if (mDisplayId == Display.DEFAULT_DISPLAY) {
mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class);
boolean active = mCdsi.setReduceBrightColorsListener(new ReduceBrightColorsListener() {
@@ -802,10 +737,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mDisplayDevice = device;
mUniqueDisplayId = uniqueId;
mDisplayDeviceConfig = config;
-
- loadAmbientLightSensor();
- loadProximitySensor();
- mHbmController.resetHbmData(token, config.getHighBrightnessModeData());
+ loadFromDisplayDeviceConfig(token);
});
}
@@ -846,6 +778,18 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
+ private void loadFromDisplayDeviceConfig(IBinder token) {
+ // All properties that depend on the associated DisplayDevice and the DDC must be
+ // updated here.
+ loadAmbientLightSensor();
+ loadBrightnessRampRates();
+ loadProximitySensor();
+ loadNitsRange(mContext.getResources());
+ setUpAutoBrightness(mContext.getResources(), mHandler);
+ reloadReduceBrightColours();
+ mHbmController.resetHbmData(token, mDisplayDeviceConfig.getHighBrightnessModeData());
+ }
+
private void sendUpdatePowerState() {
synchronized (mLock) {
sendUpdatePowerStateLocked();
@@ -903,6 +847,98 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
}
+ private void setUpAutoBrightness(Resources resources, Handler handler) {
+ if (!mUseSoftwareAutoBrightnessConfig) {
+ return;
+ }
+
+ mBrightnessMapper = BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig);
+
+ if (mBrightnessMapper != null) {
+ final float dozeScaleFactor = resources.getFraction(
+ com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
+ 1, 1);
+
+ int[] ambientBrighteningThresholds = resources.getIntArray(
+ com.android.internal.R.array.config_ambientBrighteningThresholds);
+ int[] ambientDarkeningThresholds = resources.getIntArray(
+ com.android.internal.R.array.config_ambientDarkeningThresholds);
+ int[] ambientThresholdLevels = resources.getIntArray(
+ com.android.internal.R.array.config_ambientThresholdLevels);
+ HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
+ ambientBrighteningThresholds, ambientDarkeningThresholds,
+ ambientThresholdLevels);
+
+ int[] screenBrighteningThresholds = resources.getIntArray(
+ com.android.internal.R.array.config_screenBrighteningThresholds);
+ int[] screenDarkeningThresholds = resources.getIntArray(
+ com.android.internal.R.array.config_screenDarkeningThresholds);
+ int[] screenThresholdLevels = resources.getIntArray(
+ com.android.internal.R.array.config_screenThresholdLevels);
+ HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
+ screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels);
+
+ long brighteningLightDebounce = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
+ long darkeningLightDebounce = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
+ boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
+ com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
+
+ int lightSensorWarmUpTimeConfig = resources.getInteger(
+ com.android.internal.R.integer.config_lightSensorWarmupTime);
+ int lightSensorRate = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
+ int initialLightSensorRate = resources.getInteger(
+ com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
+ if (initialLightSensorRate == -1) {
+ initialLightSensorRate = lightSensorRate;
+ } else if (initialLightSensorRate > lightSensorRate) {
+ Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
+ + initialLightSensorRate + ") to be less than or equal to "
+ + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
+ }
+
+ loadAmbientLightSensor();
+
+ if (mAutomaticBrightnessController != null) {
+ mAutomaticBrightnessController.stop();
+ }
+ mAutomaticBrightnessController = new AutomaticBrightnessController(this,
+ handler.getLooper(), mSensorManager, mLightSensor, mBrightnessMapper,
+ lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN,
+ PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate,
+ initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
+ autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
+ screenBrightnessThresholds, mLogicalDisplay, mContext, mHbmController);
+ } else {
+ mUseSoftwareAutoBrightnessConfig = false;
+ }
+ }
+
+ private void loadBrightnessRampRates() {
+ mBrightnessRampRateFastDecrease = mDisplayDeviceConfig.getBrightnessRampFastDecrease();
+ mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease();
+ mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease();
+ mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease();
+ }
+
+ private void loadNitsRange(Resources resources) {
+ if (mDisplayDeviceConfig != null && mDisplayDeviceConfig.getNits() != null) {
+ mNitsRange = mDisplayDeviceConfig.getNits();
+ } else {
+ Slog.w(TAG, "Screen brightness nits configuration is unavailable; falling back");
+ mNitsRange = BrightnessMappingStrategy.getFloatArray(resources
+ .obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits));
+ }
+ }
+
+ private void reloadReduceBrightColours() {
+ if (mCdsi != null && mCdsi.isReduceBrightColorsActivated()) {
+ applyReduceBrightColorsSplineAdjustment();
+ }
+ }
+
private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java
index 6db75eb80aea..a7e1a2876f81 100644
--- a/services/core/java/com/android/server/display/WifiDisplayController.java
+++ b/services/core/java/com/android/server/display/WifiDisplayController.java
@@ -550,11 +550,6 @@ final class WifiDisplayController implements DumpUtils.Dump {
private void disconnect() {
mDesiredDevice = null;
- mWifiP2pManager = null;
- if (null != mWifiP2pChannel) {
- mWifiP2pChannel.close();
- mWifiP2pChannel = null;
- }
updateConnection();
}
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index b9e97e89051b..aeb1893c78b6 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -65,7 +65,7 @@ import android.location.LastLocationRequest;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationManagerInternal;
-import android.location.LocationManagerInternal.OnProviderLocationTagsChangeListener;
+import android.location.LocationManagerInternal.LocationPackageTagsListener;
import android.location.LocationProvider;
import android.location.LocationRequest;
import android.location.LocationTime;
@@ -93,6 +93,7 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
+import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.location.eventlog.LocationEventLog;
@@ -259,7 +260,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
new CopyOnWriteArrayList<>();
@GuardedBy("mLock")
- @Nullable OnProviderLocationTagsChangeListener mOnProviderLocationTagsChangeListener;
+ @Nullable LocationPackageTagsListener mLocationTagsChangedListener;
LocationManagerService(Context context, Injector injector) {
mContext = context.createAttributionContext(ATTRIBUTION_TAG);
@@ -1363,32 +1364,28 @@ public class LocationManagerService extends ILocationManager.Stub implements
refreshAppOpsRestrictions(UserHandle.USER_ALL);
}
- OnProviderLocationTagsChangeListener listener;
- synchronized (mLock) {
- listener = mOnProviderLocationTagsChangeListener;
- }
-
- if (listener != null) {
- if (!oldState.extraAttributionTags.equals(newState.extraAttributionTags)
- || !Objects.equals(oldState.identity, newState.identity)) {
- if (oldState.identity != null) {
- listener.onLocationTagsChanged(
- new LocationManagerInternal.LocationTagInfo(
- oldState.identity.getUid(),
- oldState.identity.getPackageName(),
- Collections.emptySet()));
- }
- if (newState.identity != null) {
- ArraySet<String> attributionTags = new ArraySet<>(
- newState.extraAttributionTags.size() + 1);
- attributionTags.addAll(newState.extraAttributionTags);
- attributionTags.add(newState.identity.getAttributionTag());
-
- listener.onLocationTagsChanged(
- new LocationManagerInternal.LocationTagInfo(
- newState.identity.getUid(),
- newState.identity.getPackageName(),
- attributionTags));
+ if (!oldState.extraAttributionTags.equals(newState.extraAttributionTags)
+ || !Objects.equals(oldState.identity, newState.identity)) {
+ // since we're potentially affecting the tag lists for two different uids, acquire the
+ // lock to ensure providers cannot change while we're looping over the providers
+ // multiple times, which could lead to inconsistent results.
+ synchronized (mLock) {
+ LocationPackageTagsListener listener = mLocationTagsChangedListener;
+ if (listener != null) {
+ int oldUid = oldState.identity != null ? oldState.identity.getUid() : -1;
+ int newUid = newState.identity != null ? newState.identity.getUid() : -1;
+ if (oldUid != -1) {
+ PackageTagsList tags = calculateAppOpsLocationSourceTags(oldUid);
+ FgThread.getHandler().post(
+ () -> listener.onLocationPackageTagsChanged(oldUid, tags));
+ }
+ // if the new app id is the same as the old app id, no need to invoke the
+ // listener twice, it's already been taken care of
+ if (newUid != -1 && newUid != oldUid) {
+ PackageTagsList tags = calculateAppOpsLocationSourceTags(newUid);
+ FgThread.getHandler().post(
+ () -> listener.onLocationPackageTagsChanged(newUid, tags));
+ }
}
}
}
@@ -1436,6 +1433,31 @@ public class LocationManagerService extends ILocationManager.Stub implements
userId);
}
+ PackageTagsList calculateAppOpsLocationSourceTags(int uid) {
+ PackageTagsList.Builder builder = new PackageTagsList.Builder();
+ for (LocationProviderManager manager : mProviderManagers) {
+ AbstractLocationProvider.State managerState = manager.getState();
+ if (managerState.identity == null) {
+ continue;
+ }
+ if (managerState.identity.getUid() != uid) {
+ continue;
+ }
+
+ builder.add(managerState.identity.getPackageName(), managerState.extraAttributionTags);
+ if (managerState.extraAttributionTags.isEmpty()
+ || managerState.identity.getAttributionTag() != null) {
+ builder.add(managerState.identity.getPackageName(),
+ managerState.identity.getAttributionTag());
+ } else {
+ Log.e(TAG, manager.getName() + " provider has specified a null attribution tag and "
+ + "a non-empty set of extra attribution tags - dropping the null "
+ + "attribution tag");
+ }
+ }
+ return builder.build();
+ }
+
private class LocalService extends LocationManagerInternal {
LocalService() {}
@@ -1506,10 +1528,29 @@ public class LocationManagerService extends ILocationManager.Stub implements
}
@Override
- public void setOnProviderLocationTagsChangeListener(
- @Nullable OnProviderLocationTagsChangeListener listener) {
+ public void setLocationPackageTagsListener(
+ @Nullable LocationPackageTagsListener listener) {
synchronized (mLock) {
- mOnProviderLocationTagsChangeListener = listener;
+ mLocationTagsChangedListener = listener;
+
+ // calculate initial tag list and send to listener
+ if (listener != null) {
+ ArraySet<Integer> uids = new ArraySet<>(mProviderManagers.size());
+ for (LocationProviderManager manager : mProviderManagers) {
+ CallerIdentity identity = manager.getIdentity();
+ if (identity != null) {
+ uids.add(identity.getUid());
+ }
+ }
+
+ for (int uid : uids) {
+ PackageTagsList tags = calculateAppOpsLocationSourceTags(uid);
+ if (!tags.isEmpty()) {
+ FgThread.getHandler().post(
+ () -> listener.onLocationPackageTagsChanged(uid, tags));
+ }
+ }
+ }
}
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java b/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java
index 5ec85e661b98..6931baa948a1 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubShellCommand.java
@@ -32,16 +32,18 @@ public class ContextHubShellCommand extends ShellCommand {
// Internal service impl -- must perform security checks before touching.
private final ContextHubService mInternal;
+ private final Context mContext;
public ContextHubShellCommand(Context context, ContextHubService service) {
mInternal = service;
-
- context.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_CONTEXT_HUB, "ContextHubShellCommand");
+ mContext = context;
}
@Override
public int onCommand(String cmd) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_CONTEXT_HUB, "ContextHubShellCommand");
+
if ("deny".equals(cmd)) {
return runDisableAuth();
}
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index 66b23c4d7377..e6d25ece93ef 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -33,7 +33,6 @@ import android.annotation.Nullable;
import android.location.LocationRequest;
import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
-import android.os.Build;
import android.os.PowerManager.LocationPowerSaveMode;
import android.os.SystemClock;
import android.util.ArrayMap;
@@ -47,8 +46,8 @@ public class LocationEventLog extends LocalEventLog {
public static final LocationEventLog EVENT_LOG = new LocationEventLog();
private static int getLogSize() {
- if (Build.IS_DEBUGGABLE || D) {
- return 500;
+ if (D) {
+ return 600;
} else {
return 200;
}
@@ -152,7 +151,7 @@ public class LocationEventLog extends LocalEventLog {
/** Logs a client for a location provider entering the foreground state. */
public void logProviderClientForeground(String provider, CallerIdentity identity) {
- if (Build.IS_DEBUGGABLE || D) {
+ if (D) {
addLogEvent(EVENT_PROVIDER_CLIENT_FOREGROUND, provider, identity);
}
getAggregateStats(provider, identity).markRequestForeground();
@@ -160,7 +159,7 @@ public class LocationEventLog extends LocalEventLog {
/** Logs a client for a location provider leaving the foreground state. */
public void logProviderClientBackground(String provider, CallerIdentity identity) {
- if (Build.IS_DEBUGGABLE || D) {
+ if (D) {
addLogEvent(EVENT_PROVIDER_CLIENT_BACKGROUND, provider, identity);
}
getAggregateStats(provider, identity).markRequestBackground();
@@ -168,14 +167,14 @@ public class LocationEventLog extends LocalEventLog {
/** Logs a client for a location provider entering the permitted state. */
public void logProviderClientPermitted(String provider, CallerIdentity identity) {
- if (Build.IS_DEBUGGABLE || D) {
+ if (D) {
addLogEvent(EVENT_PROVIDER_CLIENT_PERMITTED, provider, identity);
}
}
/** Logs a client for a location provider leaving the permitted state. */
public void logProviderClientUnpermitted(String provider, CallerIdentity identity) {
- if (Build.IS_DEBUGGABLE || D) {
+ if (D) {
addLogEvent(EVENT_PROVIDER_CLIENT_UNPERMITTED, provider, identity);
}
}
@@ -187,7 +186,7 @@ public class LocationEventLog extends LocalEventLog {
/** Logs a new incoming location for a location provider. */
public void logProviderReceivedLocations(String provider, int numLocations) {
- if (Build.IS_DEBUGGABLE || D) {
+ if (D) {
addLogEvent(EVENT_PROVIDER_RECEIVE_LOCATION, provider, numLocations);
}
}
@@ -195,7 +194,7 @@ public class LocationEventLog extends LocalEventLog {
/** Logs a location deliver for a client of a location provider. */
public void logProviderDeliveredLocations(String provider, int numLocations,
CallerIdentity identity) {
- if (Build.IS_DEBUGGABLE || D) {
+ if (D) {
addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity);
}
getAggregateStats(provider, identity).markLocationDelivered();
diff --git a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java
index 1da45bd49767..eb7b77a2234f 100644
--- a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java
@@ -263,10 +263,10 @@ public abstract class AbstractLocationProvider {
}
/**
- * The current allowed state of this provider.
+ * The current state of the provider.
*/
- public final boolean isAllowed() {
- return mInternalState.get().state.allowed;
+ public final State getState() {
+ return mInternalState.get().state;
}
/**
@@ -277,13 +277,6 @@ public abstract class AbstractLocationProvider {
}
/**
- * The current provider properties of this provider.
- */
- public final @Nullable ProviderProperties getProperties() {
- return mInternalState.get().state.properties;
- }
-
- /**
* Call this method to report a change in provider properties.
*/
protected void setProperties(@Nullable ProviderProperties properties) {
@@ -291,13 +284,6 @@ public abstract class AbstractLocationProvider {
}
/**
- * The current identity of this provider.
- */
- public final @Nullable CallerIdentity getIdentity() {
- return mInternalState.get().state.identity;
- }
-
- /**
* Call this method to report a change in the provider's identity.
*/
protected void setIdentity(@Nullable CallerIdentity identity) {
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 4f8b87b51294..8d335b83d99c 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -1407,12 +1407,16 @@ public class LocationProviderManager extends
return mName;
}
+ public AbstractLocationProvider.State getState() {
+ return mProvider.getState();
+ }
+
public @Nullable CallerIdentity getIdentity() {
- return mProvider.getIdentity();
+ return mProvider.getState().identity;
}
public @Nullable ProviderProperties getProperties() {
- return mProvider.getProperties();
+ return mProvider.getState().properties;
}
public boolean hasProvider() {
@@ -2403,7 +2407,7 @@ public class LocationProviderManager extends
Preconditions.checkArgument(userId >= 0);
boolean enabled = mState == STATE_STARTED
- && mProvider.isAllowed()
+ && mProvider.getState().allowed
&& mSettingsHelper.isLocationEnabled(userId);
int index = mEnabled.indexOfKey(userId);
diff --git a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java
index 021e8dbdb44e..22295fe7ba28 100644
--- a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java
@@ -21,9 +21,7 @@ import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import android.annotation.Nullable;
import android.location.Location;
import android.location.LocationResult;
-import android.location.provider.ProviderProperties;
import android.location.provider.ProviderRequest;
-import android.location.util.identity.CallerIdentity;
import android.os.Bundle;
import com.android.internal.annotations.GuardedBy;
@@ -32,7 +30,6 @@ import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collections;
-import java.util.Set;
/**
* Represents a location provider that may switch between a mock implementation and a real
@@ -290,21 +287,21 @@ public class MockableLocationProvider extends AbstractLocationProvider {
Preconditions.checkState(!Thread.holdsLock(mOwnerLock));
AbstractLocationProvider provider;
+ State providerState;
synchronized (mOwnerLock) {
provider = mProvider;
- pw.println("allowed=" + isAllowed());
- CallerIdentity identity = getIdentity();
- if (identity != null) {
- pw.println("identity=" + identity);
- }
- Set<String> extraAttributionTags = getExtraAttributionTags();
- if (!extraAttributionTags.isEmpty()) {
- pw.println("extra attribution tags=" + extraAttributionTags);
- }
- ProviderProperties properties = getProperties();
- if (properties != null) {
- pw.println("properties=" + properties);
- }
+ providerState = getState();
+ }
+
+ pw.println("allowed=" + providerState.allowed);
+ if (providerState.identity != null) {
+ pw.println("identity=" + providerState.identity);
+ }
+ if (!providerState.extraAttributionTags.isEmpty()) {
+ pw.println("extra attribution tags=" + providerState.extraAttributionTags);
+ }
+ if (providerState.properties != null) {
+ pw.println("properties=" + providerState.properties);
}
if (provider != null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5b5d5d403cb7..a3f3a3a503c8 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2661,8 +2661,10 @@ public class NotificationManagerService extends SystemService {
mRoleObserver = roleObserver;
LauncherApps launcherApps =
(LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
+ UserManager userManager = (UserManager) getContext().getSystemService(
+ Context.USER_SERVICE);
mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener, getLocalService(
- ShortcutServiceInternal.class));
+ ShortcutServiceInternal.class), userManager);
BubbleExtractor bubbsExtractor = mRankingHelper.findExtractor(BubbleExtractor.class);
if (bubbsExtractor != null) {
bubbsExtractor.setShortcutHelper(mShortcutHelper);
@@ -4783,7 +4785,7 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
+ public String addAutomaticZenRule(AutomaticZenRule automaticZenRule, String pkg) {
Objects.requireNonNull(automaticZenRule, "automaticZenRule is null");
Objects.requireNonNull(automaticZenRule.getName(), "Name is null");
if (automaticZenRule.getOwner() == null
@@ -4792,6 +4794,7 @@ public class NotificationManagerService extends SystemService {
"Rule must have a conditionproviderservice and/or configuration activity");
}
Objects.requireNonNull(automaticZenRule.getConditionId(), "ConditionId is null");
+ checkCallerIsSameApp(pkg);
if (automaticZenRule.getZenPolicy() != null
&& automaticZenRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) {
throw new IllegalArgumentException("ZenPolicy is only applicable to "
@@ -4799,7 +4802,7 @@ public class NotificationManagerService extends SystemService {
}
enforcePolicyAccess(Binder.getCallingUid(), "addAutomaticZenRule");
- return mZenModeHelper.addAutomaticZenRule(automaticZenRule,
+ return mZenModeHelper.addAutomaticZenRule(pkg, automaticZenRule,
"addAutomaticZenRule");
}
diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java
index b0be20698005..fc106b8ec4ac 100644
--- a/services/core/java/com/android/server/notification/ShortcutHelper.java
+++ b/services/core/java/com/android/server/notification/ShortcutHelper.java
@@ -29,6 +29,7 @@ import android.content.pm.ShortcutServiceInternal;
import android.os.Binder;
import android.os.Handler;
import android.os.UserHandle;
+import android.os.UserManager;
import android.text.TextUtils;
import android.util.Slog;
@@ -67,6 +68,7 @@ public class ShortcutHelper {
private LauncherApps mLauncherAppsService;
private ShortcutListener mShortcutListener;
private ShortcutServiceInternal mShortcutServiceInternal;
+ private UserManager mUserManager;
// Key: packageName Value: <shortcutId, notifId>
private HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
@@ -144,10 +146,11 @@ public class ShortcutHelper {
};
ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener,
- ShortcutServiceInternal shortcutServiceInternal) {
+ ShortcutServiceInternal shortcutServiceInternal, UserManager userManager) {
mLauncherAppsService = launcherApps;
mShortcutListener = listener;
mShortcutServiceInternal = shortcutServiceInternal;
+ mUserManager = userManager;
}
@VisibleForTesting
@@ -160,6 +163,11 @@ public class ShortcutHelper {
mShortcutServiceInternal = shortcutServiceInternal;
}
+ @VisibleForTesting
+ void setUserManager(UserManager userManager) {
+ mUserManager = userManager;
+ }
+
/**
* Returns whether the given shortcut info is a conversation shortcut.
*/
@@ -182,7 +190,8 @@ public class ShortcutHelper {
* Only returns shortcut info if it's found and if it's a conversation shortcut.
*/
ShortcutInfo getValidShortcutInfo(String shortcutId, String packageName, UserHandle user) {
- if (mLauncherAppsService == null) {
+ // Shortcuts cannot be accessed when the user is locked.
+ if (mLauncherAppsService == null || !mUserManager.isUserUnlocked(user)) {
return null;
}
final long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 4cb6c3ba20d8..a98f113a9d57 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -307,7 +307,8 @@ public class ZenModeHelper {
return null;
}
- public String addAutomaticZenRule(AutomaticZenRule automaticZenRule, String reason) {
+ public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule,
+ String reason) {
if (!isSystemRule(automaticZenRule)) {
PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner());
if (component == null) {
@@ -340,7 +341,7 @@ public class ZenModeHelper {
}
newConfig = mConfig.copy();
ZenRule rule = new ZenRule();
- populateZenRule(automaticZenRule, rule, true);
+ populateZenRule(pkg, automaticZenRule, rule, true);
newConfig.automaticRules.put(rule.id, rule);
if (setConfigLocked(newConfig, reason, rule.component, true)) {
return rule.id;
@@ -376,7 +377,7 @@ public class ZenModeHelper {
? AUTOMATIC_RULE_STATUS_ENABLED : AUTOMATIC_RULE_STATUS_DISABLED);
}
- populateZenRule(automaticZenRule, rule, false);
+ populateZenRule(rule.pkg, automaticZenRule, rule, false);
return setConfigLocked(newConfig, reason, rule.component, true);
}
}
@@ -585,7 +586,8 @@ public class ZenModeHelper {
return null;
}
- private void populateZenRule(AutomaticZenRule automaticZenRule, ZenRule rule, boolean isNew) {
+ private void populateZenRule(String pkg, AutomaticZenRule automaticZenRule, ZenRule rule,
+ boolean isNew) {
rule.name = automaticZenRule.getName();
rule.condition = null;
rule.conditionId = automaticZenRule.getConditionId();
@@ -600,9 +602,7 @@ public class ZenModeHelper {
rule.id = ZenModeConfig.newRuleId();
rule.creationTime = System.currentTimeMillis();
rule.component = automaticZenRule.getOwner();
- rule.pkg = (rule.component != null)
- ? rule.component.getPackageName()
- : rule.configurationActivity.getPackageName();
+ rule.pkg = pkg;
}
if (rule.enabled != automaticZenRule.isEnabled()) {
@@ -611,10 +611,13 @@ public class ZenModeHelper {
}
protected AutomaticZenRule createAutomaticZenRule(ZenRule rule) {
- return new AutomaticZenRule(rule.name, rule.component, rule.configurationActivity,
+ AutomaticZenRule azr = new AutomaticZenRule(rule.name, rule.component,
+ rule.configurationActivity,
rule.conditionId, rule.zenPolicy,
NotificationManager.zenModeToInterruptionFilter(rule.zenMode),
rule.enabled, rule.creationTime);
+ azr.setPackageName(rule.pkg);
+ return azr;
}
public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 9370b14341dc..5b2c80903ce5 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1000,16 +1000,15 @@ public class LauncherAppsService extends SystemService {
intents[0].setSourceBounds(sourceBounds);
// Replace theme for splash screen
- final int splashScreenThemeResId =
- mShortcutServiceInternal.getShortcutStartingThemeResId(getCallingUserId(),
+ final String splashScreenThemeResName =
+ mShortcutServiceInternal.getShortcutStartingThemeResName(getCallingUserId(),
callingPackage, packageName, shortcutId, targetUserId);
- if (splashScreenThemeResId != 0) {
+ if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) {
if (startActivityOptions == null) {
startActivityOptions = new Bundle();
}
- startActivityOptions.putInt(KEY_SPLASH_SCREEN_THEME, splashScreenThemeResId);
+ startActivityOptions.putString(KEY_SPLASH_SCREEN_THEME, splashScreenThemeResName);
}
-
return startShortcutIntentsAsPublisher(
intents, packageName, featureId, startActivityOptions, targetUserId);
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 0b63b7ddef85..60a757118222 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -626,7 +626,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
- if (params.isStaged || isApex) {
+ if (isApex) {
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGE_UPDATES)
+ == PackageManager.PERMISSION_DENIED
+ && mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
+ == PackageManager.PERMISSION_DENIED) {
+ throw new SecurityException("Not allowed to perform APEX updates");
+ }
+ } else if (params.isStaged) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, TAG);
}
@@ -1110,6 +1117,17 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
mSilentUpdatePolicy.setAllowUnlimitedSilentUpdates(installerPackageName);
}
+ /**
+ * Set the silent updates throttle time in seconds.
+ */
+ @Override
+ public void setSilentUpdatesThrottleTime(long throttleTimeInSeconds) {
+ if (!isCalledBySystemOrShell(Binder.getCallingUid())) {
+ throw new SecurityException("Caller not allowed to set silent updates throttle time");
+ }
+ mSilentUpdatePolicy.setSilentUpdatesThrottleTime(throttleTimeInSeconds);
+ }
+
private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
int installerUid) {
int count = 0;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f9c63a948a86..49559f299fa0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -307,8 +307,8 @@ class PackageManagerShellCommand extends ShellCommand {
return runLogVisibility();
case "bypass-staged-installer-check":
return runBypassStagedInstallerCheck();
- case "allow-unlimited-silent-updates":
- return runAllowUnlimitedSilentUpdates();
+ case "set-silent-updates-policy":
+ return runSetSilentUpdatesPolicy();
default: {
Boolean domainVerificationResult =
mDomainVerificationShell.runCommand(this, cmd);
@@ -3041,12 +3041,20 @@ class PackageManagerShellCommand extends ShellCommand {
}
}
- private int runAllowUnlimitedSilentUpdates() {
+ private int runSetSilentUpdatesPolicy() {
final PrintWriter pw = getOutPrintWriter();
String opt;
+ String installerPackageName = null;
+ Long throttleTimeInSeconds = null;
boolean reset = false;
while ((opt = getNextOption()) != null) {
switch (opt) {
+ case "--allow-unlimited-silent-updates":
+ installerPackageName = getNextArgRequired();
+ break;
+ case "--throttle-time":
+ throttleTimeInSeconds = Long.parseLong(getNextArgRequired());
+ break;
case "--reset":
reset = true;
break;
@@ -3055,10 +3063,24 @@ class PackageManagerShellCommand extends ShellCommand {
return -1;
}
}
+ if (throttleTimeInSeconds != null && throttleTimeInSeconds < 0) {
+ pw.println("Error: Invalid value for \"--throttle-time\":" + throttleTimeInSeconds);
+ return -1;
+ }
- final String installerPackageName = reset ? null : getNextArgRequired();
try {
- mInterface.getPackageInstaller().setAllowUnlimitedSilentUpdates(installerPackageName);
+ final IPackageInstaller installer = mInterface.getPackageInstaller();
+ if (reset) {
+ installer.setAllowUnlimitedSilentUpdates(null /* installerPackageName */);
+ installer.setSilentUpdatesThrottleTime(-1 /* restore to the default */);
+ } else {
+ if (installerPackageName != null) {
+ installer.setAllowUnlimitedSilentUpdates(installerPackageName);
+ }
+ if (throttleTimeInSeconds != null) {
+ installer.setSilentUpdatesThrottleTime(throttleTimeInSeconds);
+ }
+ }
} catch (RemoteException e) {
pw.println("Failure ["
+ e.getClass().getName() + " - "
@@ -3889,11 +3911,14 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" --enable: turn on debug logging (default)");
pw.println(" --disable: turn off debug logging");
pw.println("");
- pw.println(" allow-unlimited-silent-updates (--reset | <INSTALLER>)");
- pw.println(" Allows unlimited silent updated installation requests from the installer");
- pw.println(" without the throttle time.");
- pw.println(" --reset: clear the allowed installer and tracks of silent updates in");
- pw.println(" the system.");
+ pw.println(" set-silent-updates-policy [--allow-unlimited-silent-updates <INSTALLER>]");
+ pw.println(" [--throttle-time <SECONDS>] [--reset]");
+ pw.println(" Sets the policies of the silent updates.");
+ pw.println(" --allow-unlimited-silent-updates: allows unlimited silent updated");
+ pw.println(" installation requests from the installer without the throttle time.");
+ pw.println(" --throttle-time: update the silent updates throttle time in seconds.");
+ pw.println(" --reset: restore the installer and throttle time to the default, and");
+ pw.println(" clear tracks of silent updates in the system.");
pw.println("");
mDomainVerificationShell.printHelp(pw);
pw.println("");
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 1bd9e5eedb84..b4bd086af272 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -139,7 +139,7 @@ class ShortcutPackage extends ShortcutPackageItem {
private static final String ATTR_BITMAP_PATH = "bitmap-path";
private static final String ATTR_ICON_URI = "icon-uri";
private static final String ATTR_LOCUS_ID = "locus-id";
- private static final String ATTR_SPLASH_SCREEN_THEME_ID = "splash-screen-theme-id";
+ private static final String ATTR_SPLASH_SCREEN_THEME_NAME = "splash-screen-theme-name";
private static final String ATTR_PERSON_NAME = "name";
private static final String ATTR_PERSON_URI = "uri";
@@ -1799,7 +1799,7 @@ class ShortcutPackage extends ShortcutPackageItem {
ShortcutService.writeAttr(out, ATTR_TITLE, si.getTitle());
ShortcutService.writeAttr(out, ATTR_TITLE_RES_ID, si.getTitleResId());
ShortcutService.writeAttr(out, ATTR_TITLE_RES_NAME, si.getTitleResName());
- ShortcutService.writeAttr(out, ATTR_SPLASH_SCREEN_THEME_ID, si.getStartingThemeResId());
+ ShortcutService.writeAttr(out, ATTR_SPLASH_SCREEN_THEME_NAME, si.getStartingThemeResName());
ShortcutService.writeAttr(out, ATTR_TEXT, si.getText());
ShortcutService.writeAttr(out, ATTR_TEXT_RES_ID, si.getTextResId());
ShortcutService.writeAttr(out, ATTR_TEXT_RES_NAME, si.getTextResName());
@@ -2010,7 +2010,7 @@ class ShortcutPackage extends ShortcutPackageItem {
String bitmapPath;
String iconUri;
final String locusIdString;
- int splashScreenThemeResId;
+ String splashScreenThemeResName;
int backupVersionCode;
ArraySet<String> categories = null;
ArrayList<Person> persons = new ArrayList<>();
@@ -2021,8 +2021,8 @@ class ShortcutPackage extends ShortcutPackageItem {
title = ShortcutService.parseStringAttribute(parser, ATTR_TITLE);
titleResId = ShortcutService.parseIntAttribute(parser, ATTR_TITLE_RES_ID);
titleResName = ShortcutService.parseStringAttribute(parser, ATTR_TITLE_RES_NAME);
- splashScreenThemeResId = ShortcutService.parseIntAttribute(parser,
- ATTR_SPLASH_SCREEN_THEME_ID);
+ splashScreenThemeResName = ShortcutService.parseStringAttribute(parser,
+ ATTR_SPLASH_SCREEN_THEME_NAME);
text = ShortcutService.parseStringAttribute(parser, ATTR_TEXT);
textResId = ShortcutService.parseIntAttribute(parser, ATTR_TEXT_RES_ID);
textResName = ShortcutService.parseStringAttribute(parser, ATTR_TEXT_RES_NAME);
@@ -2117,7 +2117,7 @@ class ShortcutPackage extends ShortcutPackageItem {
rank, extras, lastChangedTimestamp, flags,
iconResId, iconResName, bitmapPath, iconUri,
disabledReason, persons.toArray(new Person[persons.size()]), locusId,
- splashScreenThemeResId);
+ splashScreenThemeResName);
}
private static Intent parseIntent(TypedXmlPullParser parser)
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index c06f01a463ad..b86c50b23687 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -383,8 +383,11 @@ public class ShortcutParser {
final int textResId = sa.getResourceId(R.styleable.Shortcut_shortcutLongLabel, 0);
final int disabledMessageResId = sa.getResourceId(
R.styleable.Shortcut_shortcutDisabledMessage, 0);
- final int splashScreenTheme = sa.getResourceId(
+ final int splashScreenThemeResId = sa.getResourceId(
R.styleable.Shortcut_splashScreenTheme, 0);
+ final String splashScreenThemeResName = splashScreenThemeResId != 0
+ ? service.mContext.getResources().getResourceName(splashScreenThemeResId)
+ : null;
if (TextUtils.isEmpty(id)) {
Log.w(TAG, "android:shortcutId must be provided. activity=" + activity);
@@ -407,7 +410,7 @@ public class ShortcutParser {
rank,
iconResId,
enabled,
- splashScreenTheme);
+ splashScreenThemeResName);
} finally {
sa.recycle();
}
@@ -416,7 +419,7 @@ public class ShortcutParser {
private static ShortcutInfo createShortcutFromManifest(ShortcutService service,
@UserIdInt int userId, String id, String packageName, ComponentName activityComponent,
int titleResId, int textResId, int disabledMessageResId,
- int rank, int iconResId, boolean enabled, int splashScreenTheme) {
+ int rank, int iconResId, boolean enabled, @Nullable String splashScreenThemeResName) {
final int flags =
(enabled ? ShortcutInfo.FLAG_MANIFEST : ShortcutInfo.FLAG_DISABLED)
@@ -456,7 +459,7 @@ public class ShortcutParser {
disabledReason,
null /* persons */,
null /* locusId */,
- splashScreenTheme);
+ splashScreenThemeResName);
}
private static String parseCategory(ShortcutService service, AttributeSet attrs) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 5f1027797292..fcbf40e29933 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -3536,7 +3536,8 @@ public class ShortcutService extends IShortcutService.Stub {
}
@Override
- public int getShortcutStartingThemeResId(int launcherUserId,
+ @Nullable
+ public String getShortcutStartingThemeResName(int launcherUserId,
@NonNull String callingPackage, @NonNull String packageName,
@NonNull String shortcutId, int userId) {
Objects.requireNonNull(callingPackage, "callingPackage");
@@ -3553,11 +3554,11 @@ public class ShortcutService extends IShortcutService.Stub {
final ShortcutPackage p = getUserShortcutsLocked(userId)
.getPackageShortcutsIfExists(packageName);
if (p == null) {
- return 0;
+ return null;
}
final ShortcutInfo shortcutInfo = p.findShortcutById(shortcutId);
- return shortcutInfo != null ? shortcutInfo.getStartingThemeResId() : 0;
+ return shortcutInfo != null ? shortcutInfo.getStartingThemeResName() : null;
}
}
diff --git a/services/core/java/com/android/server/pm/SilentUpdatePolicy.java b/services/core/java/com/android/server/pm/SilentUpdatePolicy.java
index 117acab6d079..700f72cfbb94 100644
--- a/services/core/java/com/android/server/pm/SilentUpdatePolicy.java
+++ b/services/core/java/com/android/server/pm/SilentUpdatePolicy.java
@@ -33,7 +33,8 @@ import java.util.concurrent.TimeUnit;
* in the {@link PackageInstallerSession}.
*/
public class SilentUpdatePolicy {
- // A throttle time to prevent the installer from silently updating the same app repeatedly.
+ // The default throttle time to prevent the installer from silently updating the same app
+ // repeatedly.
private static final long SILENT_UPDATE_THROTTLE_TIME_MS = TimeUnit.SECONDS.toMillis(30);
// Map to the uptime timestamp for each installer and app of the silent update.
@@ -44,6 +45,9 @@ public class SilentUpdatePolicy {
@GuardedBy("mSilentUpdateInfos")
private String mAllowUnlimitedSilentUpdatesInstaller;
+ @GuardedBy("mSilentUpdateInfos")
+ private long mSilentUpdateThrottleTimeMs = SILENT_UPDATE_THROTTLE_TIME_MS;
+
/**
* Checks if the silent update is allowed by the given installer and app package name.
*
@@ -58,7 +62,11 @@ public class SilentUpdatePolicy {
return true;
}
final long lastSilentUpdatedMs = getTimestampMs(installerPackageName, packageName);
- return SystemClock.uptimeMillis() - lastSilentUpdatedMs > SILENT_UPDATE_THROTTLE_TIME_MS;
+ final long throttleTimeMs;
+ synchronized (mSilentUpdateInfos) {
+ throttleTimeMs = mSilentUpdateThrottleTimeMs;
+ }
+ return SystemClock.uptimeMillis() - lastSilentUpdatedMs > throttleTimeMs;
}
/**
@@ -99,11 +107,25 @@ public class SilentUpdatePolicy {
}
}
+ /**
+ * Set the silent updates throttle time in seconds.
+ *
+ * @param throttleTimeInSeconds The throttle time to set, or <code>-1</code> to restore the
+ * value to the default.
+ */
+ void setSilentUpdatesThrottleTime(long throttleTimeInSeconds) {
+ synchronized (mSilentUpdateInfos) {
+ mSilentUpdateThrottleTimeMs = throttleTimeInSeconds >= 0
+ ? TimeUnit.SECONDS.toMillis(throttleTimeInSeconds)
+ : SILENT_UPDATE_THROTTLE_TIME_MS;
+ }
+ }
+
private void pruneLocked(long uptime) {
final int size = mSilentUpdateInfos.size();
for (int i = size - 1; i >= 0; i--) {
final long lastSilentUpdatedMs = mSilentUpdateInfos.valueAt(i);
- if (uptime - lastSilentUpdatedMs > SILENT_UPDATE_THROTTLE_TIME_MS) {
+ if (uptime - lastSilentUpdatedMs > mSilentUpdateThrottleTimeMs) {
mSilentUpdateInfos.removeAt(i);
}
}
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 94005b2c8361..22c370ef4dbe 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -33,14 +33,15 @@ import android.content.pm.ResolveInfo;
import android.location.LocationManagerInternal;
import android.net.Uri;
import android.os.IBinder;
+import android.os.PackageTagsList;
import android.os.Process;
import android.os.UserHandle;
import android.service.voice.VoiceInteractionManagerInternal;
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.DecFunction;
@@ -52,9 +53,9 @@ import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.UndecFunction;
import com.android.server.LocalServices;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -67,11 +68,10 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
"android:activity_recognition_allow_listed_tags";
private static final String ACTIVITY_RECOGNITION_TAGS_SEPARATOR = ";";
- private static ArraySet<String> sExpectedTags = new ArraySet<>(new String[] {
+ private static final ArraySet<String> sExpectedTags = new ArraySet<>(new String[] {
"awareness_provider", "activity_recognition_provider", "network_location_provider",
"network_location_calibration", "fused_location_provider", "geofencer_provider"});
-
@NonNull
private final Object mLock = new Object();
@@ -96,13 +96,22 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
*/
@GuardedBy("mLock - writes only - see above")
@NonNull
- private final ConcurrentHashMap<Integer, ArrayMap<String, ArraySet<String>>> mLocationTags =
+ private final ConcurrentHashMap<Integer, PackageTagsList> mLocationTags =
new ConcurrentHashMap<>();
+ // location tags can vary per uid - but we merge all tags under an app id into the final data
+ // structure above
+ @GuardedBy("mLock")
+ private final SparseArray<PackageTagsList> mPerUidLocationTags = new SparseArray<>();
+
+ // activity recognition currently only grabs tags from the APK manifest. we know that the
+ // manifest is the same for all users, so there's no need to track variations in tags across
+ // different users. if that logic ever changes, this might need to behave more like location
+ // tags above.
@GuardedBy("mLock - writes only - see above")
@NonNull
- private final ConcurrentHashMap<Integer, ArrayMap<String, ArraySet<String>>>
- mActivityRecognitionTags = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap<Integer, PackageTagsList> mActivityRecognitionTags =
+ new ConcurrentHashMap<>();
public AppOpsPolicy(@NonNull Context context) {
mContext = context;
@@ -112,13 +121,28 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
final LocationManagerInternal locationManagerInternal = LocalServices.getService(
LocationManagerInternal.class);
- locationManagerInternal.setOnProviderLocationTagsChangeListener((providerTagInfo) -> {
- synchronized (mLock) {
- updateAllowListedTagsForPackageLocked(providerTagInfo.getUid(),
- providerTagInfo.getPackageName(), providerTagInfo.getTags(),
- mLocationTags);
- }
- });
+ locationManagerInternal.setLocationPackageTagsListener(
+ (uid, packageTagsList) -> {
+ synchronized (mLock) {
+ if (packageTagsList.isEmpty()) {
+ mPerUidLocationTags.remove(uid);
+ } else {
+ mPerUidLocationTags.set(uid, packageTagsList);
+ }
+
+ int appId = UserHandle.getAppId(uid);
+ PackageTagsList.Builder appIdTags = new PackageTagsList.Builder(1);
+ int size = mPerUidLocationTags.size();
+ for (int i = 0; i < size; i++) {
+ if (UserHandle.getAppId(mPerUidLocationTags.keyAt(i)) == appId) {
+ appIdTags.add(mPerUidLocationTags.valueAt(i));
+ }
+ }
+
+ updateAllowListedTagsForPackageLocked(appId, appIdTags.build(),
+ mLocationTags);
+ }
+ });
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -306,95 +330,30 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
final String tagsList = resolvedService.serviceInfo.metaData.getString(
ACTIVITY_RECOGNITION_TAGS);
- if (tagsList != null) {
- final String[] tags = tagsList.split(ACTIVITY_RECOGNITION_TAGS_SEPARATOR);
+ if (!TextUtils.isEmpty(tagsList)) {
+ PackageTagsList packageTagsList = new PackageTagsList.Builder(1).add(
+ resolvedService.serviceInfo.packageName,
+ Arrays.asList(tagsList.split(ACTIVITY_RECOGNITION_TAGS_SEPARATOR))).build();
synchronized (mLock) {
updateAllowListedTagsForPackageLocked(
- resolvedService.serviceInfo.applicationInfo.uid,
- resolvedService.serviceInfo.packageName, new ArraySet<>(tags),
+ UserHandle.getAppId(resolvedService.serviceInfo.applicationInfo.uid),
+ packageTagsList,
mActivityRecognitionTags);
}
}
}
- private static void updateAllowListedTagsForPackageLocked(int uid, String packageName,
- Set<String> allowListedTags, ConcurrentHashMap<Integer, ArrayMap<String,
- ArraySet<String>>> datastore) {
- final int appId = UserHandle.getAppId(uid);
- // We make a copy of the per UID state to limit our mutation to one
- // operation in the underlying concurrent data structure.
- ArrayMap<String, ArraySet<String>> appIdTags = datastore.get(appId);
- if (appIdTags != null) {
- appIdTags = new ArrayMap<>(appIdTags);
- }
-
- ArraySet<String> packageTags = (appIdTags != null) ? appIdTags.get(packageName) : null;
- if (packageTags != null) {
- packageTags = new ArraySet<>(packageTags);
- }
-
- if (allowListedTags != null && !allowListedTags.isEmpty()) {
- if (packageTags != null) {
- packageTags.clear();
- packageTags.addAll(allowListedTags);
- } else {
- packageTags = new ArraySet<>(allowListedTags);
- }
- if (appIdTags == null) {
- appIdTags = new ArrayMap<>();
- }
-
- // Remove any invalid tags
- boolean nullRemoved = packageTags.remove(null);
- boolean nullStrRemoved = packageTags.remove("null");
- boolean emptyRemoved = packageTags.remove("");
- if (nullRemoved || nullStrRemoved || emptyRemoved) {
- Log.e(LOG_TAG, "Attempted to add invalid source attribution tag, removed "
- + "null: " + nullRemoved + " removed \"null\": " + nullStrRemoved
- + " removed empty string: " + emptyRemoved);
- }
-
- appIdTags.put(packageName, packageTags);
- datastore.put(appId, appIdTags);
- } else if (appIdTags != null) {
- appIdTags.remove(packageName);
- if (!appIdTags.isEmpty()) {
- datastore.put(appId, appIdTags);
- } else {
- datastore.remove(appId);
- }
- }
+ private static void updateAllowListedTagsForPackageLocked(int appId,
+ PackageTagsList packageTagsList,
+ ConcurrentHashMap<Integer, PackageTagsList> datastore) {
+ datastore.put(appId, packageTagsList);
}
private static boolean isDatasourceAttributionTag(int uid, @NonNull String packageName,
- @NonNull String attributionTag, @NonNull Map<Integer, ArrayMap<String,
- ArraySet<String>>> mappedOps) {
+ @NonNull String attributionTag, @NonNull Map<Integer, PackageTagsList> mappedOps) {
// Only a single lookup from the underlying concurrent data structure
- final int appId = UserHandle.getAppId(uid);
- final ArrayMap<String, ArraySet<String>> appIdTags = mappedOps.get(appId);
- if (appIdTags != null) {
- final ArraySet<String> packageTags = appIdTags.get(packageName);
- if (packageTags != null && packageTags.contains(attributionTag)) {
- if (packageName.equals("com.google.android.gms")
- && !sExpectedTags.contains(attributionTag)) {
- Log.i("AppOpsDebugRemapping", packageName + " tag "
- + attributionTag + " in " + packageTags);
- }
- return true;
- }
- if (packageName.equals("com.google.android.gms")
- && sExpectedTags.contains(attributionTag)) {
- Log.i("AppOpsDebugRemapping", packageName + " tag " + attributionTag
- + " NOT in " + packageTags);
- }
- } else {
- if (packageName.equals("com.google.android.gms")) {
- Log.i("AppOpsDebugRemapping", "no package tags for uid " + uid
- + " package " + packageName);
- }
-
- }
- return false;
+ final PackageTagsList appIdTags = mappedOps.get(UserHandle.getAppId(uid));
+ return appIdTags != null && appIdTags.contains(packageName, attributionTag);
}
private static int resolveLocationOp(int code) {
diff --git a/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java b/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java
index e1e6195ad260..f653e4b26438 100644
--- a/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java
+++ b/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java
@@ -30,6 +30,9 @@ public final class ProcfsMemoryUtil {
"RssAnon:",
"VmSwap:"
};
+ private static final String[] VMSTAT_KEYS = new String[] {
+ "oom_kill"
+ };
private ProcfsMemoryUtil() {}
@@ -99,4 +102,22 @@ public final class ProcfsMemoryUtil {
public int anonRssInKilobytes;
public int swapInKilobytes;
}
+
+ /** Reads and parses selected entries of /proc/vmstat. */
+ @Nullable
+ static VmStat readVmStat() {
+ long[] vmstat = new long[VMSTAT_KEYS.length];
+ vmstat[0] = -1;
+ Process.readProcLines("/proc/vmstat", VMSTAT_KEYS, vmstat);
+ if (vmstat[0] == -1) {
+ return null;
+ }
+ VmStat result = new VmStat();
+ result.oomKillCount = (int) vmstat[0];
+ return result;
+ }
+
+ static final class VmStat {
+ public int oomKillCount;
+ }
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index dc868b325900..cd0ce2bd46a7 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -544,6 +544,8 @@ public class StatsPullAtomService extends SystemService {
return pullProcessDmabufMemory(atomTag, data);
case FrameworkStatsLog.SYSTEM_MEMORY:
return pullSystemMemory(atomTag, data);
+ case FrameworkStatsLog.VMSTAT:
+ return pullVmStat(atomTag, data);
case FrameworkStatsLog.TEMPERATURE:
synchronized (mTemperatureLock) {
return pullTemperatureLocked(atomTag, data);
@@ -842,6 +844,7 @@ public class StatsPullAtomService extends SystemService {
registerProcessSystemIonHeapSize();
registerSystemMemory();
registerProcessDmabufMemory();
+ registerVmStat();
registerTemperature();
registerCoolingDevice();
registerBinderCallsStats();
@@ -2273,6 +2276,27 @@ public class StatsPullAtomService extends SystemService {
return StatsManager.PULL_SUCCESS;
}
+ private void registerVmStat() {
+ int tagId = FrameworkStatsLog.VMSTAT;
+ mStatsManager.setPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ DIRECT_EXECUTOR,
+ mStatsCallbackImpl
+ );
+ }
+
+ int pullVmStat(int atomTag, List<StatsEvent> pulledData) {
+ ProcfsMemoryUtil.VmStat vmStat = ProcfsMemoryUtil.readVmStat();
+ if (vmStat != null) {
+ pulledData.add(
+ FrameworkStatsLog.buildStatsEvent(
+ atomTag,
+ vmStat.oomKillCount));
+ }
+ return StatsManager.PULL_SUCCESS;
+ }
+
private void registerTemperature() {
int tagId = FrameworkStatsLog.TEMPERATURE;
mStatsManager.setPullAtomCallback(
diff --git a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
index b695150d9ba3..e8ce4f336caa 100644
--- a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
+++ b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
@@ -16,6 +16,7 @@
package com.android.server.vibrator;
+import android.content.Context;
import android.os.VibrationEffect;
import android.os.VibratorInfo;
@@ -26,17 +27,16 @@ import java.util.List;
final class DeviceVibrationEffectAdapter
implements VibrationEffectAdapters.EffectAdapter<VibratorInfo> {
- /** Duration of each step created to simulate a ramp segment. */
- private static final int RAMP_STEP_DURATION_MILLIS = 5;
-
private final List<VibrationEffectAdapters.SegmentsAdapter<VibratorInfo>> mSegmentAdapters;
- DeviceVibrationEffectAdapter() {
+ DeviceVibrationEffectAdapter(Context context) {
mSegmentAdapters = Arrays.asList(
// TODO(b/167947076): add filter that removes unsupported primitives
// TODO(b/167947076): add filter that replaces unsupported prebaked with fallback
- new RampToStepAdapter(RAMP_STEP_DURATION_MILLIS),
- new StepToRampAdapter(),
+ new RampToStepAdapter(context.getResources().getInteger(
+ com.android.internal.R.integer.config_vibrationWaveformRampStepDuration)),
+ new StepToRampAdapter(context.getResources().getInteger(
+ com.android.internal.R.integer.config_vibrationWaveformRampDownDuration)),
new ClippingAmplitudeAndFrequencyAdapter()
);
}
diff --git a/services/core/java/com/android/server/vibrator/RampToStepAdapter.java b/services/core/java/com/android/server/vibrator/RampToStepAdapter.java
index 1e05bdbdf082..64624a28c5da 100644
--- a/services/core/java/com/android/server/vibrator/RampToStepAdapter.java
+++ b/services/core/java/com/android/server/vibrator/RampToStepAdapter.java
@@ -29,7 +29,7 @@ import java.util.List;
/**
* Adapter that converts ramp segments that to a sequence of fixed step segments.
*
- * <p>This leaves the list unchanged if the device have compose PWLE capability.
+ * <p>This leaves the list unchanged if the device has compose PWLE capability.
*/
final class RampToStepAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
diff --git a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
index f78df9208fbd..d439b94ec2fc 100644
--- a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
+++ b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
@@ -27,39 +27,221 @@ import java.util.List;
/**
* Adapter that converts step segments that should be handled as PWLEs to ramp segments.
*
- * <p>This leaves the list unchanged if the device do not have compose PWLE capability.
+ * <p>Each replaced {@link StepSegment} will be represented by a {@link RampSegment} with same
+ * start and end amplitudes/frequencies, which can then be converted to PWLE compositions. This
+ * adapter leaves the segments unchanged if the device doesn't have the PWLE composition capability.
+ *
+ * <p>This adapter also applies the ramp down duration config on devices with PWLE support. This
+ * prevents the device from ringing when it cannot handle abrupt changes between ON and OFF states.
+ * This will not change other types of abrupt amplitude changes in the original effect.
+ *
+ * <p>The effect overall duration is preserved by this transformation. Waveforms with ON/OFF
+ * segments are handled gracefully by the ramp down changes. Each OFF segment preceded by an ON
+ * segment will be shortened, and a ramp down will be added to the transition between ON and OFF.
+ * The ramps can be shorter than the configured duration in order to preserve the waveform timings,
+ * but they will still soften the ringing effect.
*/
final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
+
+ private final int mRampDownDuration;
+
+ StepToRampAdapter(int rampDownDuration) {
+ mRampDownDuration = rampDownDuration;
+ }
+
@Override
public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
VibratorInfo info) {
if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
- // The vibrator do not have PWLE capability, so keep the segments unchanged.
+ // The vibrator does not have PWLE capability, so keep the segments unchanged.
return repeatIndex;
}
+ convertStepsToRamps(segments);
+ int newRepeatIndex = addRampDownToZeroAmplitudeSegments(segments, repeatIndex);
+ newRepeatIndex = addRampDownToLoop(segments, newRepeatIndex);
+ return newRepeatIndex;
+ }
+
+ private void convertStepsToRamps(List<VibrationEffectSegment> segments) {
int segmentCount = segments.size();
+ if (mRampDownDuration > 0) {
+ // Convert all steps to ramps if the device requires ramp down.
+ for (int i = 0; i < segmentCount; i++) {
+ if (isStep(segments.get(i))) {
+ segments.set(i, apply((StepSegment) segments.get(i)));
+ }
+ }
+ return;
+ }
// Convert steps that require frequency control to ramps.
for (int i = 0; i < segmentCount; i++) {
VibrationEffectSegment segment = segments.get(i);
- if ((segment instanceof StepSegment)
- && ((StepSegment) segment).getFrequency() != 0) {
+ if (isStep(segment) && ((StepSegment) segment).getFrequency() != 0) {
segments.set(i, apply((StepSegment) segment));
}
}
// Convert steps that are next to ramps to also become ramps, so they can be composed
// together in the same PWLE waveform.
- for (int i = 1; i < segmentCount; i++) {
+ for (int i = 0; i < segmentCount; i++) {
if (segments.get(i) instanceof RampSegment) {
- for (int j = i - 1; j >= 0 && (segments.get(j) instanceof StepSegment); j--) {
+ for (int j = i - 1; j >= 0 && isStep(segments.get(j)); j--) {
segments.set(j, apply((StepSegment) segments.get(j)));
}
+ for (int j = i + 1; j < segmentCount && isStep(segments.get(j)); j++) {
+ segments.set(j, apply((StepSegment) segments.get(j)));
+ }
+ }
+ }
+ }
+
+ /**
+ * This will add a ramp to zero as follows:
+ *
+ * <ol>
+ * <li>Remove the {@link VibrationEffectSegment} that starts and ends at zero amplitude
+ * and follows a segment that ends at non-zero amplitude;
+ * <li>Add a ramp down to zero starting at the previous segment end amplitude and frequency,
+ * with min between the removed segment duration and the configured ramp down duration;
+ * <li>Add a zero amplitude segment following the ramp with the remaining duration, if
+ * necessary;
+ * </ol>
+ */
+ private int addRampDownToZeroAmplitudeSegments(List<VibrationEffectSegment> segments,
+ int repeatIndex) {
+ if (mRampDownDuration <= 0) {
+ // Nothing to do, no ramp down duration configured.
+ return repeatIndex;
+ }
+ int newRepeatIndex = repeatIndex;
+ int newSegmentCount = segments.size();
+ for (int i = 1; i < newSegmentCount; i++) {
+ if (!isOffRampSegment(segments.get(i))
+ || !endsWithNonZeroAmplitude(segments.get(i - 1))) {
+ continue;
+ }
+
+ // We know the previous segment is a ramp that ends at non-zero amplitude.
+ float previousAmplitude = ((RampSegment) segments.get(i - 1)).getEndAmplitude();
+ float previousFrequency = ((RampSegment) segments.get(i - 1)).getEndFrequency();
+ RampSegment ramp = (RampSegment) segments.get(i);
+
+ if (ramp.getDuration() <= mRampDownDuration) {
+ // Replace the zero amplitude segment with a ramp down of same duration, to
+ // preserve waveform timings and still soften the transition to zero.
+ segments.set(i, createRampDown(previousAmplitude, previousFrequency,
+ ramp.getDuration()));
+ } else {
+ // Make the zero amplitude segment shorter, to preserve waveform timings, and add a
+ // ramp down to zero segment right before it.
+ segments.set(i, updateDuration(ramp, ramp.getDuration() - mRampDownDuration));
+ segments.add(i, createRampDown(previousAmplitude, previousFrequency,
+ mRampDownDuration));
+ if (repeatIndex > i) {
+ newRepeatIndex++;
+ }
+ i++;
+ newSegmentCount++;
+ }
+ }
+ return newRepeatIndex;
+ }
+
+ /**
+ * This will add a ramp to zero at the repeating index of the given effect, if set, only if
+ * the last segment ends at a non-zero amplitude and the repeating segment starts and ends at
+ * zero amplitude. The update is described as:
+ *
+ * <ol>
+ * <li>Add a ramp down to zero following the last segment, with the min between the
+ * removed segment duration and the configured ramp down duration;
+ * <li>Skip the zero-amplitude segment by incrementing the repeat index, splitting it if
+ * necessary to skip the correct amount;
+ * </ol>
+ */
+ private int addRampDownToLoop(List<VibrationEffectSegment> segments, int repeatIndex) {
+ if (repeatIndex < 0) {
+ // Non-repeating compositions should remain unchanged so duration will be preserved.
+ return repeatIndex;
+ }
+
+ int segmentCount = segments.size();
+ if (mRampDownDuration <= 0 || !endsWithNonZeroAmplitude(segments.get(segmentCount - 1))) {
+ // Nothing to do, no ramp down duration configured or composition already ends at zero.
+ return repeatIndex;
+ }
+
+ // We know the last segment is a ramp that ends at non-zero amplitude.
+ RampSegment lastRamp = (RampSegment) segments.get(segmentCount - 1);
+ float previousAmplitude = lastRamp.getEndAmplitude();
+ float previousFrequency = lastRamp.getEndFrequency();
+
+ if (isOffRampSegment(segments.get(repeatIndex))) {
+ // Repeating from a non-zero to a zero amplitude segment, we know the next segment is a
+ // ramp with zero amplitudes.
+ RampSegment nextRamp = (RampSegment) segments.get(repeatIndex);
+
+ if (nextRamp.getDuration() <= mRampDownDuration) {
+ // Skip the zero amplitude segment and append a ramp down of same duration to the
+ // end of the composition, to preserve waveform timings and still soften the
+ // transition to zero.
+ // This will update the waveform as follows:
+ // R R+1
+ // | ____ | ____
+ // _|_/ => __|/ \
+ segments.add(createRampDown(previousAmplitude, previousFrequency,
+ nextRamp.getDuration()));
+ repeatIndex++;
+ } else {
+ // Append a ramp down to the end of the composition, split the zero amplitude
+ // segment and start repeating from the second half, to preserve waveform timings.
+ // This will update the waveform as follows:
+ // R R+1
+ // | ____ | ____
+ // _|__/ => __|_/ \
+ segments.add(createRampDown(previousAmplitude, previousFrequency,
+ mRampDownDuration));
+ segments.set(repeatIndex, updateDuration(nextRamp,
+ nextRamp.getDuration() - mRampDownDuration));
+ segments.add(repeatIndex, updateDuration(nextRamp, mRampDownDuration));
+ repeatIndex++;
}
}
+
return repeatIndex;
}
- private RampSegment apply(StepSegment segment) {
+ private static RampSegment apply(StepSegment segment) {
return new RampSegment(segment.getAmplitude(), segment.getAmplitude(),
segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration());
}
+
+ private static RampSegment createRampDown(float amplitude, float frequency, long duration) {
+ return new RampSegment(amplitude, /* endAmplitude= */ 0, frequency, frequency,
+ (int) duration);
+ }
+
+ private static RampSegment updateDuration(RampSegment ramp, long newDuration) {
+ return new RampSegment(ramp.getStartAmplitude(), ramp.getEndAmplitude(),
+ ramp.getStartFrequency(), ramp.getEndFrequency(), (int) newDuration);
+ }
+
+ private static boolean isStep(VibrationEffectSegment segment) {
+ return segment instanceof StepSegment;
+ }
+
+ /** Returns true if the segment is a ramp that starts and ends at zero amplitude. */
+ private static boolean isOffRampSegment(VibrationEffectSegment segment) {
+ if (segment instanceof RampSegment) {
+ RampSegment ramp = (RampSegment) segment;
+ return ramp.getStartAmplitude() == 0 && ramp.getEndAmplitude() == 0;
+ }
+ return false;
+ }
+
+ private static boolean endsWithNonZeroAmplitude(VibrationEffectSegment segment) {
+ if (segment instanceof RampSegment) {
+ return ((RampSegment) segment).getEndAmplitude() != 0;
+ }
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index e3672f4d497c..150fde99b706 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -95,8 +95,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
private final WorkSource mWorkSource = new WorkSource();
private final PowerManager.WakeLock mWakeLock;
private final IBatteryStats mBatteryStatsService;
- private final DeviceVibrationEffectAdapter mDeviceEffectAdapter =
- new DeviceVibrationEffectAdapter();
+ private final DeviceVibrationEffectAdapter mDeviceEffectAdapter;
private final Vibration mVibration;
private final VibrationCallbacks mCallbacks;
private final SparseArray<VibratorController> mVibrators = new SparseArray<>();
@@ -104,10 +103,11 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
private volatile boolean mForceStop;
- VibrationThread(Vibration vib, SparseArray<VibratorController> availableVibrators,
- PowerManager.WakeLock wakeLock, IBatteryStats batteryStatsService,
- VibrationCallbacks callbacks) {
+ VibrationThread(Vibration vib, DeviceVibrationEffectAdapter effectAdapter,
+ SparseArray<VibratorController> availableVibrators, PowerManager.WakeLock wakeLock,
+ IBatteryStats batteryStatsService, VibrationCallbacks callbacks) {
mVibration = vib;
+ mDeviceEffectAdapter = effectAdapter;
mCallbacks = callbacks;
mWakeLock = wakeLock;
mWorkSource.set(vib.uid);
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 06a5077bec82..79706ead555c 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -132,6 +132,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
private final VibrationSettings mVibrationSettings;
private final VibrationScaler mVibrationScaler;
private final InputDeviceDelegate mInputDeviceDelegate;
+ private final DeviceVibrationEffectAdapter mDeviceVibrationEffectAdapter;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
@@ -175,6 +176,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
mVibrationSettings = new VibrationSettings(mContext, mHandler);
mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings);
mInputDeviceDelegate = new InputDeviceDelegate(mContext, mHandler);
+ mDeviceVibrationEffectAdapter = new DeviceVibrationEffectAdapter(mContext);
VibrationCompleteListener listener = new VibrationCompleteListener(this);
mNativeWrapper = injector.getNativeWrapper();
@@ -512,8 +514,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
return Vibration.Status.FORWARDED_TO_INPUT_DEVICES;
}
- VibrationThread vibThread = new VibrationThread(vib, mVibrators, mWakeLock,
- mBatteryStatsService, mVibrationCallbacks);
+ VibrationThread vibThread = new VibrationThread(vib, mDeviceVibrationEffectAdapter,
+ mVibrators, mWakeLock, mBatteryStatsService, mVibrationCallbacks);
if (mCurrentVibration == null) {
return startVibrationThreadLocked(vibThread);
@@ -721,6 +723,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
* VibrationAttributes.USAGE_* values.
*/
private boolean shouldCancelVibration(VibrationAttributes attrs, int usageFilter) {
+ if (attrs.getUsage() == VibrationAttributes.USAGE_UNKNOWN) {
+ // Special case, usage UNKNOWN would match all filters. Instead it should only match if
+ // it's cancelling that usage specifically, or if cancelling all usages.
+ return usageFilter == VibrationAttributes.USAGE_UNKNOWN
+ || usageFilter == VibrationAttributes.USAGE_FILTER_MATCH_ALL;
+ }
return (usageFilter & attrs.getUsage()) == attrs.getUsage();
}
@@ -1533,7 +1541,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
private int runCancel() {
- cancelVibrate(/* usageFilter= */ -1, mToken);
+ cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, mToken);
return 0;
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 71e31c3a10df..ac0665a37c0b 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -703,7 +703,7 @@ final class AccessibilityController {
Slog.i(LOG_TAG, "Rotation: " + Surface.rotationToString(rotation)
+ " displayId: " + displayContent.getDisplayId());
}
- mMagnifedViewport.onRotationChanged(displayContent.getPendingTransaction());
+ mMagnifedViewport.onRotationChanged();
mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_ROTATION_CHANGED);
}
@@ -858,7 +858,7 @@ final class AccessibilityController {
private final RectF mTempRectF = new RectF();
- private final Point mTempPoint = new Point();
+ private final Point mScreenSize = new Point();
private final Matrix mTempMatrix = new Matrix();
@@ -887,8 +887,8 @@ final class AccessibilityController {
if (mDisplayContext.getResources().getConfiguration().isScreenRound()) {
mCircularPath = new Path();
- mDisplay.getRealSize(mTempPoint);
- final int centerXY = mTempPoint.x / 2;
+ mDisplay.getRealSize(mScreenSize);
+ final int centerXY = mScreenSize.x / 2;
mCircularPath.addCircle(centerXY, centerXY, centerXY, Path.Direction.CW);
} else {
mCircularPath = null;
@@ -917,9 +917,9 @@ final class AccessibilityController {
}
void recomputeBounds() {
- mDisplay.getRealSize(mTempPoint);
- final int screenWidth = mTempPoint.x;
- final int screenHeight = mTempPoint.y;
+ mDisplay.getRealSize(mScreenSize);
+ final int screenWidth = mScreenSize.x;
+ final int screenHeight = mScreenSize.y;
mMagnificationRegion.set(0, 0, 0, 0);
final Region availableBounds = mTempRegion1;
@@ -1052,7 +1052,7 @@ final class AccessibilityController {
|| windowType == TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
}
- void onRotationChanged(SurfaceControl.Transaction t) {
+ void onRotationChanged() {
// If we are showing the magnification border, hide it immediately so
// the user does not see strange artifacts during rotation. The screenshot
// used for rotation already has the border. After the rotation is complete
@@ -1066,7 +1066,7 @@ final class AccessibilityController {
mHandler.sendMessageDelayed(message, delay);
}
recomputeBounds();
- mWindow.updateSize(t);
+ mWindow.updateSize();
}
void setMagnifiedRegionBorderShown(boolean shown, boolean animate) {
@@ -1148,9 +1148,9 @@ final class AccessibilityController {
/* ignore */
}
mSurfaceControl = surfaceControl;
- mDisplay.getRealSize(mTempPoint);
+ mDisplay.getRealSize(mScreenSize);
mBlastBufferQueue = new BLASTBufferQueue(SURFACE_TITLE, mSurfaceControl,
- mTempPoint.x, mTempPoint.y, PixelFormat.RGBA_8888);
+ mScreenSize.x, mScreenSize.y, PixelFormat.RGBA_8888);
final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
final int layer =
@@ -1224,10 +1224,11 @@ final class AccessibilityController {
}
}
- void updateSize(SurfaceControl.Transaction t) {
+ void updateSize() {
synchronized (mService.mGlobalLock) {
- mDisplay.getRealSize(mTempPoint);
- t.setBufferSize(mSurfaceControl, mTempPoint.x, mTempPoint.y);
+ mDisplay.getRealSize(mScreenSize);
+ mBlastBufferQueue.update(mSurfaceControl, mScreenSize.x, mScreenSize.y,
+ PixelFormat.RGBA_8888);
invalidate(mDirtyRect);
}
}
@@ -1296,8 +1297,8 @@ final class AccessibilityController {
pw.println(prefix
+ " mBounds= " + mBounds
+ " mDirtyRect= " + mDirtyRect
- + " mWidth= " + mSurfaceControl.getWidth()
- + " mHeight= " + mSurfaceControl.getHeight());
+ + " mWidth= " + mScreenSize.x
+ + " mHeight= " + mScreenSize.y);
}
private final class AnimationController extends Handler {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 2b6a83896cc6..14f6fb3ed99a 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -312,6 +312,12 @@ class ActivityMetricsLogger {
}
}
+ /** Returns {@code true} if the incoming activity can belong to this transition. */
+ boolean canCoalesce(ActivityRecord r) {
+ return mLastLaunchedActivity.mDisplayContent == r.mDisplayContent
+ && mLastLaunchedActivity.getWindowingMode() == r.getWindowingMode();
+ }
+
/** @return {@code true} if the activity matches a launched activity in this transition. */
boolean contains(ActivityRecord r) {
return r != null && (r == mLastLaunchedActivity || mPendingDrawActivities.contains(r));
@@ -604,8 +610,7 @@ class ActivityMetricsLogger {
return;
}
- final DisplayContent targetDisplay = launchedActivity.mDisplayContent;
- if (info != null && info.mLastLaunchedActivity.mDisplayContent == targetDisplay) {
+ if (info != null && info.canCoalesce(launchedActivity)) {
// If we are already in an existing transition on the same display, only update the
// activity name, but not the other attributes.
@@ -633,7 +638,7 @@ class ActivityMetricsLogger {
// As abort for no process switch.
launchObserverNotifyIntentFailed();
}
- if (targetDisplay.isSleeping()) {
+ if (launchedActivity.mDisplayContent.isSleeping()) {
// It is unknown whether the activity can be drawn or not, e.g. ut depends on the
// keyguard states and the attributes or flags set by the activity. If the activity
// keeps invisible in the grace period, the tracker will be cancelled so it won't get
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 660cd37b123c..8514f3599832 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -309,6 +309,7 @@ import android.view.animation.Animation;
import android.window.IRemoteTransition;
import android.window.SizeConfigurationBuckets;
import android.window.SplashScreen;
+import android.window.SplashScreenView;
import android.window.SplashScreenView.SplashScreenViewParcelable;
import android.window.TaskSnapshot;
import android.window.WindowContainerToken;
@@ -716,25 +717,29 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean startingMoved;
boolean mHandleExitSplashScreen;
- @TransferSplashScreenState int mTransferringSplashScreenState =
- TRANSFER_SPLASH_SCREEN_IDLE;
+ @TransferSplashScreenState
+ int mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_IDLE;
- // Idle, can be triggered to do transfer if needed.
+ /** Idle, can be triggered to do transfer if needed. */
static final int TRANSFER_SPLASH_SCREEN_IDLE = 0;
- // requesting a copy from shell.
+
+ /** Requesting a copy from shell. */
static final int TRANSFER_SPLASH_SCREEN_COPYING = 1;
- // attach the splash screen view to activity.
+
+ /** Attach the splash screen view to activity. */
static final int TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT = 2;
- // client has taken over splash screen view.
+
+ /** Client has taken over splash screen view. */
static final int TRANSFER_SPLASH_SCREEN_FINISH = 3;
- @IntDef(prefix = { "TRANSFER_SPLASH_SCREEN_" }, value = {
+ @IntDef(prefix = {"TRANSFER_SPLASH_SCREEN_"}, value = {
TRANSFER_SPLASH_SCREEN_IDLE,
TRANSFER_SPLASH_SCREEN_COPYING,
TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT,
TRANSFER_SPLASH_SCREEN_FINISH,
})
- @interface TransferSplashScreenState {}
+ @interface TransferSplashScreenState {
+ }
// How long we wait until giving up transfer splash screen.
private static final int TRANSFER_SPLASH_SCREEN_TIMEOUT = 2000;
@@ -2196,6 +2201,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
removeStartingWindowAnimation(false /* prepareAnimation */);
}
+ /**
+ * Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} it should clean up any
+ * remaining reference to this {@link ActivityRecord}'s splash screen.
+ * @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
+ * @see SplashScreenView#remove()
+ */
+ void cleanUpSplashScreen() {
+ // We only clean up the splash screen if we were supposed to handle it. If it was
+ // transferred to another activity, the next one will handle the clean up.
+ if (mHandleExitSplashScreen && !startingMoved
+ && (mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_FINISH
+ || mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_IDLE)) {
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Cleaning splash screen token=%s", this);
+ mAtmService.mTaskOrganizerController.onAppSplashScreenViewRemoved(getTask());
+ }
+ }
+
void removeStartingWindow() {
removeStartingWindowAnimation(true /* prepareAnimation */);
}
@@ -3343,6 +3365,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
task.cleanUpActivityReferences(this);
clearLastParentBeforePip();
+ // Clean up the splash screen if it was still displayed.
+ cleanUpSplashScreen();
+
deferRelaunchUntilPaused = false;
frozenBeforeDestroy = false;
@@ -7504,10 +7529,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (getUid() == SYSTEM_UID) {
return false;
}
- // Do not sandbox to activity window bounds if the feature is disabled.
- if (mDisplayContent != null && !mDisplayContent.sandboxDisplayApis()) {
- return false;
- }
// Never apply sandboxing to an app that should be explicitly excluded from the config.
if (info != null && info.neverSandboxDisplayApis()) {
return false;
@@ -8086,6 +8107,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
setState(PAUSED, "relaunchActivityLocked");
}
+ // The activity may be waiting for stop, but that is no longer appropriate for it.
+ mTaskSupervisor.mStoppingActivities.remove(this);
+
configChangeFlags = 0;
deferRelaunchUntilPaused = false;
preserveWindowOnDeferredRelaunch = false;
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index eaebb6f1ce74..4acadb21b5e3 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -623,7 +623,11 @@ public class AppTransitionController {
siblings.add(current);
boolean canPromote = true;
- if (parent == null || !parent.canCreateRemoteAnimationTarget()) {
+ if (parent == null || !parent.canCreateRemoteAnimationTarget()
+ // We cannot promote the animation on Task's parent when the task is in
+ // clearing task in case the animating get stuck when performing the opening
+ // task that behind it.
+ || (current.asTask() != null && current.asTask().mInRemoveTask)) {
canPromote = false;
} else {
// In case a descendant of the parent belongs to the other group, we cannot promote
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 81992d8934ed..e0bae9d8de32 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -358,13 +358,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
boolean mIsSizeForced = false;
/**
- * Overridden display size and metrics to activity window bounds. Set via
- * "adb shell wm set-sandbox-display-apis". Default to true, since only disable for debugging.
- * @see WindowManagerService#setSandboxDisplayApis(int, boolean)
- */
- private boolean mSandboxDisplayApis = true;
-
- /**
* Overridden display density for current user. Initialized with {@link #mInitialDisplayDensity}
* but can be set from Settings or via shell command "adb shell wm density".
* @see WindowManagerService#setForcedDisplayDensityForUser(int, int, int)
@@ -5810,21 +5803,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return true;
}
- /**
- * Sets if Display APIs should be sandboxed to the activity window bounds.
- */
- void setSandboxDisplayApis(boolean sandboxDisplayApis) {
- mSandboxDisplayApis = sandboxDisplayApis;
- }
-
- /**
- * Returns {@code true} is Display APIs should be sandboxed to the activity window bounds,
- * {@code false} otherwise. Default to true, unless set for debugging purposes.
- */
- boolean sandboxDisplayApis() {
- return mSandboxDisplayApis;
- }
-
/** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 0112f797d937..f8238c1d154a 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -48,6 +48,7 @@ import android.os.Trace;
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
+import android.view.Display;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -163,16 +164,27 @@ class KeyguardController {
aodShowing ? 1 : 0,
mKeyguardGoingAway ? 1 : 0,
"setKeyguardShown");
+
+ // Update the task snapshot if the screen will not be turned off. To make sure that the
+ // unlocking animation can animate consistent content. The conditions are:
+ // - Either AOD or keyguard changes to be showing. So if the states change individually,
+ // the later one can be skipped to avoid taking snapshot again. While it still accepts
+ // if both of them change to show at the same time.
+ // - Keyguard was not going away. Because if it was, the closing transition is able to
+ // handle the snapshot.
+ // - The display state is ON. Because if AOD is not on or pulsing, the display state will
+ // be OFF or DOZE (the path of screen off may have handled it).
+ if (((aodShowing ^ keyguardShowing) || (aodShowing && aodChanged && keyguardChanged))
+ && !mKeyguardGoingAway && Display.isOnState(
+ mRootWindowContainer.getDefaultDisplay().getDisplayInfo().state)) {
+ mWindowManager.mTaskSnapshotController.snapshotForSleeping(DEFAULT_DISPLAY);
+ }
+
mKeyguardShowing = keyguardShowing;
mAodShowing = aodShowing;
if (aodChanged) {
// Ensure the new state takes effect.
mWindowManager.mWindowPlacerLocked.performSurfacePlacement();
- // If the device can enter AOD and keyguard at the same time, the screen will not be
- // turned off, so the snapshot needs to be refreshed when these states are changed.
- if (aodShowing && keyguardShowing && keyguardChanged) {
- mWindowManager.mTaskSnapshotController.snapshotForSleeping(DEFAULT_DISPLAY);
- }
}
if (keyguardChanged) {
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index eb7087cbc722..7174e68b06f4 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.graphics.Color;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -104,20 +105,12 @@ final class LetterboxConfiguration {
* com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
* the framework implementation will be used to determine the aspect ratio.
*/
+ @VisibleForTesting
void setFixedOrientationLetterboxAspectRatio(float aspectRatio) {
mFixedOrientationLetterboxAspectRatio = aspectRatio;
}
/**
- * Resets the aspect ratio of letterbox for fixed orientation to {@link
- * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}.
- */
- void resetFixedOrientationLetterboxAspectRatio() {
- mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
- }
-
- /**
* Gets the aspect ratio of letterbox for fixed orientation.
*/
float getFixedOrientationLetterboxAspectRatio() {
@@ -125,25 +118,6 @@ final class LetterboxConfiguration {
}
/**
- * Overrides corners raidus for activities presented in the letterbox mode. If given value < 0,
- * both it and a value of {@link
- * com.android.internal.R.integer.config_letterboxActivityCornersRadius} will be ignored and
- * and corners of the activity won't be rounded.
- */
- void setLetterboxActivityCornersRadius(int cornersRadius) {
- mLetterboxActivityCornersRadius = cornersRadius;
- }
-
- /**
- * Resets corners raidus for activities presented in the letterbox mode to {@link
- * com.android.internal.R.integer.config_letterboxActivityCornersRadius}.
- */
- void resetLetterboxActivityCornersRadius() {
- mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_letterboxActivityCornersRadius);
- }
-
- /**
* Whether corners of letterboxed activities are rounded.
*/
boolean isLetterboxActivityCornersRounded() {
@@ -166,25 +140,6 @@ final class LetterboxConfiguration {
return mLetterboxBackgroundColor;
}
-
- /**
- * Sets color of letterbox background which is used when {@link
- * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
- * fallback for other backfround types.
- */
- void setLetterboxBackgroundColor(Color color) {
- mLetterboxBackgroundColor = color;
- }
-
- /**
- * Resets color of letterbox background to {@link
- * com.android.internal.R.color.config_letterboxBackgroundColor}.
- */
- void resetLetterboxBackgroundColor() {
- mLetterboxBackgroundColor = Color.valueOf(mContext.getResources().getColor(
- com.android.internal.R.color.config_letterboxBackgroundColor));
- }
-
/**
* Gets {@link LetterboxBackgroundType} specified in {@link
* com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
@@ -194,19 +149,6 @@ final class LetterboxConfiguration {
return mLetterboxBackgroundType;
}
- /** Sets letterbox background type. */
- void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
- mLetterboxBackgroundType = backgroundType;
- }
-
- /**
- * Resets cletterbox background type to {@link
- * com.android.internal.R.integer.config_letterboxBackgroundType}.
- */
- void resetLetterboxBackgroundType() {
- mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
- }
-
/** Returns a string representing the given {@link LetterboxBackgroundType}. */
static String letterboxBackgroundTypeToString(
@LetterboxBackgroundType int backgroundType) {
@@ -236,27 +178,6 @@ final class LetterboxConfiguration {
}
/**
- * Overrides alpha of a black scrim shown over wallpaper for {@link
- * #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
- *
- * <p>If given value is < 0 or >= 1, both it and a value of {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
- * and 0.0 (transparent) is instead.
- */
- void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
- mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
- }
-
- /**
- * Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
- */
- void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
- mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
- }
-
- /**
* Gets alpha of a black scrim shown over wallpaper letterbox background.
*/
float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
@@ -264,28 +185,6 @@ final class LetterboxConfiguration {
}
/**
- * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
- * {@link mLetterboxBackgroundType}.
- *
- * <p> If given value <= 0, both it and a value of {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
- * and 0 is used instead.
- */
- void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
- mLetterboxBackgroundWallpaperBlurRadius = radius;
- }
-
- /**
- * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
- * mLetterboxBackgroundType} to {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
- */
- void resetLetterboxBackgroundWallpaperBlurRadius() {
- mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
- }
-
- /**
* Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
* mLetterboxBackgroundType}.
*/
@@ -312,17 +211,9 @@ final class LetterboxConfiguration {
* com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} are ignored and
* central position (0.5) is used.
*/
+ @VisibleForTesting
void setLetterboxHorizontalPositionMultiplier(float multiplier) {
mLetterboxHorizontalPositionMultiplier = multiplier;
}
- /**
- * Resets horizontal position of a center of the letterboxed app window to {@link
- * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
- */
- void resetLetterboxHorizontalPositionMultiplier() {
- mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
- }
-
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7af8d8bb5200..565f99f80890 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6689,24 +6689,26 @@ class Task extends WindowContainer<WindowContainer> {
}
}
- // TODO(185200798): Persist theme name instead of theme if
- int splashScreenThemeResId = options != null
- ? options.getSplashScreenThemeResId() : 0;
-
- // User can override the splashscreen theme. The theme name is used to persist
- // the setting, so if no theme is set in the ActivityOptions, we check if has
- // been persisted here.
- if (splashScreenThemeResId == 0) {
+ // Find the splash screen theme. User can override the persisted theme by
+ // ActivityOptions.
+ String splashScreenThemeResName = options != null
+ ? options.getSplashScreenThemeResName() : null;
+ if (splashScreenThemeResName == null || splashScreenThemeResName.isEmpty()) {
try {
- String themeName = mAtmService.getPackageManager()
+ splashScreenThemeResName = mAtmService.getPackageManager()
.getSplashScreenTheme(r.packageName, r.mUserId);
- if (themeName != null) {
- Context packageContext = mAtmService.mContext
- .createPackageContext(r.packageName, 0);
- splashScreenThemeResId = packageContext.getResources()
- .getIdentifier(themeName, null, null);
- }
- } catch (RemoteException | PackageManager.NameNotFoundException
+ } catch (RemoteException ignore) {
+ // Just use the default theme
+ }
+ }
+ int splashScreenThemeResId = 0;
+ if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) {
+ try {
+ final Context packageContext = mAtmService.mContext
+ .createPackageContext(r.packageName, 0);
+ splashScreenThemeResId = packageContext.getResources()
+ .getIdentifier(splashScreenThemeResName, null, null);
+ } catch (PackageManager.NameNotFoundException
| Resources.NotFoundException ignore) {
// Just use the default theme
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index f23028f6f67a..3a2ca80f2e12 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -43,6 +43,7 @@ import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
+import android.window.SplashScreenView;
import android.window.StartingWindowInfo;
import android.window.TaskAppearedInfo;
import android.window.TaskSnapshot;
@@ -215,6 +216,14 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
}
}
+ void onAppSplashScreenViewRemoved(Task task) {
+ try {
+ mTaskOrganizer.onAppSplashScreenViewRemoved(task.mTaskId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception sending onAppSplashScreenViewRemoved callback", e);
+ }
+ }
+
SurfaceControl prepareLeash(Task task, String reason) {
return new SurfaceControl(task.getSurfaceControl(), reason);
}
@@ -314,6 +323,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
mOrganizer.copySplashScreenView(t);
}
+ public void onAppSplashScreenViewRemoved(Task t) {
+ mOrganizer.onAppSplashScreenViewRemoved(t);
+ }
+
/**
* Register this task with this state, but doesn't trigger the task appeared callback to
* the organizer.
@@ -566,6 +579,22 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
return true;
}
+ /**
+ * Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
+ * removed the splash screen view.
+ * @see com.android.wm.shell.ShellTaskOrganizer#onAppSplashScreenViewRemoved(int)
+ * @see SplashScreenView#remove()
+ */
+ public void onAppSplashScreenViewRemoved(Task task) {
+ final Task rootTask = task.getRootTask();
+ if (rootTask == null || rootTask.mTaskOrganizer == null) {
+ return;
+ }
+ final TaskOrganizerState state =
+ mTaskOrganizerStates.get(rootTask.mTaskOrganizer.asBinder());
+ state.onAppSplashScreenViewRemoved(task);
+ }
+
void onTaskAppeared(ITaskOrganizer organizer, Task task) {
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
if (state != null && state.addTask(task)) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c1e29ebc4703..e9dd521670a9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2910,6 +2910,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ " for the display " + displayId + " that does not exist.");
return;
}
+ remoteAnimationAdapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
displayContent.mAppTransition.overridePendingAppTransitionRemote(
remoteAnimationAdapter);
}
@@ -5390,25 +5391,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- void setSandboxDisplayApis(int displayId, boolean sandboxDisplayApis) {
- if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
- }
-
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mGlobalLock) {
- final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
- if (displayContent != null) {
- displayContent.setSandboxDisplayApis(sandboxDisplayApis);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
/** The global settings only apply to default display. */
private boolean applyForcedPropertiesForDefaultDisplay() {
boolean changed = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index d59654949a27..a94fd074ff2e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -19,12 +19,6 @@ package com.android.server.wm;
import static android.os.Build.IS_USER;
import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
-
-import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.ParcelFileDescriptor;
@@ -42,7 +36,6 @@ import com.android.internal.os.ByteTransferPipe;
import com.android.internal.protolog.ProtoLogImpl;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
-import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import java.io.IOException;
import java.io.PrintWriter;
@@ -65,12 +58,10 @@ public class WindowManagerShellCommand extends ShellCommand {
// Internal service impl -- must perform security checks before touching.
private final WindowManagerService mInternal;
- private final LetterboxConfiguration mLetterboxConfiguration;
public WindowManagerShellCommand(WindowManagerService service) {
mInterface = service;
mInternal = service;
- mLetterboxConfiguration = service.mLetterboxConfiguration;
}
@Override
@@ -122,14 +113,6 @@ public class WindowManagerShellCommand extends ShellCommand {
return runGetIgnoreOrientationRequest(pw);
case "dump-visible-window-views":
return runDumpVisibleWindowViews(pw);
- case "set-letterbox-style":
- return runSetLetterboxStyle(pw);
- case "get-letterbox-style":
- return runGetLetterboxStyle(pw);
- case "reset-letterbox-style":
- return runResetLetterboxStyle(pw);
- case "set-sandbox-display-apis":
- return runSandboxDisplayApis(pw);
case "set-multi-window-config":
return runSetMultiWindowConfig();
case "get-multi-window-config":
@@ -348,37 +331,6 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0;
}
- /**
- * Override display size and metrics to reflect the DisplayArea of the calling activity.
- */
- private int runSandboxDisplayApis(PrintWriter pw) throws RemoteException {
- int displayId = Display.DEFAULT_DISPLAY;
- String arg = getNextArgRequired();
- if ("-d".equals(arg)) {
- displayId = Integer.parseInt(getNextArgRequired());
- arg = getNextArgRequired();
- }
-
- final boolean sandboxDisplayApis;
- switch (arg) {
- case "true":
- case "1":
- sandboxDisplayApis = true;
- break;
- case "false":
- case "0":
- sandboxDisplayApis = false;
- break;
- default:
- getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we "
- + "get " + arg);
- return -1;
- }
-
- mInternal.setSandboxDisplayApis(displayId, sandboxDisplayApis);
- return 0;
- }
-
private int runDismissKeyguard(PrintWriter pw) throws RemoteException {
mInterface.dismissKeyguard(null /* callback */, null /* message */);
return 0;
@@ -596,231 +548,6 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0;
}
- private int runSetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException {
- final float aspectRatio;
- try {
- String arg = getNextArgRequired();
- aspectRatio = Float.parseFloat(arg);
- } catch (NumberFormatException e) {
- getErrPrintWriter().println("Error: bad aspect ratio format " + e);
- return -1;
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset' or aspect ratio should be provided as an argument " + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(aspectRatio);
- }
- return 0;
- }
-
- private int runSetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException {
- final int cornersRadius;
- try {
- String arg = getNextArgRequired();
- cornersRadius = Integer.parseInt(arg);
- } catch (NumberFormatException e) {
- getErrPrintWriter().println("Error: bad corners radius format " + e);
- return -1;
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset' or corners radius should be provided as an argument " + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setLetterboxActivityCornersRadius(cornersRadius);
- }
- return 0;
- }
-
- private int runSetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
- @LetterboxBackgroundType final int backgroundType;
- try {
- String arg = getNextArgRequired();
- switch (arg) {
- case "solid_color":
- backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR;
- break;
- case "app_color_background":
- backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
- break;
- case "app_color_background_floating":
- backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
- break;
- case "wallpaper":
- backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
- break;
- default:
- getErrPrintWriter().println(
- "Error: 'reset', 'solid_color', 'app_color_background' or "
- + "'wallpaper' should be provided as an argument");
- return -1;
- }
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset', 'solid_color', 'app_color_background' or "
- + "'wallpaper' should be provided as an argument" + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setLetterboxBackgroundType(backgroundType);
- }
- return 0;
- }
-
- private int runSetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
- final Color color;
- try {
- String arg = getNextArgRequired();
- color = Color.valueOf(Color.parseColor(arg));
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset' or color in #RRGGBB format should be provided as "
- + "an argument " + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setLetterboxBackgroundColor(color);
- }
- return 0;
- }
-
- private int runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
- throws RemoteException {
- final int radius;
- try {
- String arg = getNextArgRequired();
- radius = Integer.parseInt(arg);
- } catch (NumberFormatException e) {
- getErrPrintWriter().println("Error: blur radius format " + e);
- return -1;
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset' or blur radius should be provided as an argument " + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadius(radius);
- }
- return 0;
- }
-
- private int runSetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)
- throws RemoteException {
- final float alpha;
- try {
- String arg = getNextArgRequired();
- alpha = Float.parseFloat(arg);
- } catch (NumberFormatException e) {
- getErrPrintWriter().println("Error: bad alpha format " + e);
- return -1;
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset' or alpha should be provided as an argument " + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
- }
- return 0;
- }
-
- private int runSeLetterboxHorizontalPositionMultiplier(PrintWriter pw) throws RemoteException {
- final float multiplier;
- try {
- String arg = getNextArgRequired();
- multiplier = Float.parseFloat(arg);
- } catch (NumberFormatException e) {
- getErrPrintWriter().println("Error: bad multiplier format " + e);
- return -1;
- } catch (IllegalArgumentException e) {
- getErrPrintWriter().println(
- "Error: 'reset' or multiplier should be provided as an argument " + e);
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(multiplier);
- }
- return 0;
- }
-
- private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
- if (peekNextArg() == null) {
- getErrPrintWriter().println("Error: No arguments provided.");
- }
- while (peekNextArg() != null) {
- String arg = getNextArg();
- switch (arg) {
- case "--aspectRatio":
- runSetFixedOrientationLetterboxAspectRatio(pw);
- break;
- case "--cornerRadius":
- runSetLetterboxActivityCornersRadius(pw);
- break;
- case "--backgroundType":
- runSetLetterboxBackgroundType(pw);
- break;
- case "--backgroundColor":
- runSetLetterboxBackgroundColor(pw);
- break;
- case "--wallpaperBlurRadius":
- runSetLetterboxBackgroundWallpaperBlurRadius(pw);
- break;
- case "--wallpaperDarkScrimAlpha":
- runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
- break;
- case "--horizontalPositionMultiplier":
- runSeLetterboxHorizontalPositionMultiplier(pw);
- break;
- default:
- getErrPrintWriter().println(
- "Error: Unrecognized letterbox style option: " + arg);
- return -1;
- }
- }
- return 0;
- }
-
- private int runResetLetterboxStyle(PrintWriter pw) throws RemoteException {
- if (peekNextArg() == null) {
- resetLetterboxStyle();
- }
- synchronized (mInternal.mGlobalLock) {
- while (peekNextArg() != null) {
- String arg = getNextArg();
- switch (arg) {
- case "aspectRatio":
- mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
- break;
- case "cornerRadius":
- mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
- break;
- case "backgroundType":
- mLetterboxConfiguration.resetLetterboxBackgroundType();
- break;
- case "backgroundColor":
- mLetterboxConfiguration.resetLetterboxBackgroundColor();
- break;
- case "wallpaperBlurRadius":
- mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
- break;
- case "wallpaperDarkScrimAlpha":
- mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
- break;
- case "horizontalPositionMultiplier":
- mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
- break;
- default:
- getErrPrintWriter().println(
- "Error: Unrecognized letterbox style option: " + arg);
- return -1;
- }
- }
- }
- return 0;
- }
-
private int runSetMultiWindowConfig() {
if (peekNextArg() == null) {
getErrPrintWriter().println("Error: No arguments provided.");
@@ -895,40 +622,6 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0;
}
- private void resetLetterboxStyle() {
- synchronized (mInternal.mGlobalLock) {
- mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
- mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
- mLetterboxConfiguration.resetLetterboxBackgroundType();
- mLetterboxConfiguration.resetLetterboxBackgroundColor();
- mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
- mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
- mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
- }
- }
-
- private int runGetLetterboxStyle(PrintWriter pw) throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- pw.println("Corner radius: "
- + mLetterboxConfiguration.getLetterboxActivityCornersRadius());
- pw.println("Horizontal position multiplier: "
- + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
- pw.println("Aspect ratio: "
- + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
-
- pw.println("Background type: "
- + LetterboxConfiguration.letterboxBackgroundTypeToString(
- mLetterboxConfiguration.getLetterboxBackgroundType()));
- pw.println(" Background color: " + Integer.toHexString(
- mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb()));
- pw.println(" Wallpaper blur radius: "
- + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
- pw.println(" Wallpaper dark scrim alpha: "
- + mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
- }
- return 0;
- }
-
private int runReset(PrintWriter pw) throws RemoteException {
int displayId = getDisplayId(getNextArg());
@@ -953,12 +646,6 @@ public class WindowManagerShellCommand extends ShellCommand {
// set-ignore-orientation-request
mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */);
- // set-letterbox-style
- resetLetterboxStyle();
-
- // set-sandbox-display-apis
- mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true);
-
// set-multi-window-config
runResetMultiWindowConfig();
@@ -993,12 +680,7 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]");
pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] ");
pw.println(" If app requested orientation should be ignored.");
- pw.println(" set-sandbox-display-apis [true|1|false|0]");
- pw.println(" Sets override of Display APIs getRealSize / getRealMetrics to reflect ");
- pw.println(" DisplayArea of the activity, or the window bounds if in letterbox or");
- pw.println(" Size Compat Mode.");
- printLetterboxHelp(pw);
printMultiWindowConfigHelp(pw);
pw.println(" reset [-d DISPLAY_ID]");
@@ -1011,49 +693,6 @@ public class WindowManagerShellCommand extends ShellCommand {
}
}
- private void printLetterboxHelp(PrintWriter pw) {
- pw.println(" set-letterbox-style");
- pw.println(" Sets letterbox style using the following options:");
- pw.println(" --aspectRatio aspectRatio");
- pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= "
- + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
- pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will");
- pw.println(" be ignored and framework implementation will determine aspect ratio.");
- pw.println(" --cornerRadius radius");
- pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,");
- pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be");
- pw.println(" ignored and corners of the activity won't be rounded.");
- pw.println(" --backgroundType [reset|solid_color|app_color_background");
- pw.println(" |app_color_background_floating|wallpaper]");
- pw.println(" Type of background used in the letterbox mode.");
- pw.println(" --backgroundColor color");
- pw.println(" Color of letterbox which is be used when letterbox background type");
- pw.println(" is 'solid-color'. Use (set)get-letterbox-style to check and control");
- pw.println(" letterbox background type. See Color#parseColor for allowed color");
- pw.println(" formats (#RRGGBB and some colors by name, e.g. magenta or olive).");
- pw.println(" --wallpaperBlurRadius radius");
- pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0");
- pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius");
- pw.println(" are ignored and 0 is used.");
- pw.println(" --wallpaperDarkScrimAlpha alpha");
- pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'");
- pw.println(" letterbox background. If alpha < 0 or >= 1 both it and");
- pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored");
- pw.println(" and 0.0 (transparent) is used instead.");
- pw.println(" --horizontalPositionMultiplier multiplier");
- pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,");
- pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
- pw.println(" are ignored and central position (0.5) is used.");
- pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
- pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
- pw.println(" |horizontalPositionMultiplier]");
- pw.println(" Resets overrides to default values for specified properties separated");
- pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
- pw.println(" If no arguments provided, all values will be reset.");
- pw.println(" get-letterbox-style");
- pw.println(" Prints letterbox style configuration.");
- }
-
private void printMultiWindowConfigHelp(PrintWriter pw) {
pw.println(" set-multi-window-config");
pw.println(" Sets options to determine if activity should be shown in multi window:");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 03762b3ee8bf..07ac73b05706 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -61,6 +61,7 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NOT_MAGNIFIABLE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
@@ -5385,6 +5386,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|| mAttrs.type == TYPE_NAVIGATION_BAR_PANEL) {
return false;
}
+ if ((mAttrs.privateFlags & PRIVATE_FLAG_NOT_MAGNIFIABLE) != 0) {
+ return false;
+ }
return true;
}
@@ -5508,7 +5512,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mSurfacePlacementNeeded = false;
transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
mSurfacePosition);
- mSurfacePosition.offset(mXOffset, mYOffset);
+
+ if (mWallpaperScale != 1f) {
+ DisplayInfo displayInfo = getDisplayInfo();
+ Matrix matrix = mTmpMatrix;
+ matrix.setTranslate(mXOffset, mYOffset);
+ matrix.postScale(mWallpaperScale, mWallpaperScale, displayInfo.logicalWidth / 2f,
+ displayInfo.logicalHeight / 2f);
+ matrix.getValues(mTmpMatrixArray);
+ mSurfacePosition.offset(Math.round(mTmpMatrixArray[Matrix.MTRANS_X]),
+ Math.round(mTmpMatrixArray[Matrix.MTRANS_Y]));
+ } else {
+ mSurfacePosition.offset(mXOffset, mYOffset);
+ }
// Freeze position while we're unrotated, so the surface remains at the position it was
// prior to the rotation.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0128d350bd10..2439760e3f67 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -169,6 +169,7 @@ import android.app.admin.DevicePolicyManager.OperationSafetyReason;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.DevicePolicyManager.PersonalAppsSuspensionReason;
import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.DevicePolicyManagerLiteInternal;
import android.app.admin.DevicePolicySafetyChecker;
import android.app.admin.DeviceStateCache;
import android.app.admin.FactoryResetProtectionPolicy;
@@ -1748,6 +1749,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
mTransferOwnershipMetadataManager = mInjector.newTransferOwnershipMetadataManager();
mBugreportCollectionManager = new RemoteBugreportManager(this, mInjector);
+ // "Lite" interface is available even when the device doesn't have the feature
+ LocalServices.addService(DevicePolicyManagerLiteInternal.class, mLocalService);
if (!mHasFeature) {
// Skip the rest of the initialization
mSetupContentObserver = null;
@@ -6832,7 +6835,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void wipeDataWithReason(int flags, String wipeReasonForUser,
boolean calledOnParentInstance) {
- if (!mHasFeature) {
+ if (!mHasFeature && !hasCallingOrSelfPermission(permission.MASTER_CLEAR)) {
return;
}
final CallerIdentity caller = getCallerIdentity();
@@ -8027,6 +8030,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
inForeground = true;
receiverComponent = resolveDelegateReceiver(
DELEGATION_SECURITY_LOGGING, action, userId);
+ // STOPSHIP(b/185004808): remove excessive log.
+ Slogf.d(LOG_TAG, "Delegate for security logs broadcast: " + receiverComponent);
}
if (receiverComponent == null) {
receiverComponent = getOwnerComponent(userId);
@@ -12612,7 +12617,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@VisibleForTesting
- final class LocalService extends DevicePolicyManagerInternal {
+ final class LocalService extends DevicePolicyManagerInternal
+ implements DevicePolicyManagerLiteInternal {
private List<OnCrossProfileWidgetProvidersChangeListener> mWidgetProviderListeners;
@Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java b/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java
index 86437a27a64d..1cbc634b7152 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java
@@ -21,7 +21,7 @@ import static android.app.admin.DevicePolicyManager.operationToString;
import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
import android.app.admin.DevicePolicyManager.OperationSafetyReason;
-import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.DevicePolicyManagerLiteInternal;
import android.app.admin.DevicePolicySafetyChecker;
import android.os.Handler;
import android.os.Looper;
@@ -80,8 +80,8 @@ final class OneTimeSafetyChecker implements DevicePolicySafetyChecker {
+ ", should be " + operationToString(mOperation));
}
String reasonName = operationSafetyReasonToString(reason);
- DevicePolicyManagerInternal dpmi = LocalServices
- .getService(DevicePolicyManagerInternal.class);
+ DevicePolicyManagerLiteInternal dpmi = LocalServices
+ .getService(DevicePolicyManagerLiteInternal.class);
Slog.i(TAG, "notifying " + reasonName + " is UNSAFE");
dpmi.notifyUnsafeOperationStateChanged(this, reason, /* isSafe= */ false);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
index c29de905d370..0741c81bb528 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
@@ -64,7 +64,7 @@ class SecurityLogMonitor implements Runnable {
mLastForceNanos = System.nanoTime();
}
- private static final boolean DEBUG = false; // STOPSHIP if true.
+ private static final boolean DEBUG = true; // STOPSHIP if true.
private static final String TAG = "SecurityLogMonitor";
/**
* Each log entry can hold up to 4K bytes (but as of {@link android.os.Build.VERSION_CODES#N}
@@ -427,7 +427,7 @@ class SecurityLogMonitor implements Runnable {
while (!Thread.currentThread().isInterrupted()) {
try {
final boolean force = mForceSemaphore.tryAcquire(POLLING_INTERVAL_MS, MILLISECONDS);
-
+ if (DEBUG) Slog.d(TAG, "Retrieving next batch, force=" + force);
getNextBatch(newLogs);
mLock.lockInterruptibly();
@@ -469,6 +469,11 @@ class SecurityLogMonitor implements Runnable {
return;
}
final int logSize = mPendingLogs.size();
+ if (DEBUG) {
+ Slog.d(TAG, String.format(
+ "notifyDeviceOwnerOrProfileOwnerIfNeeded, size: %d now: %d next: %d",
+ logSize, SystemClock.elapsedRealtime(), mNextAllowedRetrievalTimeMillis));
+ }
if (logSize >= BUFFER_ENTRIES_NOTIFICATION_LEVEL || (force && logSize > 0)) {
// Allow DO to retrieve logs if too many pending logs or if forced.
if (!mAllowedToRetrieve) {
@@ -507,6 +512,7 @@ class SecurityLogMonitor implements Runnable {
synchronized (mForceSemaphore) {
final long toWaitNanos = mLastForceNanos + FORCE_FETCH_THROTTLE_NS - nowNanos;
if (toWaitNanos > 0) {
+ if (DEBUG) Slog.d(TAG, "Forcing security logs throttled");
return NANOSECONDS.toMillis(toWaitNanos) + 1; // Round up.
}
mLastForceNanos = nowNanos;
@@ -515,6 +521,7 @@ class SecurityLogMonitor implements Runnable {
if (mForceSemaphore.availablePermits() == 0) {
mForceSemaphore.release();
}
+ if (DEBUG) Slog.d(TAG, "Forcing security logs semaphore released");
return 0;
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index d5e1cd6e0415..280204dfd481 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -58,7 +58,8 @@ import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PERMISSION;
import static com.android.server.alarm.AlarmManagerService.ACTIVE_INDEX;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.APP_STANDBY_BUCKET_CHANGED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.CHARGING_STATUS_CHANGED;
-import static com.android.server.alarm.AlarmManagerService.AlarmHandler.EXACT_ALARM_DENY_LIST_CHANGED;
+import static com.android.server.alarm.AlarmManagerService.AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_ADDED;
+import static com.android.server.alarm.AlarmManagerService.AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_ALARMS;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
@@ -103,10 +104,8 @@ import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -155,6 +154,8 @@ import com.android.server.AppStateTrackerImpl;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.usage.AppStandbyInternal;
@@ -175,6 +176,7 @@ import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
@@ -370,8 +372,9 @@ public class AlarmManagerServiceTest {
.mockStatic(LocalServices.class)
.spyStatic(Looper.class)
.mockStatic(MetricsHelper.class)
- .mockStatic(Settings.Global.class)
+ .mockStatic(PermissionManagerService.class)
.mockStatic(ServiceManager.class)
+ .mockStatic(Settings.Global.class)
.mockStatic(SystemProperties.class)
.spyStatic(UserHandle.class)
.strictness(Strictness.WARN)
@@ -394,7 +397,7 @@ public class AlarmManagerServiceTest {
doCallRealMethod().when((MockedVoidMethod) () ->
LocalServices.addService(eq(AlarmManagerInternal.class), any()));
doCallRealMethod().when(() -> LocalServices.getService(AlarmManagerInternal.class));
- doReturn(false).when(() -> UserHandle.isCore(TEST_CALLING_UID));
+ doReturn(false).when(() -> UserHandle.isCore(anyInt()));
when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE),
eq(TEST_CALLING_USER), anyLong())).thenReturn(STANDBY_BUCKET_ACTIVE);
doReturn(Looper.getMainLooper()).when(Looper::myLooper);
@@ -983,8 +986,7 @@ public class AlarmManagerServiceTest {
verify(mService.mHandler, atLeastOnce()).sendMessageAtTime(messageCaptor.capture(),
anyLong());
final Message lastMessage = messageCaptor.getValue();
- assertEquals("Unexpected message send to handler", lastMessage.what,
- what);
+ assertEquals("Unexpected message send to handler", what, lastMessage.what);
mService.mHandler.handleMessage(lastMessage);
}
@@ -1876,6 +1878,8 @@ public class AlarmManagerServiceTest {
@Test
public void hasScheduleExactAlarmBinderCallNotDenyListed() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
mockExactAlarmPermissionGrant(true, false, MODE_DEFAULT);
assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
@@ -1891,6 +1895,8 @@ public class AlarmManagerServiceTest {
@Test
public void hasScheduleExactAlarmBinderCallDenyListed() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
mockExactAlarmPermissionGrant(true, true, MODE_ERRORED);
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
@@ -1905,7 +1911,25 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void hasScheduleExactAlarmBinderCallChangeDisabled() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
+
+ mockExactAlarmPermissionGrant(true, false, MODE_DEFAULT);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockExactAlarmPermissionGrant(true, true, MODE_ALLOWED);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+ }
+
+ private void mockChangeEnabled(long changeId, boolean enabled) {
+ doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(),
+ any(UserHandle.class)));
+ }
+
+ @Test
public void hasScheduleExactAlarmBinderCallNotDeclared() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
mockExactAlarmPermissionGrant(false, false, MODE_DEFAULT);
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
@@ -1918,9 +1942,7 @@ public class AlarmManagerServiceTest {
@Test
public void noPermissionCheckWhenChangeDisabled() throws RemoteException {
- doReturn(false).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
// alarm clock
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, 0,
@@ -1946,9 +1968,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactBinderCallWhenChangeDisabled() throws Exception {
- doReturn(false).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
@@ -1963,9 +1983,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactAllowWhileIdleBinderCallWhenChangeDisabled() throws Exception {
- doReturn(false).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
@@ -1985,9 +2003,7 @@ public class AlarmManagerServiceTest {
@Test
public void inexactAllowWhileIdleBinderCallWhenChangeDisabled() throws Exception {
- doReturn(false).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_HEURISTIC, 0,
@@ -2006,9 +2022,7 @@ public class AlarmManagerServiceTest {
@Test
public void alarmClockBinderCallWhenChangeDisabled() throws Exception {
- doReturn(false).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
final PendingIntent alarmPi = getNewMockPendingIntent();
final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
@@ -2023,9 +2037,7 @@ public class AlarmManagerServiceTest {
@Test
public void alarmClockBinderCall() throws RemoteException {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockExactAlarmPermissionGrant(true, false, MODE_ALLOWED);
@@ -2060,7 +2072,6 @@ public class AlarmManagerServiceTest {
} else {
setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, "");
}
-
when(mAppOpsManager.checkOpNoThrow(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID,
TEST_CALLING_PACKAGE)).thenReturn(mode);
}
@@ -2068,9 +2079,7 @@ public class AlarmManagerServiceTest {
@Test
public void alarmClockBinderCallWithoutPermission() throws RemoteException {
setDeviceConfigBoolean(KEY_CRASH_NON_CLOCK_APPS, true);
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
@@ -2089,9 +2098,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactBinderCallWithPermission() throws RemoteException {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockExactAlarmPermissionGrant(true, false, MODE_ALLOWED);
final PendingIntent alarmPi = getNewMockPendingIntent();
@@ -2115,9 +2122,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactBinderCallWithAllowlist() throws RemoteException {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
// If permission is denied, only then allowlist will be checked.
mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
@@ -2137,9 +2142,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactAllowWhileIdleBinderCallWithPermission() throws RemoteException {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockExactAlarmPermissionGrant(true, false, MODE_ALLOWED);
final PendingIntent alarmPi = getNewMockPendingIntent();
@@ -2162,9 +2165,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactAllowWhileIdleBinderCallWithAllowlist() throws RemoteException {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
// If permission is denied, only then allowlist will be checked.
mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
@@ -2191,9 +2192,7 @@ public class AlarmManagerServiceTest {
@Test
public void exactBinderCallsWithoutPermissionWithoutAllowlist() throws RemoteException {
setDeviceConfigBoolean(KEY_CRASH_NON_CLOCK_APPS, true);
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
@@ -2220,9 +2219,7 @@ public class AlarmManagerServiceTest {
public void inexactAllowWhileIdleBinderCall() throws RemoteException {
// Both permission and power exemption status don't matter for these alarms.
// We only want to test that the flags and idleOptions are correct.
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 4321, WINDOW_HEURISTIC, 0,
@@ -2244,9 +2241,7 @@ public class AlarmManagerServiceTest {
@Test
public void binderCallWithUserAllowlist() throws RemoteException {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
@@ -2266,10 +2261,7 @@ public class AlarmManagerServiceTest {
@Test
public void minWindowChangeEnabled() {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(
- eq(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true);
final int minWindow = 73;
setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
@@ -2315,17 +2307,16 @@ public class AlarmManagerServiceTest {
@Test
public void minWindowChangeDisabled() {
- doReturn(false).when(
- () -> CompatChanges.isChangeEnabled(
- eq(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, false);
final long minWindow = 73;
+ final long futurity = 10_000;
setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
// 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
for (int window = 1; window <= minWindow; window++) {
final PendingIntent pi = getNewMockPendingIntent();
- setTestAlarm(ELAPSED_REALTIME, 0, window, pi, 0, 0, TEST_CALLING_UID, null);
+ setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, pi, 0, 0,
+ TEST_CALLING_UID, null);
assertEquals(1, mService.mAlarmStore.size());
final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0);
@@ -2334,21 +2325,61 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void minWindowExempted() {
+ mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true);
+ final long minWindow = 73;
+ final long futurity = 10_000;
+
+ setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
+
+ final int coreUid = 2312;
+ doReturn(true).when(() -> UserHandle.isCore(coreUid));
+
+ final int allowlisted = 54239;
+ when(mDeviceIdleInternal.isAppOnWhitelist(UserHandle.getAppId(allowlisted))).thenReturn(
+ true);
+
+ for (final int callingUid : new int[]{SYSTEM_UI_UID, coreUid, coreUid}) {
+ // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
+ for (int window = 1; window <= minWindow; window++) {
+ final PendingIntent pi = getNewMockPendingIntent();
+ setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, pi, 0, 0,
+ callingUid, null);
+
+ assertEquals(1, mService.mAlarmStore.size());
+ final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0);
+ assertEquals(window, a.windowLength);
+ }
+ }
+
+ // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
+ for (int window = 1; window <= minWindow; window++) {
+ final PendingIntent pi = getNewMockPendingIntent();
+ setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, pi, 0, 0,
+ TEST_CALLING_UID, null);
+
+ assertEquals(1, mService.mAlarmStore.size());
+ final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0);
+ assertEquals(minWindow, a.windowLength);
+ }
+ }
+
+ @Test
public void minWindowPriorityAlarm() {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(
- eq(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true);
final long minWindow = 73;
+ final long futurity = 10_000;
setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
// 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
for (int window = 1; window <= minWindow; window++) {
- setPrioritizedAlarm(ELAPSED_REALTIME, 0, window, new IAlarmListener.Stub() {
- @Override
- public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
- }
- });
+ setPrioritizedAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window,
+ new IAlarmListener.Stub() {
+ @Override
+ public void doAlarm(IAlarmCompleteListener callback)
+ throws RemoteException {
+ }
+ });
assertEquals(1, mService.mAlarmStore.size());
final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0);
assertEquals(window, a.windowLength);
@@ -2356,76 +2387,135 @@ public class AlarmManagerServiceTest {
}
@Test
- public void denyListPackagesAdded() {
+ public void denyListChanged() {
mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{"p1", "p2", "p3"});
+ when(mActivityManagerInternal.getStartedUserIds()).thenReturn(EmptyArray.INT);
+
setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, "p2,p4,p5");
- assertAndHandleMessageSync(EXACT_ALARM_DENY_LIST_CHANGED);
+
+ final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mService.mHandler, times(2)).sendMessageAtTime(messageCaptor.capture(),
+ anyLong());
+
+ final List<Message> messages = messageCaptor.getAllValues();
+ for (final Message msg : messages) {
+ assertTrue("Unwanted message sent to handler: " + msg.what,
+ msg.what == EXACT_ALARM_DENY_LIST_PACKAGES_ADDED
+ || msg.what == EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED);
+ mService.mHandler.handleMessage(msg);
+ }
ArraySet<String> added = new ArraySet<>(new String[]{"p4", "p5"});
- verify(mService).handlePackagesAddedToExactAlarmsDenyListLocked(eq(added));
+ verify(mService).handleChangesToExactAlarmDenyList(eq(added), eq(true));
+
+ ArraySet<String> removed = new ArraySet<>(new String[]{"p1", "p3"});
+ verify(mService).handleChangesToExactAlarmDenyList(eq(removed), eq(false));
}
@Test
- public void denyListPackagesRemoved() {
- clearInvocations(mService.mHandler);
- mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{"p1", "p2", "p3"});
- setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, "p2");
- verifyNoMoreInteractions(mService.mHandler);
+ public void permissionGrantedDueToDenyList() {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
+ final String[] packages = {"example.package.1", "example.package.2"};
+
+ final int appId1 = 232;
+ final int appId2 = 431;
+
+ final int userId1 = 42;
+ final int userId2 = 53;
+
+ registerAppIds(packages, new Integer[]{appId1, appId2});
+
+ when(mActivityManagerInternal.getStartedUserIds()).thenReturn(new int[]{userId1, userId2});
+
+ when(mPermissionManagerInternal.getAppOpPermissionPackages(
+ SCHEDULE_EXACT_ALARM)).thenReturn(packages);
+ mService.refreshExactAlarmCandidates();
+
+ final long allowListDuration = 53442;
+ when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(
+ allowListDuration);
+
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId1), MODE_ALLOWED);
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId1), MODE_DEFAULT);
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId2), MODE_IGNORED);
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId2), MODE_ERRORED);
+
+ mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), false);
+
+ // No permission revoked.
+ verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(anyInt(), anyString());
+
+ // Permission got granted only for (appId1, userId2).
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ final ArgumentCaptor<UserHandle> userCaptor = ArgumentCaptor.forClass(UserHandle.class);
+
+ verify(mMockContext).sendBroadcastAsUser(intentCaptor.capture(), userCaptor.capture(),
+ isNull(), bundleCaptor.capture());
+
+ assertEquals(userId2, userCaptor.getValue().getIdentifier());
+
+ // Validate the intent.
+ assertEquals(AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
+ intentCaptor.getValue().getAction());
+ assertEquals(packages[0], intentCaptor.getValue().getPackage());
+
+ // Validate the options.
+ final BroadcastOptions bOptions = new BroadcastOptions(bundleCaptor.getValue());
+ assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+ bOptions.getTemporaryAppAllowlistType());
+ assertEquals(allowListDuration, bOptions.getTemporaryAppAllowlistDuration());
+ assertEquals(PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
+ bOptions.getTemporaryAppAllowlistReasonCode());
}
@Test
- public void removeExactAlarmsOnPackageAddedToDenyList() {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ public void permissionRevokedDueToDenyList() {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
- // basic exact alarm
- setTestAlarm(ELAPSED_REALTIME, 1, 0, getNewMockPendingIntent(), 0, 0, TEST_CALLING_UID,
- null);
- // exact and allow-while-idle alarm
- setTestAlarm(ELAPSED_REALTIME, 2, 0, getNewMockPendingIntent(), 0, FLAG_ALLOW_WHILE_IDLE,
- TEST_CALLING_UID, null);
- // alarm clock
- setWakeFromIdle(RTC_WAKEUP, 3, getNewMockPendingIntent());
+ final String[] packages = {"example.package.1", "example.package.2"};
- final PendingIntent inexact = getNewMockPendingIntent();
- setTestAlarm(ELAPSED_REALTIME, 4, 10, inexact, 0, 0, TEST_CALLING_UID, null);
+ final int appId1 = 232;
+ final int appId2 = 431;
- final PendingIntent inexactAwi = getNewMockPendingIntent();
- setTestAlarm(ELAPSED_REALTIME, 5, 10, inexactAwi, 0, FLAG_ALLOW_WHILE_IDLE,
- TEST_CALLING_UID, null);
+ final int userId1 = 42;
+ final int userId2 = 53;
- final String differentPackage = "different.package";
- final PendingIntent exactButDifferentPackage = getNewMockPendingIntent(
- TEST_CALLING_UID, differentPackage);
- setTestAlarm(ELAPSED_REALTIME, 6, 0, exactButDifferentPackage, 0, 0,
- TEST_CALLING_UID, differentPackage, null);
- assertEquals(6, mService.mAlarmStore.size());
+ registerAppIds(packages, new Integer[]{appId1, appId2});
- when(mAppOpsManager.checkOpNoThrow(eq(OP_SCHEDULE_EXACT_ALARM), anyInt(),
- anyString())).thenReturn(MODE_DEFAULT);
- setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, TEST_CALLING_PACKAGE);
- assertAndHandleMessageSync(EXACT_ALARM_DENY_LIST_CHANGED);
- verify(mService).handlePackagesAddedToExactAlarmsDenyListLocked(
- argThat(set -> (set.size() == 1 && set.contains(TEST_CALLING_PACKAGE))));
+ when(mActivityManagerInternal.getStartedUserIds()).thenReturn(new int[]{userId1, userId2});
- final ArrayList<Alarm> remaining = mService.mAlarmStore.asList();
- assertEquals(3, remaining.size());
- assertTrue("Basic inexact alarm removed",
- remaining.removeIf(a -> a.matches(inexact, null)));
- assertTrue("Inexact allow-while-idle alarm removed",
- remaining.removeIf(a -> a.matches(inexactAwi, null)));
- assertTrue("Alarm from different package removed",
- remaining.removeIf(a -> a.matches(exactButDifferentPackage, null)));
+ when(mPermissionManagerInternal.getAppOpPermissionPackages(
+ SCHEDULE_EXACT_ALARM)).thenReturn(packages);
+ mService.refreshExactAlarmCandidates();
- // Mock should return false by default.
- verify(mDeviceIdleInternal, atLeastOnce()).isAppOnWhitelist(
- UserHandle.getAppId(TEST_CALLING_UID));
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId1), MODE_ALLOWED);
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId1), MODE_DEFAULT);
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId2), MODE_IGNORED);
+ mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId2), MODE_ERRORED);
+
+ mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), true);
+
+ // Permission got revoked only for (appId1, userId2)
+ verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(
+ eq(UserHandle.getUid(userId1, appId1)), eq(packages[0]));
+ verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(
+ eq(UserHandle.getUid(userId1, appId2)), eq(packages[1]));
+ verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(
+ eq(UserHandle.getUid(userId2, appId2)), eq(packages[1]));
+
+ verify(mService).removeExactAlarmsOnPermissionRevokedLocked(
+ eq(UserHandle.getUid(userId2, appId1)), eq(packages[0]));
}
@Test
- public void opScheduleExactAlarmRevoked() throws Exception {
+ public void opChangedPermissionRevoked() throws Exception {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
+ mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED);
mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
assertAndHandleMessageSync(REMOVE_EXACT_ALARMS);
verify(mService).removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID,
@@ -2433,10 +2523,39 @@ public class AlarmManagerServiceTest {
}
@Test
- public void opScheduleExactAlarmGranted() throws Exception {
+ public void opChangedChangeDisabled() throws Exception {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
+
+ mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED);
+ mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+
+ mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
+
+ verify(mService.mHandler, never()).sendMessageAtTime(
+ argThat(m -> m.what == REMOVE_EXACT_ALARMS), anyLong());
+ }
+
+ @Test
+ public void opChangedNoPermissionChangeDueToDenyList() throws Exception {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
+
+ mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED);
+ mockExactAlarmPermissionGrant(true, true, MODE_DEFAULT);
+
+ mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
+
+ verify(mService.mHandler, never()).sendMessageAtTime(
+ argThat(m -> m.what == REMOVE_EXACT_ALARMS), anyLong());
+ }
+
+ @Test
+ public void opChangedPermissionGranted() throws Exception {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
final long durationMs = 20000L;
when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs);
+ mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED);
mockExactAlarmPermissionGrant(true, false, MODE_ALLOWED);
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
@@ -2462,9 +2581,7 @@ public class AlarmManagerServiceTest {
@Test
public void removeExactAlarmsOnPermissionRevoked() {
- doReturn(true).when(
- () -> CompatChanges.isChangeEnabled(eq(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION),
- anyString(), any(UserHandle.class)));
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
// basic exact alarm
setTestAlarm(ELAPSED_REALTIME, 0, 0, getNewMockPendingIntent(), 0, 0, TEST_CALLING_UID,
@@ -2501,6 +2618,9 @@ public class AlarmManagerServiceTest {
// Mock should return false by default.
verify(mDeviceIdleInternal, atLeastOnce()).isAppOnWhitelist(
UserHandle.getAppId(TEST_CALLING_UID));
+
+ verify(() -> PermissionManagerService.killUid(eq(TEST_CALLING_UID), eq(TEST_CALLING_USER),
+ anyString()));
}
@Test
@@ -2567,6 +2687,86 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void onLastOpScheduleExactAlarmOnUserStart() {
+ final int userId = 54;
+ SystemService.TargetUser mockTargetUser = mock(SystemService.TargetUser.class);
+ when(mockTargetUser.getUserIdentifier()).thenReturn(userId);
+
+ final Integer[] appIds = new Integer[]{43, 254, 7731};
+ final int unknownAppId = 2347;
+ final String[] packageNames = new String[]{"p43", "p254", "p7731"};
+ final int[] appOpModes = new int[]{MODE_ALLOWED, MODE_IGNORED, MODE_ERRORED};
+ mService.mExactAlarmCandidates = new ArraySet<>(appIds);
+ mService.mExactAlarmCandidates.add(unknownAppId);
+
+ for (int i = 0; i < appIds.length; i++) {
+ final int uid = UserHandle.getUid(userId, appIds[i]);
+ final AndroidPackage pkg = mock(AndroidPackage.class);
+ when(pkg.getPackageName()).thenReturn(packageNames[i]);
+
+ when(mPackageManagerInternal.getPackage(uid)).thenReturn(pkg);
+ when(mAppOpsManager.checkOpNoThrow(OP_SCHEDULE_EXACT_ALARM, uid,
+ packageNames[i])).thenReturn(appOpModes[i]);
+ }
+
+ final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ doReturn(true).when(mService.mHandler).post(runnableCaptor.capture());
+
+ mService.onUserStarting(mockTargetUser);
+ runnableCaptor.getValue().run();
+
+ assertEquals(appIds.length, mService.mLastOpScheduleExactAlarm.size());
+ for (int i = 0; i < appIds.length; i++) {
+ final int uid = UserHandle.getUid(userId, appIds[i]);
+ assertEquals(appOpModes[i], mService.mLastOpScheduleExactAlarm.get(uid, -1));
+ }
+ assertTrue(mService.mLastOpScheduleExactAlarm.indexOfKey(
+ UserHandle.getUid(userId, unknownAppId)) < 0);
+ }
+
+ @Test
+ public void refreshExactAlarmCandidatesRemovesExactAlarmsIfNeeded() {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
+ mService.mExactAlarmCandidates = new ArraySet<>(new Integer[]{1, 2, 5});
+ final String[] updatedRequesters = new String[]{"p11", "p2", "p9"};
+ final Integer[] appIds = new Integer[]{11, 2, 9};
+ registerAppIds(updatedRequesters, appIds);
+
+ when(mPermissionManagerInternal.getAppOpPermissionPackages(
+ SCHEDULE_EXACT_ALARM)).thenReturn(updatedRequesters);
+
+ final PendingIntent exactAppId1 = getNewMockPendingIntent();
+ setTestAlarm(ELAPSED_REALTIME, 0, 0, exactAppId1, 0, 0,
+ UserHandle.getUid(TEST_CALLING_USER, 1), null);
+
+ final PendingIntent exactAppId2 = getNewMockPendingIntent();
+ setTestAlarm(ELAPSED_REALTIME, 0, 0, exactAppId2, 0, 0,
+ UserHandle.getUid(TEST_CALLING_USER, 2), null);
+
+ final PendingIntent exactAppId5 = getNewMockPendingIntent();
+ setTestAlarm(ELAPSED_REALTIME, 0, 0, exactAppId5, 0, 0,
+ UserHandle.getUid(TEST_CALLING_USER, 5), null);
+
+ final PendingIntent inexactAppId5 = getNewMockPendingIntent();
+ setTestAlarm(ELAPSED_REALTIME, 0, 23, inexactAppId5, 0, 0,
+ UserHandle.getUid(TEST_CALLING_USER, 5), null);
+
+ assertEquals(4, mService.mAlarmStore.size());
+
+ mService.refreshExactAlarmCandidates();
+ // App ids 1 and 5 lost the permission, so there alarms should be removed.
+
+ final ArrayList<Alarm> remaining = mService.mAlarmStore.asList();
+ assertEquals(2, remaining.size());
+
+ assertTrue("Inexact alarm removed",
+ remaining.removeIf(a -> a.matches(inexactAppId5, null)));
+ assertTrue("Alarm from app id 2 removed",
+ remaining.removeIf(a -> a.matches(exactAppId2, null)));
+ }
+
+ @Test
public void refreshExactAlarmCandidatesOnPackageAdded() {
final String[] exactAlarmRequesters = new String[]{"p11", "p2", "p9"};
final Integer[] appIds = new Integer[]{11, 2, 9};
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java
index cf5db2e0db98..8532dbb7f38a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java
@@ -158,7 +158,7 @@ public class MockableLocationProviderTest {
@Test
public void testSetState() {
- assertThat(mProvider.isAllowed()).isFalse();
+ assertThat(mProvider.getState().allowed).isFalse();
AbstractLocationProvider.State newState;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index 1ac4a8ed96d0..a71b481372d8 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -19,6 +19,7 @@ package com.android.server.accessibility;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_HOVER_MOVE;
import static android.view.MotionEvent.ACTION_UP;
+import static android.view.WindowManagerPolicyConstants.FLAG_INJECTED_FROM_ACCESSIBILITY;
import static android.view.WindowManagerPolicyConstants.FLAG_PASS_TO_USER;
import static org.hamcrest.CoreMatchers.allOf;
@@ -186,9 +187,9 @@ public class MotionEventInjectorTest {
verifyNoMoreInteractions(next);
mMessageCapturingHandler.sendOneMessage(); // Send a motion event
- verify(next).onMotionEvent(mCaptor1.capture(), mCaptor2.capture(), eq(FLAG_PASS_TO_USER));
- verify(next).onMotionEvent(argThat(mIsLineStart), argThat(mIsLineStart),
- eq(FLAG_PASS_TO_USER));
+ final int expectedFlags = FLAG_PASS_TO_USER | FLAG_INJECTED_FROM_ACCESSIBILITY;
+ verify(next).onMotionEvent(mCaptor1.capture(), mCaptor2.capture(), eq(expectedFlags));
+ verify(next).onMotionEvent(argThat(mIsLineStart), argThat(mIsLineStart), eq(expectedFlags));
verifyNoMoreInteractions(next);
reset(next);
@@ -196,7 +197,7 @@ public class MotionEventInjectorTest {
mMessageCapturingHandler.sendOneMessage(); // Send a motion event
verify(next).onMotionEvent(argThat(allOf(mIsLineMiddle, hasRightDownTime)),
- argThat(allOf(mIsLineMiddle, hasRightDownTime)), eq(FLAG_PASS_TO_USER));
+ argThat(allOf(mIsLineMiddle, hasRightDownTime)), eq(expectedFlags));
verifyNoMoreInteractions(next);
reset(next);
@@ -204,7 +205,7 @@ public class MotionEventInjectorTest {
mMessageCapturingHandler.sendOneMessage(); // Send a motion event
verify(next).onMotionEvent(argThat(allOf(mIsLineEnd, hasRightDownTime)),
- argThat(allOf(mIsLineEnd, hasRightDownTime)), eq(FLAG_PASS_TO_USER));
+ argThat(allOf(mIsLineEnd, hasRightDownTime)), eq(expectedFlags));
verifyNoMoreInteractions(next);
verify(mServiceInterface).onPerformGestureResult(LINE_SEQUENCE, true);
@@ -242,7 +243,8 @@ public class MotionEventInjectorTest {
mMessageCapturingHandler.sendAllMessages(); // Send all motion events
reset(next);
mMotionEventInjector.onMotionEvent(mClickDownEvent, mClickDownEvent, 0);
- verify(next).onMotionEvent(argThat(mIsClickDown), argThat(mIsClickDown), eq(0));
+ verify(next).onMotionEvent(argThat(mIsClickDown), argThat(mIsClickDown),
+ eq(FLAG_INJECTED_FROM_ACCESSIBILITY));
}
@Test
@@ -258,7 +260,8 @@ public class MotionEventInjectorTest {
mMessageCapturingHandler.sendOneMessage(); // Send a motion event
verify(next).onMotionEvent(
- argThat(mIsLineStart), argThat(mIsLineStart), eq(FLAG_PASS_TO_USER));
+ argThat(mIsLineStart), argThat(mIsLineStart),
+ eq(FLAG_PASS_TO_USER | FLAG_INJECTED_FROM_ACCESSIBILITY));
}
@Test
@@ -289,9 +292,11 @@ public class MotionEventInjectorTest {
reset(next);
mMessageCapturingHandler.sendOneMessage(); // Send a motion event
- verify(next).onMotionEvent(mCaptor1.capture(), mCaptor2.capture(), eq(FLAG_PASS_TO_USER));
+ verify(next).onMotionEvent(mCaptor1.capture(), mCaptor2.capture(),
+ eq(FLAG_PASS_TO_USER | FLAG_INJECTED_FROM_ACCESSIBILITY));
verify(next).onMotionEvent(
- argThat(mIsLineStart), argThat(mIsLineStart), eq(FLAG_PASS_TO_USER));
+ argThat(mIsLineStart), argThat(mIsLineStart),
+ eq(FLAG_PASS_TO_USER | FLAG_INJECTED_FROM_ACCESSIBILITY));
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index eace99f61e60..e19aa727b735 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -59,6 +59,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import java.io.IOException;
@@ -79,7 +80,9 @@ import java.util.regex.Pattern;
public class ActivityManagerTest {
private static final String TAG = "ActivityManagerTest";
- private static final String TEST_APP = "com.android.servicestests.apps.simpleservicetestapp1";
+ private static final String TEST_APP1 = "com.android.servicestests.apps.simpleservicetestapp1";
+ private static final String TEST_APP2 = "com.android.servicestests.apps.simpleservicetestapp2";
+ private static final String TEST_APP3 = "com.android.servicestests.apps.simpleservicetestapp3";
private static final String TEST_CLASS =
"com.android.servicestests.apps.simpleservicetestapp.SimpleService";
private static final int TEST_LOOPS = 100;
@@ -135,13 +138,13 @@ public class ActivityManagerTest {
final PackageManager pm = mContext.getPackageManager();
int uid = 0;
try {
- uid = pm.getPackageUid(TEST_APP, 0);
+ uid = pm.getPackageUid(TEST_APP1, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
Intent intent = new Intent();
- intent.setClassName(TEST_APP, TEST_CLASS);
+ intent.setClassName(TEST_APP1, TEST_CLASS);
// Create a service connection with auto creation.
CountDownLatch latch = new CountDownLatch(1);
@@ -156,7 +159,7 @@ public class ActivityManagerTest {
// Create a service connection without any flags.
intent = new Intent();
- intent.setClassName(TEST_APP, TEST_CLASS);
+ intent.setClassName(TEST_APP1, TEST_CLASS);
latch = new CountDownLatch(1);
MyServiceConnection otherConnection = new MyServiceConnection(latch);
mContext.bindService(intent, otherConnection, 0);
@@ -242,7 +245,7 @@ public class ActivityManagerTest {
public void testFgsProcStatsTracker() throws Exception {
final PackageManager pm = mContext.getPackageManager();
final long timeout = 5000;
- int uid = pm.getPackageUid(TEST_APP, 0);
+ int uid = pm.getPackageUid(TEST_APP1, 0);
final MyUidImportanceListener uidListener1 = new MyUidImportanceListener(uid);
final MyUidImportanceListener uidListener2 = new MyUidImportanceListener(uid);
final ActivityManager am = mContext.getSystemService(ActivityManager.class);
@@ -275,12 +278,12 @@ public class ActivityManagerTest {
am.addOnUidImportanceListener(uidListener1,
RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE);
am.addOnUidImportanceListener(uidListener2, RunningAppProcessInfo.IMPORTANCE_GONE);
- runShellCommand("cmd deviceidle whitelist +" + TEST_APP);
+ runShellCommand("cmd deviceidle whitelist +" + TEST_APP1);
toggleScreenOn(true);
final Intent intent = new Intent(ACTION_FGS_STATS_TEST);
final ComponentName cn = ComponentName.unflattenFromString(
- TEST_APP + "/" + TEST_FGS_CLASS);
+ TEST_APP1 + "/" + TEST_FGS_CLASS);
final Bundle bundle = new Bundle();
intent.setComponent(cn);
bundle.putBinder(EXTRA_MESSENGER, messenger.getBinder());
@@ -314,10 +317,10 @@ public class ActivityManagerTest {
timeout * 2, TimeUnit.MILLISECONDS));
} finally {
toggleScreenOn(true);
- runShellCommand("cmd deviceidle whitelist -" + TEST_APP);
+ runShellCommand("cmd deviceidle whitelist -" + TEST_APP1);
am.removeOnUidImportanceListener(uidListener1);
am.removeOnUidImportanceListener(uidListener2);
- am.forceStopPackage(TEST_APP);
+ am.forceStopPackage(TEST_APP1);
mContext.unregisterReceiver(receiver);
}
}
@@ -358,7 +361,7 @@ public class ActivityManagerTest {
ActivityManagerConstants.KEY_MAX_SERVICE_INACTIVITY + "=" + waitFor);
final Intent intent = new Intent();
- intent.setClassName(TEST_APP, TEST_CLASS);
+ intent.setClassName(TEST_APP1, TEST_CLASS);
final CountDownLatch latch = new CountDownLatch(1);
autoConnection = new MyServiceConnection(latch);
@@ -370,7 +373,7 @@ public class ActivityManagerTest {
} catch (InterruptedException e) {
fail("Unable to bind to service " + intent.getComponent());
}
- assertFalse(TEST_APP + " shouldn't be frozen now.", isAppFrozen(TEST_APP));
+ assertFalse(TEST_APP1 + " shouldn't be frozen now.", isAppFrozen(TEST_APP1));
// Trigger oomAdjUpdate/
toggleScreenOn(false);
@@ -380,7 +383,7 @@ public class ActivityManagerTest {
Thread.sleep(waitFor * 4);
// It still shouldn't be frozen, although it's been in cached state.
- assertFalse(TEST_APP + " shouldn't be frozen now.", isAppFrozen(TEST_APP));
+ assertFalse(TEST_APP1 + " shouldn't be frozen now.", isAppFrozen(TEST_APP1));
} finally {
toggleScreenOn(true);
if (amConstantsSettings != null) {
@@ -424,7 +427,7 @@ public class ActivityManagerTest {
final long shortTimeoutMs = 5_000;
final long backgroundSettleMs = 10_000;
final PackageManager pm = mContext.getPackageManager();
- final int uid = pm.getPackageUid(TEST_APP, 0);
+ final int uid = pm.getPackageUid(TEST_APP1, 0);
final MyUidImportanceListener uidListener1 = new MyUidImportanceListener(uid);
final MyUidImportanceListener uidListener2 = new MyUidImportanceListener(uid);
SettingsSession<String> amConstantsSettings = null;
@@ -462,11 +465,11 @@ public class ActivityManagerTest {
Thread.sleep(currentBackgroundSettleMs);
amConstantsSettings.set(
ActivityManagerConstants.KEY_BACKGROUND_SETTLE_TIME + "=" + backgroundSettleMs);
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND allow");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND allow");
final Intent intent = new Intent(ACTION_FGS_STATS_TEST);
final ComponentName cn = ComponentName.unflattenFromString(
- TEST_APP + "/" + TEST_FGS_CLASS);
+ TEST_APP1 + "/" + TEST_FGS_CLASS);
final Bundle bundle = new Bundle();
intent.setComponent(cn);
bundle.putBinder(EXTRA_MESSENGER, messenger.getBinder());
@@ -491,21 +494,21 @@ public class ActivityManagerTest {
RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs));
// Set the FAS state.
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND deny");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND deny");
// Now it should've been killed.
assertTrue("Should have been killed", uidListener2.waitFor(
RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs));
// Start the FGS.
// Temporarily allow RUN_ANY_IN_BACKGROUND to start FGS.
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND allow");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND allow");
latchHolder[0] = new CountDownLatch(1);
mContext.startForegroundService(intent);
assertTrue("Timed out to start fg service", uidListener1.waitFor(
RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE, shortTimeoutMs));
assertTrue("Timed out to get the remote messenger", latchHolder[0].await(
shortTimeoutMs, TimeUnit.MILLISECONDS));
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND deny");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND deny");
// It shouldn't be killed since it's not cached.
assertFalse("FGS shouldn't be killed", uidListener2.waitFor(
RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs));
@@ -523,14 +526,14 @@ public class ActivityManagerTest {
// Start the FGS.
// Temporarily allow RUN_ANY_IN_BACKGROUND to start FGS.
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND allow");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND allow");
latchHolder[0] = new CountDownLatch(1);
mContext.startForegroundService(intent);
assertTrue("Timed out to start fg service", uidListener1.waitFor(
RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE, shortTimeoutMs));
assertTrue("Timed out to get the remote messenger", latchHolder[0].await(
shortTimeoutMs, TimeUnit.MILLISECONDS));
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND deny");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND deny");
assertFalse("FGS shouldn't be killed", uidListener2.waitFor(
RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs));
@@ -542,7 +545,7 @@ public class ActivityManagerTest {
assertFalse("FGS shouldn't be killed", uidListener2.waitFor(
RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs));
} finally {
- runShellCommand("cmd appops set " + TEST_APP + " RUN_ANY_IN_BACKGROUND default");
+ runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND default");
if (amConstantsSettings != null) {
amConstantsSettings.close();
}
@@ -554,6 +557,82 @@ public class ActivityManagerTest {
}
}
+ @Ignore("Need to disable calling uid check in ActivityManagerService.killPids before this test")
+ @Test
+ public void testKillPids() throws Exception {
+ final long timeout = 5000;
+ final long shortTimeout = 2000;
+ final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ final PackageManager pm = mContext.getPackageManager();
+ final int uid1 = pm.getPackageUid(TEST_APP1, 0);
+ final int uid2 = pm.getPackageUid(TEST_APP2, 0);
+ final int uid3 = pm.getPackageUid(TEST_APP3, 0);
+ final MyUidImportanceListener uid1Listener1 = new MyUidImportanceListener(uid1);
+ final MyUidImportanceListener uid1Listener2 = new MyUidImportanceListener(uid1);
+ final MyUidImportanceListener uid2Listener1 = new MyUidImportanceListener(uid2);
+ final MyUidImportanceListener uid2Listener2 = new MyUidImportanceListener(uid2);
+ final MyUidImportanceListener uid3Listener1 = new MyUidImportanceListener(uid3);
+ final MyUidImportanceListener uid3Listener2 = new MyUidImportanceListener(uid3);
+ try {
+ am.addOnUidImportanceListener(uid1Listener1, RunningAppProcessInfo.IMPORTANCE_SERVICE);
+ am.addOnUidImportanceListener(uid1Listener2, RunningAppProcessInfo.IMPORTANCE_GONE);
+ am.addOnUidImportanceListener(uid2Listener1, RunningAppProcessInfo.IMPORTANCE_SERVICE);
+ am.addOnUidImportanceListener(uid2Listener2, RunningAppProcessInfo.IMPORTANCE_GONE);
+ am.addOnUidImportanceListener(uid3Listener1, RunningAppProcessInfo.IMPORTANCE_SERVICE);
+ am.addOnUidImportanceListener(uid3Listener2, RunningAppProcessInfo.IMPORTANCE_GONE);
+ runShellCommand("cmd deviceidle whitelist +" + TEST_APP1);
+ runShellCommand("cmd deviceidle whitelist +" + TEST_APP2);
+ runShellCommand("cmd deviceidle whitelist +" + TEST_APP3);
+ final int[] pids = new int[3];
+ // Test sync kills
+ pids[0] = startTargetService(am, TEST_APP1, TEST_CLASS, uid1, TEST_APP1,
+ uid1Listener1, timeout);
+ pids[1] = startTargetService(am, TEST_APP2, TEST_CLASS, uid2, TEST_APP2,
+ uid2Listener1, timeout);
+ pids[2] = startTargetService(am, TEST_APP3, TEST_CLASS, uid3, TEST_APP3,
+ uid3Listener1, timeout);
+ Thread.sleep(shortTimeout);
+ mService.killPids(pids, "testKillPids", false);
+ assertTrue("Timed out to kill process", uid1Listener2.waitFor(
+ RunningAppProcessInfo.IMPORTANCE_GONE, timeout));
+ assertTrue("Timed out to kill process", uid2Listener2.waitFor(
+ RunningAppProcessInfo.IMPORTANCE_GONE, timeout));
+ assertTrue("Timed out to kill process", uid3Listener2.waitFor(
+ RunningAppProcessInfo.IMPORTANCE_GONE, timeout));
+ } finally {
+ runShellCommand("cmd deviceidle whitelist -" + TEST_APP1);
+ runShellCommand("cmd deviceidle whitelist -" + TEST_APP2);
+ runShellCommand("cmd deviceidle whitelist -" + TEST_APP3);
+ am.removeOnUidImportanceListener(uid1Listener1);
+ am.removeOnUidImportanceListener(uid1Listener2);
+ am.removeOnUidImportanceListener(uid2Listener1);
+ am.removeOnUidImportanceListener(uid2Listener2);
+ am.removeOnUidImportanceListener(uid3Listener1);
+ am.removeOnUidImportanceListener(uid3Listener2);
+ am.forceStopPackage(TEST_APP1);
+ am.forceStopPackage(TEST_APP2);
+ am.forceStopPackage(TEST_APP3);
+ }
+ }
+
+ private int startTargetService(ActivityManager am, String targetPakage, String targetService,
+ int targetUid, String targetProcessName, MyUidImportanceListener uidListener,
+ long timeout) throws Exception {
+ final Intent intent = new Intent();
+ intent.setComponent(ComponentName.unflattenFromString(targetPakage + "/" + targetService));
+ mContext.startService(intent);
+ assertTrue("Timed out to start service", uidListener.waitFor(
+ RunningAppProcessInfo.IMPORTANCE_SERVICE, timeout));
+ final List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
+ for (int i = processes.size() - 1; i >= 0; i--) {
+ final RunningAppProcessInfo info = processes.get(i);
+ if (info.uid == targetUid && targetProcessName.equals(info.processName)) {
+ return info.pid;
+ }
+ }
+ return -1;
+ }
+
/**
* Make sure the screen state.
*/
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
index 3bcbcbdbd2c8..8666fa6ac35a 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
@@ -57,6 +57,11 @@ import java.util.Map;
/** This tests AppSearchImpl when it's running with a platform-backed VisibilityStore. */
public class AppSearchImplPlatformTest {
+ /**
+ * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+ */
+ private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
+
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
private Context mContext;
@@ -88,7 +93,8 @@ public class AppSearchImplPlatformTest {
AppSearchImpl.create(
mTemporaryFolder.newFolder(),
mContext,
- /*logger=*/ null);
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
mGlobalQuerierUid =
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
index 6ac4d138c9d1..4faffc025e2f 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
@@ -56,6 +56,11 @@ import java.util.Collections;
import java.util.Map;
public class VisibilityStoreTest {
+ /**
+ * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+ */
+ private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
+
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
private Context mContext;
@@ -87,7 +92,8 @@ public class VisibilityStoreTest {
AppSearchImpl.create(
mTemporaryFolder.newFolder(),
mContext,
- /*logger=*/ null);
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
mVisibilityStore = appSearchImpl.getVisibilityStoreLocked();
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index 5a8c44caa0a3..e26cfeab1529 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -76,17 +76,22 @@ import java.util.Set;
public class AppSearchImplTest {
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
private AppSearchImpl mAppSearchImpl;
+ /**
+ * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+ */
+ private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
@Before
public void setUp() throws Exception {
Context context = ApplicationProvider.getApplicationContext();
- // Give ourselves global query permissions
+ // Give ourselves global query permissions.
mAppSearchImpl =
AppSearchImpl.create(
mTemporaryFolder.newFolder(),
context,
- /*logger=*/ null);
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
}
/**
@@ -423,7 +428,7 @@ public class AppSearchImplTest {
}
@Test
- public void testOptimize() throws Exception {
+ public void testTriggerCheckOptimizeByMutationSize() throws Exception {
// Insert schema
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -436,56 +441,30 @@ public class AppSearchImplTest {
/*forceOverride=*/ false,
/*version=*/ 0);
- // Insert enough documents.
- for (int i = 0;
- i
- < AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT
- + AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
- i++) {
- GenericDocument document =
- new GenericDocument.Builder<>("namespace", "id" + i, "type").build();
- mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
- }
+ // Insert a document and then remove it to generate garbage.
+ GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
+ mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
+ mAppSearchImpl.remove(
+ "package", "database", "namespace", "id", /*removeStatsBuilder=*/ null);
- // Check optimize() will release 0 docs since there is no deletion.
+ // Verify there is garbage documents.
GetOptimizeInfoResultProto optimizeInfo = mAppSearchImpl.getOptimizeInfoResultLocked();
- assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(0);
-
- // delete 999 documents, we will reach the threshold to trigger optimize() in next
- // deletion.
- for (int i = 0; i < AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT - 1; i++) {
- mAppSearchImpl.remove(
- "package", "database", "namespace", "id" + i, /*removeStatsBuilder=*/ null);
- }
+ assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(1);
- // Updates the check for optimize counter, checkForOptimize() will be triggered since
- // CHECK_OPTIMIZE_INTERVAL is reached but optimize() won't since
- // OPTIMIZE_THRESHOLD_DOC_COUNT is not.
- mAppSearchImpl.checkForOptimize(
- /*mutateBatchSize=*/ AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT - 1);
+ // Increase mutation counter and stop before reach the threshold
+ mAppSearchImpl.checkForOptimize(AppSearchImpl.CHECK_OPTIMIZE_INTERVAL - 1);
- // Verify optimize() still not be triggered.
+ // Verify the optimize() isn't triggered.
optimizeInfo = mAppSearchImpl.getOptimizeInfoResultLocked();
- assertThat(optimizeInfo.getOptimizableDocs())
- .isEqualTo(AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT - 1);
-
- // Keep delete docs
- for (int i = AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT;
- i
- < AppSearchImpl.OPTIMIZE_THRESHOLD_DOC_COUNT
- + AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
- i++) {
- mAppSearchImpl.remove(
- "package", "database", "namespace", "id" + i, /*removeStatsBuilder=*/ null);
- }
- // updates the check for optimize counter, will reach both CHECK_OPTIMIZE_INTERVAL and
- // OPTIMIZE_THRESHOLD_DOC_COUNT this time and trigger a optimize().
- mAppSearchImpl.checkForOptimize(/*mutateBatchSize*/ AppSearchImpl.CHECK_OPTIMIZE_INTERVAL);
+ assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(1);
- // Verify optimize() is triggered
+ // Increase the counter and reach the threshold, optimize() should be triggered.
+ mAppSearchImpl.checkForOptimize(/*mutateBatchSize=*/ 1);
+
+ // Verify optimize() is triggered.
optimizeInfo = mAppSearchImpl.getOptimizeInfoResultLocked();
- assertThat(optimizeInfo.getOptimizableDocs())
- .isLessThan(AppSearchImpl.CHECK_OPTIMIZE_INTERVAL);
+ assertThat(optimizeInfo.getOptimizableDocs()).isEqualTo(0);
+ assertThat(optimizeInfo.getEstimatedOptimizableBytes()).isEqualTo(0);
}
@Test
@@ -493,7 +472,12 @@ public class AppSearchImplTest {
// Setup the index
Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
- AppSearchImpl appSearchImpl = AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
// Insert schema
List<AppSearchSchema> schemas =
@@ -522,7 +506,7 @@ public class AppSearchImplTest {
/*queryExpression=*/ "",
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
- VisibilityStore.NO_OP_USER_ID,
+ VisibilityStore.NO_OP_UID,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
@@ -554,7 +538,9 @@ public class AppSearchImplTest {
// Initialize AppSearchImpl. This should cause a reset.
appSearchImpl.close();
- appSearchImpl = AppSearchImpl.create(appsearchDir, context, testLogger);
+ appSearchImpl =
+ AppSearchImpl.create(
+ appsearchDir, context, testLogger, ALWAYS_OPTIMIZE);
// Check recovery state
InitializeStats initStats = testLogger.mInitializeStats;
@@ -582,7 +568,7 @@ public class AppSearchImplTest {
/*queryExpression=*/ "",
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
- VisibilityStore.NO_OP_USER_ID,
+ VisibilityStore.NO_OP_UID,
/*logger=*/ null);
assertThat(results.getResults()).isEmpty();
@@ -606,7 +592,7 @@ public class AppSearchImplTest {
/*queryExpression=*/ "",
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
- VisibilityStore.NO_OP_USER_ID,
+ VisibilityStore.NO_OP_UID,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
@@ -862,7 +848,7 @@ public class AppSearchImplTest {
"",
searchSpec,
/*callerPackageName=*/ "",
- /*callerUid=*/ 0,
+ VisibilityStore.NO_OP_UID,
/*logger=*/ null);
assertThat(searchResultPage.getResults()).isEmpty();
}
@@ -1683,7 +1669,8 @@ public class AppSearchImplTest {
AppSearchImpl.create(
mTemporaryFolder.newFolder(),
context,
- /*logger=*/ null);
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
// Initial check that we could do something at first.
List<AppSearchSchema> schemas =
@@ -1758,7 +1745,7 @@ public class AppSearchImplTest {
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
.build(),
"package",
- /*callerUid=*/ 1,
+ VisibilityStore.NO_OP_UID,
/*logger=*/ null);
});
@@ -1830,7 +1817,12 @@ public class AppSearchImplTest {
// Setup the index
Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
- AppSearchImpl appSearchImpl = AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -1856,7 +1848,11 @@ public class AppSearchImplTest {
// That document should be visible even from another instance.
AppSearchImpl appSearchImpl2 =
- AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
getResult =
appSearchImpl2.getDocument(
"package", "database", "namespace1", "id1", Collections.emptyMap());
@@ -1868,7 +1864,12 @@ public class AppSearchImplTest {
// Setup the index
Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
- AppSearchImpl appSearchImpl = AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -1918,7 +1919,11 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
- AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
expectThrows(
AppSearchException.class,
() ->
@@ -1939,7 +1944,12 @@ public class AppSearchImplTest {
// Setup the index
Context context = ApplicationProvider.getApplicationContext();
File appsearchDir = mTemporaryFolder.newFolder();
- AppSearchImpl appSearchImpl = AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
@@ -1997,7 +2007,11 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
- AppSearchImpl.create(appsearchDir, context, /*logger=*/ null);
+ AppSearchImpl.create(
+ appsearchDir,
+ context,
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
expectThrows(
AppSearchException.class,
() ->
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
index f0a6ef13b212..c6726c69c7fd 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java
@@ -53,6 +53,10 @@ public class AppSearchLoggerTest {
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
private AppSearchImpl mAppSearchImpl;
private TestLogger mLogger;
+ /**
+ * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+ */
+ private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
@Before
public void setUp() throws Exception {
@@ -63,7 +67,8 @@ public class AppSearchLoggerTest {
AppSearchImpl.create(
mTemporaryFolder.newFolder(),
context,
- /*logger=*/ null);
+ /*logger=*/ null,
+ ALWAYS_OPTIMIZE);
mLogger = new TestLogger();
}
@@ -286,11 +291,13 @@ public class AppSearchLoggerTest {
public void testLoggingStats_initialize() throws Exception {
Context context = ApplicationProvider.getApplicationContext();
+ // Create an unused AppSearchImpl to generated an InitializeStats.
AppSearchImpl appSearchImpl =
AppSearchImpl.create(
mTemporaryFolder.newFolder(),
context,
- mLogger);
+ mLogger,
+ ALWAYS_OPTIMIZE);
InitializeStats iStats = mLogger.mInitializeStats;
assertThat(iStats).isNotNull();
@@ -325,9 +332,9 @@ public class AppSearchLoggerTest {
PutDocumentStats pStats = mLogger.mPutDocumentStats;
assertThat(pStats).isNotNull();
- assertThat(pStats.getGeneralStats().getPackageName()).isEqualTo(testPackageName);
- assertThat(pStats.getGeneralStats().getDatabase()).isEqualTo(testDatabase);
- assertThat(pStats.getGeneralStats().getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
+ assertThat(pStats.getPackageName()).isEqualTo(testPackageName);
+ assertThat(pStats.getDatabase()).isEqualTo(testDatabase);
+ assertThat(pStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
// The rest of native stats have been tested in testCopyNativeStats
assertThat(pStats.getNativeDocumentSizeBytes()).isGreaterThan(0);
}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java
new file mode 100644
index 000000000000..f30cbb8c5158
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appsearch.external.localstorage;
+
+import static com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy.BYTES_OPTIMIZE_THRESHOLD;
+import static com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy.DOC_COUNT_OPTIMIZE_THRESHOLD;
+import static com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy.TIME_OPTIMIZE_THRESHOLD_MILLIS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.server.appsearch.proto.GetOptimizeInfoResultProto;
+import com.android.server.appsearch.proto.StatusProto;
+
+import org.junit.Test;
+
+public class FrameworkOptimizeStrategyTest {
+ FrameworkOptimizeStrategy mFrameworkOptimizeStrategy = new FrameworkOptimizeStrategy();
+
+ @Test
+ public void testShouldOptimize_docCountThreshold() {
+ GetOptimizeInfoResultProto optimizeInfo =
+ GetOptimizeInfoResultProto.newBuilder()
+ .setTimeSinceLastOptimizeMs(0)
+ .setEstimatedOptimizableBytes(BYTES_OPTIMIZE_THRESHOLD)
+ .setOptimizableDocs(0)
+ .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
+ .build();
+ assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
+ }
+
+ @Test
+ public void testShouldOptimize_byteThreshold() {
+ GetOptimizeInfoResultProto optimizeInfo =
+ GetOptimizeInfoResultProto.newBuilder()
+ .setTimeSinceLastOptimizeMs(TIME_OPTIMIZE_THRESHOLD_MILLIS)
+ .setEstimatedOptimizableBytes(0)
+ .setOptimizableDocs(0)
+ .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
+ .build();
+ assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
+ }
+
+ @Test
+ public void testShouldNotOptimize_timeThreshold() {
+ GetOptimizeInfoResultProto optimizeInfo =
+ GetOptimizeInfoResultProto.newBuilder()
+ .setTimeSinceLastOptimizeMs(0)
+ .setEstimatedOptimizableBytes(0)
+ .setOptimizableDocs(DOC_COUNT_OPTIMIZE_THRESHOLD)
+ .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK).build())
+ .build();
+ assertThat(mFrameworkOptimizeStrategy.shouldOptimize(optimizeInfo)).isTrue();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
index a71e53233848..6d9068675a72 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
@@ -29,57 +29,28 @@ public class AppSearchStatsTest {
static final int TEST_TOTAL_LATENCY_MILLIS = 20;
@Test
- public void testAppSearchStats_GeneralStats() {
- final GeneralStats gStats =
- new GeneralStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
- .setStatusCode(TEST_STATUS_CODE)
- .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
- .build();
-
- assertThat(gStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(gStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
- assertThat(gStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
- assertThat(gStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
- }
-
- /** Make sure status code is UNKNOWN if not set in {@link GeneralStats} */
- @Test
- public void testAppSearchStats_GeneralStats_defaultStatsCode_Unknown() {
- final GeneralStats gStats =
- new GeneralStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
- .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
- .build();
-
- assertThat(gStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(gStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
- assertThat(gStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_UNKNOWN_ERROR);
- assertThat(gStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
- }
-
- @Test
public void testAppSearchStats_CallStats() {
final int estimatedBinderLatencyMillis = 1;
final int numOperationsSucceeded = 2;
final int numOperationsFailed = 3;
final @CallStats.CallType int callType = CallStats.CALL_TYPE_PUT_DOCUMENTS;
- final CallStats.Builder cStatsBuilder =
- new CallStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+ final CallStats cStats =
+ new CallStats.Builder()
+ .setPackageName(TEST_PACKAGE_NAME)
+ .setDatabase(TEST_DATA_BASE)
+ .setStatusCode(TEST_STATUS_CODE)
+ .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
.setCallType(callType)
.setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
.setNumOperationsSucceeded(numOperationsSucceeded)
- .setNumOperationsFailed(numOperationsFailed);
- cStatsBuilder
- .getGeneralStatsBuilder()
- .setStatusCode(TEST_STATUS_CODE)
- .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS);
- final CallStats cStats = cStatsBuilder.build();
+ .setNumOperationsFailed(numOperationsFailed)
+ .build();
- assertThat(cStats.getGeneralStats().getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(cStats.getGeneralStats().getDatabase()).isEqualTo(TEST_DATA_BASE);
- assertThat(cStats.getGeneralStats().getStatusCode()).isEqualTo(TEST_STATUS_CODE);
- assertThat(cStats.getGeneralStats().getTotalLatencyMillis())
- .isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+ assertThat(cStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+ assertThat(cStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
+ assertThat(cStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(cStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
assertThat(cStats.getEstimatedBinderLatencyMillis())
.isEqualTo(estimatedBinderLatencyMillis);
assertThat(cStats.getCallType()).isEqualTo(callType);
@@ -88,6 +59,19 @@ public class AppSearchStatsTest {
}
@Test
+ public void testAppSearchCallStats_nullValues() {
+ final @CallStats.CallType int callType = CallStats.CALL_TYPE_PUT_DOCUMENTS;
+
+ final CallStats.Builder cStatsBuilder = new CallStats.Builder().setCallType(callType);
+
+ final CallStats cStats = cStatsBuilder.build();
+
+ assertThat(cStats.getPackageName()).isNull();
+ assertThat(cStats.getDatabase()).isNull();
+ assertThat(cStats.getCallType()).isEqualTo(callType);
+ }
+
+ @Test
public void testAppSearchStats_PutDocumentStats() {
final int generateDocumentProtoLatencyMillis = 1;
final int rewriteDocumentTypesLatencyMillis = 2;
@@ -100,6 +84,8 @@ public class AppSearchStatsTest {
final boolean nativeExceededMaxNumTokens = true;
final PutDocumentStats.Builder pStatsBuilder =
new PutDocumentStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+ .setStatusCode(TEST_STATUS_CODE)
+ .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
.setGenerateDocumentProtoLatencyMillis(generateDocumentProtoLatencyMillis)
.setRewriteDocumentTypesLatencyMillis(rewriteDocumentTypesLatencyMillis)
.setNativeLatencyMillis(nativeLatencyMillis)
@@ -109,17 +95,13 @@ public class AppSearchStatsTest {
.setNativeDocumentSizeBytes(nativeDocumentSize)
.setNativeNumTokensIndexed(nativeNumTokensIndexed)
.setNativeExceededMaxNumTokens(nativeExceededMaxNumTokens);
- pStatsBuilder
- .getGeneralStatsBuilder()
- .setStatusCode(TEST_STATUS_CODE)
- .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS);
+
final PutDocumentStats pStats = pStatsBuilder.build();
- assertThat(pStats.getGeneralStats().getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(pStats.getGeneralStats().getDatabase()).isEqualTo(TEST_DATA_BASE);
- assertThat(pStats.getGeneralStats().getStatusCode()).isEqualTo(TEST_STATUS_CODE);
- assertThat(pStats.getGeneralStats().getTotalLatencyMillis())
- .isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+ assertThat(pStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+ assertThat(pStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
+ assertThat(pStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(pStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
assertThat(pStats.getGenerateDocumentProtoLatencyMillis())
.isEqualTo(generateDocumentProtoLatencyMillis);
assertThat(pStats.getRewriteDocumentTypesLatencyMillis())
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index fa3f45c08202..a2b1c1cb1a49 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.DevicePolicyManagerLiteInternal;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -158,6 +159,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
final long ident = mContext.binder.clearCallingIdentity();
try {
+ LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
@@ -271,6 +273,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
final long ident = mContext.binder.clearCallingIdentity();
try {
+ LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
@@ -339,6 +342,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
// (Need clearCallingIdentity() to pass permission checks.)
final long ident = mContext.binder.clearCallingIdentity();
try {
+ LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
@@ -499,6 +503,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
DevicePolicyManagerServiceTestable dpms;
final long ident = mContext.binder.clearCallingIdentity();
try {
+ LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 5447a58a1643..cedf6361e33b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -84,6 +84,7 @@ import android.app.PendingIntent;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.DevicePolicyManagerLiteInternal;
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.PasswordMetrics;
import android.app.admin.SystemUpdatePolicy;
@@ -280,6 +281,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
private void initializeDpms() {
// Need clearCallingIdentity() to pass permission checks.
final long ident = mContext.binder.clearCallingIdentity();
+ LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
@@ -369,10 +371,14 @@ public class DevicePolicyManagerTest extends DpmTestBase {
.thenReturn(false);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+ LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class);
new DevicePolicyManagerServiceTestable(getServices(), mContext);
// If the device has no DPMS feature, it shouldn't register the local service.
assertThat(LocalServices.getService(DevicePolicyManagerInternal.class)).isNull();
+
+ // But should still register the lite one
+ assertThat(LocalServices.getService(DevicePolicyManagerLiteInternal.class)).isNotNull();
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index fb2db2259c7e..918979cdd859 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -854,7 +854,7 @@ public class DisplayModeDirectorTest {
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
verify(mStatusBarMock, never()).setUdfpsHbmListener(any());
- director.start(createMockSensorManager());
+ director.onBootCompleted();
verify(mStatusBarMock).setUdfpsHbmListener(eq(director.getUdpfsObserver()));
}
@@ -863,6 +863,7 @@ public class DisplayModeDirectorTest {
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
director.start(createMockSensorManager());
+ director.onBootCompleted();
ArgumentCaptor<IUdfpsHbmListener> captor =
ArgumentCaptor.forClass(IUdfpsHbmListener.class);
verify(mStatusBarMock).setUdfpsHbmListener(captor.capture());
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 7241fa00ecf7..90a127701505 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -253,6 +253,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
.setPerson(makePerson("person", "personKey", "personUri"))
.setLongLived(true)
.setExtras(pb)
+ .setStartingTheme(android.R.style.Theme_Black_NoTitleBar_Fullscreen)
.build();
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
@@ -288,6 +289,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(null, si.getTextResName());
assertEquals(0, si.getDisabledMessageResourceId());
assertEquals(null, si.getDisabledMessageResName());
+ assertEquals("android:style/Theme.Black.NoTitleBar.Fullscreen",
+ si.getStartingThemeResName());
}
public void testShortcutInfoParcel_resId() {
@@ -308,6 +311,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
.setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
.setRank(123)
.setExtras(pb)
+ .setStartingTheme(android.R.style.Theme_Black_NoTitleBar_Fullscreen)
.build();
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
@@ -339,6 +343,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(456, si.getIconResourceId());
assertEquals("string/r456", si.getIconResName());
assertEquals("test_uri", si.getIconUri());
+ assertEquals("android:style/Theme.Black.NoTitleBar.Fullscreen",
+ si.getStartingThemeResName());
}
public void testShortcutInfoClone() {
@@ -2210,6 +2216,10 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
android.R.drawable.alert_dark_frame, true, getTestContext().getPackageName()));
assertEquals("" + android.R.string.cancel, ShortcutInfo.lookUpResourceName(res,
android.R.string.cancel, false, getTestContext().getPackageName()));
+ assertEquals("" + android.R.style.Theme_Black_NoTitleBar_Fullscreen,
+ ShortcutInfo.lookUpResourceName(
+ res, android.R.style.Theme_Black_NoTitleBar_Fullscreen, true,
+ getTestContext().getPackageName()));
}
public void testLookUpResourceName_appResources() {
@@ -2236,6 +2246,10 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(android.R.drawable.alert_dark_frame, ShortcutInfo.lookUpResourceId(res,
"" + android.R.drawable.alert_dark_frame, null,
getTestContext().getPackageName()));
+ assertEquals(android.R.style.Theme_Black_NoTitleBar_Fullscreen,
+ ShortcutInfo.lookUpResourceId(
+ res, "" + android.R.style.Theme_Black_NoTitleBar_Fullscreen,
+ null, getTestContext().getPackageName()));
}
// Test for a ShortcutInfo method.
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
index 00b05d4ad10c..14cab021edb0 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
@@ -17,6 +17,7 @@
package com.android.server.vibrator;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import android.hardware.vibrator.IVibrator;
import android.os.VibrationEffect;
@@ -25,8 +26,11 @@ import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.PrimitiveSegment;
import android.os.vibrator.RampSegment;
import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
import android.platform.test.annotations.Presubmit;
+import androidx.test.InstrumentationRegistry;
+
import org.junit.Before;
import org.junit.Test;
@@ -58,7 +62,7 @@ public class DeviceVibrationEffectAdapterTest {
@Before
public void setUp() throws Exception {
- mAdapter = new DeviceVibrationEffectAdapter();
+ mAdapter = new DeviceVibrationEffectAdapter(InstrumentationRegistry.getContext());
}
@Test
@@ -84,28 +88,19 @@ public class DeviceVibrationEffectAdapterTest {
new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0.2f,
/* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 10),
new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
- /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 11),
+ /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 100),
new RampSegment(/* startAmplitude= */ 0.65f, /* endAmplitude= */ 0.65f,
- /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 200)),
+ /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 1000)),
/* repeatIndex= */ 3);
- VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
- new StepSegment(/* amplitude= */ 0, Float.NaN, /* duration= */ 10),
- new StepSegment(/* amplitude= */ 0.5f, Float.NaN, /* duration= */ 100),
- // 10ms ramp becomes 2 steps
- new StepSegment(/* amplitude= */ 1, Float.NaN, /* duration= */ 5),
- new StepSegment(/* amplitude= */ 0.2f, Float.NaN, /* duration= */ 5),
- // 11ms ramp becomes 3 steps
- new StepSegment(/* amplitude= */ 0.8f, Float.NaN, /* duration= */ 5),
- new StepSegment(/* amplitude= */ 0.6f, Float.NaN, /* duration= */ 5),
- new StepSegment(/* amplitude= */ 0.2f, Float.NaN, /* duration= */ 1),
- // 200ms ramp with same amplitude becomes a single step
- new StepSegment(/* amplitude= */ 0.65f, Float.NaN, /* duration= */ 200)),
- // Repeat index fixed after intermediate steps added
- /* repeatIndex= */ 4);
-
- VibratorInfo info = createVibratorInfo(EMPTY_FREQUENCY_MAPPING);
- assertEquals(expected, mAdapter.apply(effect, info));
+ VibrationEffect.Composed adaptedEffect = (VibrationEffect.Composed) mAdapter.apply(effect,
+ createVibratorInfo(EMPTY_FREQUENCY_MAPPING));
+ assertTrue(adaptedEffect.getSegments().size() > effect.getSegments().size());
+ assertTrue(adaptedEffect.getRepeatIndex() >= effect.getRepeatIndex());
+
+ for (VibrationEffectSegment adaptedSegment : adaptedEffect.getSegments()) {
+ assertTrue(adaptedSegment instanceof StepSegment);
+ }
}
@Test
@@ -136,33 +131,6 @@ public class DeviceVibrationEffectAdapterTest {
}
@Test
- public void testStepAndRampSegments_withPwleCapabilityAndNoFrequency_keepsOriginalSteps() {
- VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
- new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 10),
- new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
- new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10),
- new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
- /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
- new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
- /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)),
- /* repeatIndex= */ 2);
-
- VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
- new StepSegment(/* amplitude= */ 0, /* frequency= */ 150, /* duration= */ 10),
- new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 150, /* duration= */ 100),
- new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10),
- new RampSegment(/* startAmplitude= */ 0.1f, /* endAmplitude= */ 0.8f,
- /* startFrequency= */ 50, /* endFrequency= */ 200, /* duration= */ 50),
- new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.1f,
- /* startFrequency= */ 200, /* endFrequency= */ 50, /* duration= */ 20)),
- /* repeatIndex= */ 2);
-
- VibratorInfo info = createVibratorInfo(TEST_FREQUENCY_MAPPING,
- IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
- assertEquals(expected, mAdapter.apply(effect, info));
- }
-
- @Test
public void testStepAndRampSegments_withEmptyFreqMapping_returnsSameAmplitudesAndZeroFreq() {
VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/RampToStepAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/RampToStepAdapterTest.java
new file mode 100644
index 000000000000..95c3bd93e69b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/RampToStepAdapterTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import static org.junit.Assert.assertEquals;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
+
+/**
+ * Tests for {@link RampToStepAdapter}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:RampToStepAdapterTest
+ */
+@Presubmit
+public class RampToStepAdapterTest {
+ private static final int TEST_STEP_DURATION = 5;
+
+ private RampToStepAdapter mAdapter;
+
+ @Before
+ public void setUp() throws Exception {
+ mAdapter = new RampToStepAdapter(TEST_STEP_DURATION);
+ }
+
+ @Test
+ public void testStepAndPrebakedAndPrimitiveSegments_keepsListUnchanged() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+ new PrebakedSegment(
+ VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_LIGHT),
+ new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10)));
+ List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+ assertEquals(-1, mAdapter.apply(segments, -1, createVibratorInfo()));
+ assertEquals(1, mAdapter.apply(segments, 1, createVibratorInfo()));
+
+ assertEquals(originalSegments, segments);
+ }
+
+ @Test
+ public void testRampSegments_withPwleCapability_keepsListUnchanged() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)));
+ List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
+ assertEquals(0, mAdapter.apply(segments, 0, vibratorInfo));
+
+ assertEquals(originalSegments, segments);
+ }
+
+ @Test
+ public void testRampSegments_withoutPwleCapability_convertsRampsToSteps() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ -3, /* endFrequency= */ 0, /* duration= */ 11),
+ new RampSegment(/* startAmplitude= */ 0.65f, /* endAmplitude= */ 0.65f,
+ /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 200)));
+
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+ // 10ms ramp becomes 2 steps
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ -4, /* duration= */ 5),
+ new StepSegment(/* amplitude= */ 0.2f, /* frequency= */ 2, /* duration= */ 5),
+ // 11ms ramp becomes 3 steps
+ new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ -3, /* duration= */ 5),
+ new StepSegment(/* amplitude= */ 0.6f, /* frequency= */ -2, /* duration= */ 5),
+ new StepSegment(/* amplitude= */ 0.2f, /* frequency= */ 0, /* duration= */ 1),
+ // 200ms ramp with same amplitude becomes a single step
+ new StepSegment(/* amplitude= */ 0.65f, /* frequency= */ 0, /* duration= */ 200));
+
+ // Repeat index fixed after intermediate steps added
+ assertEquals(4, mAdapter.apply(segments, 3, createVibratorInfo()));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ private static VibratorInfo createVibratorInfo(int... capabilities) {
+ return new VibratorInfo.Builder(0)
+ .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0))
+ .build();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
new file mode 100644
index 000000000000..f4eb2ded5a9d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import static org.junit.Assert.assertEquals;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
+
+/**
+ * Tests for {@link StepToRampAdapter}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:StepToRampAdapterTest
+ */
+@Presubmit
+public class StepToRampAdapterTest {
+ private StepToRampAdapter mAdapter;
+
+ @Before
+ public void setUp() throws Exception {
+ mAdapter = new StepToRampAdapter(/* rampDownDuration= */ 0);
+ }
+
+ @Test
+ public void testRampAndPrebakedAndPrimitiveSegments_returnsOriginalSegments() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 10),
+ new PrebakedSegment(
+ VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_LIGHT),
+ new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10)));
+ List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+ assertEquals(-1, mAdapter.apply(segments, -1, createVibratorInfo()));
+ assertEquals(1, mAdapter.apply(segments, 1, createVibratorInfo()));
+
+ assertEquals(originalSegments, segments);
+ }
+
+ @Test
+ public void testStepAndRampSegments_withoutPwleCapability_keepsListUnchanged() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)));
+ List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+ assertEquals(-1, mAdapter.apply(segments, -1, createVibratorInfo()));
+ assertEquals(0, mAdapter.apply(segments, 0, createVibratorInfo()));
+
+ assertEquals(originalSegments, segments);
+ }
+
+ @Test
+ public void testStepAndRampSegments_withPwleCapabilityAndNoFrequency_keepsOriginalSteps() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+ new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)));
+ List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
+ assertEquals(3, mAdapter.apply(segments, 3, vibratorInfo));
+
+ assertEquals(originalSegments, segments);
+ }
+
+ @Test
+ public void testStepAndRampSegments_withPwleCapabilityAndStepNextToRamp_convertsStepsToRamps() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20),
+ new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ -1, /* duration= */ 60)));
+
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.5f,
+ /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 50),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.8f,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 60));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
+ assertEquals(2, mAdapter.apply(segments, 2, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withPwleCapabilityAndFrequency_convertsStepsToRamps() {
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ -1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 1, /* duration= */ 100)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.5f,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 100));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
+ assertEquals(0, mAdapter.apply(segments, 0, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownEndingAtNonZero_noRampDownAdded() {
+ int rampDownDuration = 50;
+ mAdapter = new StepToRampAdapter(rampDownDuration);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 1, /* duration= */ 100)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+ /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.8f,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 100));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownAndShortZeroSegment_replaceWithRampDown() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 20),
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 20),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(2, mAdapter.apply(segments, 2, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownAndLongZeroSegment_splitAndAddRampDown() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 150),
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 50),
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ // Repeat index fixed after intermediate steps added
+ assertEquals(3, mAdapter.apply(segments, 2, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownAndNoZeroSegment_noRampDownAdded() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30),
+ new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
+ new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownAndRepeatToNonZeroSegment_noRampDownAdded() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+ /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(0, mAdapter.apply(segments, 0, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownAndRepeatToShortZeroSegment_skipAndAppendRampDown() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 20),
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ // Shift repeat index to the right to use append instead of zero segment.
+ assertEquals(1, mAdapter.apply(segments, 0, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ @Test
+ public void testStepSegments_withRampDownAndRepeatToLongZeroSegment_splitAndAppendRampDown() {
+ mAdapter = new StepToRampAdapter(50);
+
+ List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 120),
+ new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
+ List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+ // Split long zero segment to skip part of it.
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 50),
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 70),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+ /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 50));
+
+ VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ // Shift repeat index to the right to use append with part of the zero segment.
+ assertEquals(1, mAdapter.apply(segments, 0, vibratorInfo));
+
+ assertEquals(expectedSegments, segments);
+ }
+
+ private static VibratorInfo createVibratorInfo(int... capabilities) {
+ return new VibratorInfo.Builder(0)
+ .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0))
+ .build();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index ac3e05d27962..f02e2f081e3b 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.hardware.vibrator.Braking;
import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.IVibratorManager;
@@ -98,13 +99,17 @@ public class VibrationThreadTest {
private IBatteryStats mIBatteryStatsMock;
private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
+ private DeviceVibrationEffectAdapter mEffectAdapter;
private PowerManager.WakeLock mWakeLock;
private TestLooper mTestLooper;
@Before
public void setUp() throws Exception {
mTestLooper = new TestLooper();
- mWakeLock = InstrumentationRegistry.getContext().getSystemService(
+
+ Context context = InstrumentationRegistry.getContext();
+ mEffectAdapter = new DeviceVibrationEffectAdapter(context);
+ mWakeLock = context.getSystemService(
PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
mockVibrators(VIBRATOR_ID);
@@ -985,8 +990,8 @@ public class VibrationThreadTest {
}
private VibrationThread startThreadAndDispatcher(Vibration vib) {
- VibrationThread thread = new VibrationThread(vib, createVibratorControllers(), mWakeLock,
- mIBatteryStatsMock, mThreadCallbacks);
+ VibrationThread thread = new VibrationThread(vib, mEffectAdapter,
+ createVibratorControllers(), mWakeLock, mIBatteryStatsMock, mThreadCallbacks);
doAnswer(answer -> {
thread.vibratorComplete(answer.getArgument(0));
return null;
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index ea2dc0a8a345..9117ae696e9f 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -234,7 +234,7 @@ public class VibratorManagerServiceTest {
CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
- service.cancelVibrate(/* usageFilter= */ -1, service);
+ service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service);
assertTrue(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
@@ -889,13 +889,13 @@ public class VibratorManagerServiceTest {
mockVibrators(1);
VibratorManagerService service = createSystemReadyService();
- service.cancelVibrate(/* usageFilter= */ -1, service);
+ service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service);
assertFalse(service.isVibrating(1));
vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), ALARM_ATTRS);
assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
- service.cancelVibrate(/* usageFilter= */ -1, service);
+ service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service);
assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
}
@@ -924,6 +924,39 @@ public class VibratorManagerServiceTest {
assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
}
+ @Test
+ public void cancelVibrate_withoutUnknownUsage_onlyStopsIfFilteringUnknownOrAllUsages()
+ throws Exception {
+ mockVibrators(1);
+ VibrationAttributes attrs = new VibrationAttributes.Builder()
+ .setUsage(VibrationAttributes.USAGE_UNKNOWN)
+ .build();
+ VibratorManagerService service = createSystemReadyService();
+
+ vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs);
+ assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
+
+ // Do not cancel UNKNOWN vibration when filter is being applied for other usages.
+ service.cancelVibrate(VibrationAttributes.USAGE_RINGTONE, service);
+ assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50));
+
+ service.cancelVibrate(
+ VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK,
+ service);
+ assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50));
+
+ // Cancel UNKNOWN vibration when filtered for that vibration specifically.
+ service.cancelVibrate(VibrationAttributes.USAGE_UNKNOWN, service);
+ assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
+
+ vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs);
+ assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
+
+ // Cancel UNKNOWN vibration when all vibrations are being cancelled.
+ service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service);
+ assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
+ }
+
private void mockCapabilities(long... capabilities) {
when(mNativeWrapperMock.getCapabilities()).thenReturn(
Arrays.stream(capabilities).reduce(0, (a, b) -> a | b));
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 5614aa2a165d..577e36c7d5db 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -394,7 +394,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
"disabledMessage", 0, "disabledMessageResName",
null, null, 0, null, 0, 0,
0, "iconResName", "bitmapPath", null, 0,
- null, null, 0);
+ null, null, null);
return si;
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 2c7c3e3d0a87..a522b5c6161e 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -65,6 +65,8 @@ import static com.android.server.notification.NotificationManagerService.ACTION_
import static com.android.server.notification.NotificationManagerService.ACTION_ENABLE_NAS;
import static com.android.server.notification.NotificationManagerService.ACTION_LEARNMORE_NAS;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -261,6 +263,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Mock
private ShortcutServiceInternal mShortcutServiceInternal;
@Mock
+ private UserManager mUserManager;
+ @Mock
ActivityManager mActivityManager;
@Mock
Resources mResources;
@@ -526,6 +530,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mShortcutHelper = mService.getShortcutHelper();
mShortcutHelper.setLauncherApps(mLauncherApps);
mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);
+ mShortcutHelper.setUserManager(mUserManager);
// Capture PackageIntentReceiver
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
@@ -567,6 +572,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
anyString(), anyInt(), any())).thenReturn(true);
+ when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
// Set the testable bubble extractor
RankingHelper rankingHelper = mService.getRankingHelper();
@@ -6466,7 +6472,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
zenPolicy, NotificationManager.INTERRUPTION_FILTER_NONE, isEnabled);
try {
- mBinderService.addAutomaticZenRule(rule);
+ mBinderService.addAutomaticZenRule(rule, mContext.getPackageName());
fail("Zen policy only applies to priority only mode");
} catch (IllegalArgumentException e) {
// yay
@@ -6474,11 +6480,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
rule = new AutomaticZenRule("test", owner, owner, mock(Uri.class),
zenPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, isEnabled);
- mBinderService.addAutomaticZenRule(rule);
+ mBinderService.addAutomaticZenRule(rule, mContext.getPackageName());
rule = new AutomaticZenRule("test", owner, owner, mock(Uri.class),
null, NotificationManager.INTERRUPTION_FILTER_NONE, isEnabled);
- mBinderService.addAutomaticZenRule(rule);
+ mBinderService.addAutomaticZenRule(rule, mContext.getPackageName());
}
@Test
@@ -7506,6 +7512,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mBinderService.getConversationsForPackage(PKG_P, mUid).getList();
assertEquals(si, conversations.get(0).getShortcutInfo());
assertEquals(si, conversations.get(1).getShortcutInfo());
+
+ // Returns null shortcuts when locked.
+ when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(false);
+ conversations =
+ mBinderService.getConversationsForPackage(PKG_P, mUid).getList();
+ assertThat(conversations.get(0).getShortcutInfo()).isNull();
+ assertThat(conversations.get(1).getShortcutInfo()).isNull();
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
index f43e5a83c95d..11cb150651aa 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
@@ -34,6 +34,7 @@ import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutQueryWrapper;
import android.content.pm.ShortcutServiceInternal;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.TestableLooper;
@@ -71,6 +72,8 @@ public class ShortcutHelperTest extends UiServiceTestCase {
@Mock
ShortcutHelper.ShortcutListener mShortcutListener;
@Mock
+ UserManager mUserManager;
+ @Mock
ShortcutServiceInternal mShortcutServiceInternal;
@Mock
NotificationRecord mNr;
@@ -92,11 +95,12 @@ public class ShortcutHelperTest extends UiServiceTestCase {
MockitoAnnotations.initMocks(this);
mShortcutHelper = new ShortcutHelper(
- mLauncherApps, mShortcutListener, mShortcutServiceInternal);
+ mLauncherApps, mShortcutListener, mShortcutServiceInternal, mUserManager);
when(mSbn.getPackageName()).thenReturn(PKG);
when(mShortcutInfo.getId()).thenReturn(SHORTCUT_ID);
when(mNotif.getBubbleMetadata()).thenReturn(mBubbleMetadata);
when(mBubbleMetadata.getShortcutId()).thenReturn(SHORTCUT_ID);
+ when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
setUpMockNotificationRecord(mNr, KEY);
}
@@ -317,6 +321,25 @@ public class ShortcutHelperTest extends UiServiceTestCase {
.isSameInstanceAs(si);
}
+
+ @Test
+ public void testGetValidShortcutInfo_isValidButUserLocked() {
+ ShortcutInfo si = mock(ShortcutInfo.class);
+ when(si.getPackage()).thenReturn(PKG);
+ when(si.getId()).thenReturn(SHORTCUT_ID);
+ when(si.getUserId()).thenReturn(UserHandle.USER_SYSTEM);
+ when(si.isLongLived()).thenReturn(true);
+ when(si.isEnabled()).thenReturn(true);
+ when(si.getPersons()).thenReturn(new Person[]{PERSON});
+ ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+ shortcuts.add(si);
+ when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
+ when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(false);
+
+ assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM))
+ .isNull();
+ }
+
@Test
public void testGetValidShortcutInfo_hasGetPersonsDataFlag() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index 5262465a399c..d0bf63a1680f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -190,7 +190,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
rule.configurationActivity = new ComponentName("a", "a");
- rule.component = new ComponentName("a", "b");
+ rule.component = new ComponentName("b", "b");
rule.conditionId = new Uri.Builder().scheme("hello").build();
rule.condition = new Condition(rule.conditionId, "", Condition.STATE_TRUE);
rule.enabled = true;
@@ -200,6 +200,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
rule.modified = true;
rule.name = "name";
rule.snoozing = true;
+ rule.pkg = "b";
TypedXmlSerializer out = Xml.newFastSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -215,8 +216,7 @@ public class ZenModeConfigTest extends UiServiceTestCase {
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
- // read from backing component
- assertEquals("a", fromXml.pkg);
+ assertEquals("b", fromXml.pkg);
// always resets on reboot
assertFalse(fromXml.snoozing);
//should all match original
@@ -232,6 +232,55 @@ public class ZenModeConfigTest extends UiServiceTestCase {
assertEquals(rule.zenMode, fromXml.zenMode);
}
+ @Test
+ public void testRuleXml_pkg_component() throws Exception {
+ String tag = "tag";
+
+ ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+ rule.configurationActivity = new ComponentName("a", "a");
+ rule.component = new ComponentName("b", "b");
+
+ TypedXmlSerializer out = Xml.newFastSerializer();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ out.setOutput(new BufferedOutputStream(baos), "utf-8");
+ out.startDocument(null, true);
+ out.startTag(null, tag);
+ ZenModeConfig.writeRuleXml(rule, out);
+ out.endTag(null, tag);
+ out.endDocument();
+
+ TypedXmlPullParser parser = Xml.newFastPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(baos.toByteArray())), null);
+ parser.nextTag();
+ ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
+ assertEquals("b", fromXml.pkg);
+ }
+
+ @Test
+ public void testRuleXml_pkg_configActivity() throws Exception {
+ String tag = "tag";
+
+ ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+ rule.configurationActivity = new ComponentName("a", "a");
+
+ TypedXmlSerializer out = Xml.newFastSerializer();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ out.setOutput(new BufferedOutputStream(baos), "utf-8");
+ out.startDocument(null, true);
+ out.startTag(null, tag);
+ ZenModeConfig.writeRuleXml(rule, out);
+ out.endTag(null, tag);
+ out.endDocument();
+
+ TypedXmlPullParser parser = Xml.newFastPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(baos.toByteArray())), null);
+ parser.nextTag();
+ ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
+ assertNull(fromXml.pkg);
+ }
+
private ZenModeConfig getMutedRingerConfig() {
ZenModeConfig config = new ZenModeConfig();
// Allow alarms, media
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 72c6028e5ad3..00dbaf649ca2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -1597,7 +1597,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ComponentName("android", "ScheduleConditionProvider"),
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule(zenRule, "test");
+ String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
assertTrue(id != null);
ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
@@ -1617,12 +1617,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ComponentName("android", "ScheduleConditionProvider"),
sharedUri,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule(zenRule, "test");
+ String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
new ComponentName("android", "ScheduleConditionProvider"),
sharedUri,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id2 = mZenModeHelperSpy.addAutomaticZenRule(zenRule2, "test");
+ String id2 = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule2, "test");
Condition condition = new Condition(sharedUri, "", Condition.STATE_TRUE);
mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 82c459c6868a..38466ebaa0cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -38,6 +38,7 @@ import static org.mockito.Mockito.timeout;
import android.app.ActivityOptions;
import android.app.ActivityOptions.SourceInfo;
import android.app.WaitResult;
+import android.app.WindowConfiguration;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
@@ -476,6 +477,18 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
transitToDrawnAndVerifyOnLaunchFinished(activityOnNewDisplay);
}
+ @Test
+ public void testConsecutiveLaunchWithDifferentWindowingMode() {
+ mTopActivity.setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+ onActivityLaunched(mTrampolineActivity);
+ mActivityMetricsLogger.notifyActivityLaunching(mTopActivity.intent,
+ mTrampolineActivity /* caller */, mTrampolineActivity.getUid());
+ notifyActivityLaunched(START_SUCCESS, mTopActivity);
+ // Different windowing modes should be independent launch events.
+ transitToDrawnAndVerifyOnLaunchFinished(mTrampolineActivity);
+ transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
+ }
+
private void transitToDrawnAndVerifyOnLaunchFinished(ActivityRecord activity) {
notifyTransitionStarting(activity);
notifyWindowsDrawn(activity);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index d2270b55b954..4e261deb67f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1534,30 +1534,6 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
- public void testSandboxDisplayApis_unresizableAppNotSandboxed() {
- // Set up a display in landscape with an unresizable app.
- setUpDisplaySizeWithApp(2500, 1000);
- mActivity.mDisplayContent.setSandboxDisplayApis(false /* sandboxDisplayApis */);
- prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
- assertFitted();
-
- // Activity max bounds not be sandboxed since sandboxing is disabled.
- assertMaxBoundsInheritDisplayAreaBounds();
- }
-
- @Test
- public void testSandboxDisplayApis_unresizableAppSandboxed() {
- // Set up a display in landscape with an unresizable app.
- setUpDisplaySizeWithApp(2500, 1000);
- mActivity.mDisplayContent.setSandboxDisplayApis(true /* sandboxDisplayApis */);
- prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
- assertFitted();
-
- // Activity max bounds should be sandboxed since sandboxing is enabled.
- assertActivityMaxBoundsSandboxed();
- }
-
- @Test
public void testResizableApp_notSandboxed() {
// Set up a display in landscape with a fully resizable app.
setUpDisplaySizeWithApp(2500, 1000);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 3f1248a5fff7..a1b3159825fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -796,6 +796,9 @@ public class WindowOrganizerTests extends WindowTestsBase {
@Override
public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) {
}
+ @Override
+ public void onAppSplashScreenViewRemoved(int taskId) {
+ }
};
private ActivityRecord makePipableActivity() {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index a14912e5593d..bc812c2ae4a7 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -562,11 +562,10 @@ public class VoiceInteractionManagerService extends SystemService {
}
void switchImplementationIfNeededLocked(boolean force) {
- if (!mCurUserSupported || mTemporarilyDisabled) {
+ if (!mCurUserSupported) {
if (DEBUG_USER) {
Slog.d(TAG, "switchImplementationIfNeeded(): skipping: force= " + force
- + "mCurUserSupported=" + mCurUserSupported
- + "mTemporarilyDisabled=" + mTemporarilyDisabled);
+ + "mCurUserSupported=" + mCurUserSupported);
}
if (mImpl != null) {
mImpl.shutdownLocked();
@@ -1048,13 +1047,16 @@ public class VoiceInteractionManagerService extends SystemService {
if (DEBUG) Slog.d(TAG, "setDisabled(): already " + disabled);
return;
}
- Slog.i(TAG, "setDisabled(): changing to " + disabled);
- final long caller = Binder.clearCallingIdentity();
- try {
- mTemporarilyDisabled = disabled;
- switchImplementationIfNeeded(/* force= */ false);
- } finally {
- Binder.restoreCallingIdentity(caller);
+ mTemporarilyDisabled = disabled;
+ if (mTemporarilyDisabled) {
+ Slog.i(TAG, "setDisabled(): temporarily disabling and hiding current session");
+ try {
+ hideCurrentSession();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call hideCurrentSession", e);
+ }
+ } else {
+ Slog.i(TAG, "setDisabled(): re-enabling");
}
}
}
@@ -1508,12 +1510,20 @@ public class VoiceInteractionManagerService extends SystemService {
public boolean showSessionForActiveService(Bundle args, int sourceFlags,
IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
+ if (DEBUG_USER) Slog.d(TAG, "showSessionForActiveService()");
+
synchronized (this) {
if (mImpl == null) {
Slog.w(TAG, "showSessionForActiveService without running voice interaction"
+ "service");
return false;
}
+ if (mTemporarilyDisabled) {
+ Slog.i(TAG, "showSessionForActiveService(): ignored while temporarily "
+ + "disabled");
+ return false;
+ }
+
final long caller = Binder.clearCallingIdentity();
try {
return mImpl.showSessionLocked(args,
@@ -1530,22 +1540,21 @@ public class VoiceInteractionManagerService extends SystemService {
@Override
public void hideCurrentSession() throws RemoteException {
enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
- synchronized (this) {
- if (mImpl == null) {
- return;
- }
- final long caller = Binder.clearCallingIdentity();
- try {
- if (mImpl.mActiveSession != null && mImpl.mActiveSession.mSession != null) {
- try {
- mImpl.mActiveSession.mSession.closeSystemDialogs();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to call closeSystemDialogs", e);
- }
+
+ if (mImpl == null) {
+ return;
+ }
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ if (mImpl.mActiveSession != null && mImpl.mActiveSession.mSession != null) {
+ try {
+ mImpl.mActiveSession.mSession.closeSystemDialogs();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call closeSystemDialogs", e);
}
- } finally {
- Binder.restoreCallingIdentity(caller);
}
+ } finally {
+ Binder.restoreCallingIdentity(caller);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
index 6c355a3b4b30..2e3ca0157a3b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
@@ -71,6 +71,7 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
pw.println("");
pw.println(" hide");
pw.println(" Hides the current session");
+ pw.println("");
pw.println(" disable [true|false]");
pw.println(" Temporarily disable (when true) service");
pw.println("");
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index ea5a43104bba..e07fbbf7a1c1 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -27,6 +27,7 @@ android_test {
libs: ["android.test.runner"],
static_libs: [
"androidx.test.ext.junit",
+ "androidx.test.uiautomator_uiautomator",
"compatibility-device-util-axt",
"platform-test-annotations",
"truth-prebuilt",
diff --git a/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/AndroidManifest.xml b/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/AndroidManifest.xml
index 5d8f5fc2da93..8c3d87698e17 100644
--- a/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/AndroidManifest.xml
+++ b/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/AndroidManifest.xml
@@ -19,5 +19,6 @@
package="com.android.emojirenderingtestapp">
<application>
<activity android:name=".EmojiRenderingTestActivity"/>
+ <activity android:name=".GetAvailableFontsTestActivity"/>
</application>
</manifest>
diff --git a/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/src/com/android/emojirenderingtestapp/GetAvailableFontsTestActivity.java b/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/src/com/android/emojirenderingtestapp/GetAvailableFontsTestActivity.java
new file mode 100644
index 000000000000..b9a91490f517
--- /dev/null
+++ b/tests/UpdatableSystemFontTest/EmojiRenderingTestApp/src/com/android/emojirenderingtestapp/GetAvailableFontsTestActivity.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.emojirenderingtestapp;
+
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
+import android.app.Activity;
+import android.graphics.fonts.Font;
+import android.graphics.fonts.SystemFonts;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class GetAvailableFontsTestActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ String emojiFontPath = "<Not found>";
+ for (Font font : SystemFonts.getAvailableFonts()) {
+ // Calls font attribute getters to make sure that they don't open font files.
+ font.getAxes();
+ font.getFile();
+ font.getLocaleList();
+ font.getStyle();
+ font.getTtcIndex();
+ if ("NotoColorEmoji.ttf".equals(font.getFile().getName())) {
+ emojiFontPath = font.getFile().getAbsolutePath();
+ }
+ }
+ LinearLayout container = new LinearLayout(this);
+ container.setOrientation(LinearLayout.VERTICAL);
+ TextView textView = new TextView(this);
+ textView.setText(emojiFontPath);
+ container.addView(textView, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
+ setContentView(container);
+ }
+}
diff --git a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
index 80b0dfeb8804..6bd07d0a84fd 100644
--- a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
+++ b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
@@ -40,6 +40,9 @@ import android.util.Pair;
import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
import com.android.compatibility.common.util.StreamUtil;
import com.android.compatibility.common.util.SystemUtil;
@@ -101,6 +104,9 @@ public class UpdatableSystemFontTest {
EMOJI_RENDERING_TEST_APP_ID + "/.EmojiRenderingTestActivity";
private static final long ACTIVITY_TIMEOUT_MILLIS = SECONDS.toMillis(10);
+ private static final String GET_AVAILABLE_FONTS_TEST_ACTIVITY =
+ EMOJI_RENDERING_TEST_APP_ID + "/.GetAvailableFontsTestActivity";
+
private static final Pattern PATTERN_FONT_FILES = Pattern.compile("\\.(ttf|otf|ttc|otc)$");
private static final Pattern PATTERN_TMP_FILES = Pattern.compile("^/data/local/tmp/");
private static final Pattern PATTERN_DATA_FONT_FILES = Pattern.compile("^/data/fonts/files/");
@@ -109,6 +115,7 @@ public class UpdatableSystemFontTest {
private String mKeyId;
private FontManager mFontManager;
+ private UiDevice mUiDevice;
@Before
public void setUp() throws Exception {
@@ -120,6 +127,7 @@ public class UpdatableSystemFontTest {
mKeyId = insertCert(CERT_PATH);
mFontManager = context.getSystemService(FontManager.class);
expectCommandToSucceed("cmd font clear");
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
}
@After
@@ -287,6 +295,19 @@ public class UpdatableSystemFontTest {
assertThat(countMatch(openFiles, patternEmojiVPlus1)).isEqualTo(0);
}
+ @Test
+ public void getAvailableFonts() throws Exception {
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
+ startActivity(EMOJI_RENDERING_TEST_APP_ID, GET_AVAILABLE_FONTS_TEST_ACTIVITY);
+ // GET_AVAILABLE_FONTS_TEST_ACTIVITY shows the NotoColorEmoji path it got.
+ mUiDevice.wait(
+ Until.findObject(By.pkg(EMOJI_RENDERING_TEST_APP_ID).text(fontPath)),
+ ACTIVITY_TIMEOUT_MILLIS);
+ // The font file should not be opened just by querying the path using
+ // SystemFont.getAvailableFonts().
+ assertThat(isFileOpenedBy(fontPath, EMOJI_RENDERING_TEST_APP_ID)).isFalse();
+ }
+
private static String insertCert(String certPath) throws Exception {
Pair<String, String> result;
try (InputStream is = new FileInputStream(certPath)) {
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 3360d40062a3..b7a6d0ff7607 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -57,6 +57,7 @@ import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
@@ -707,10 +708,9 @@ public class VcnManagementServiceTest {
@Test(expected = SecurityException.class)
public void testAddVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
- doThrow(new SecurityException())
+ doReturn(PackageManager.PERMISSION_DENIED)
.when(mMockContext)
- .enforceCallingOrSelfPermission(
- eq(android.Manifest.permission.NETWORK_FACTORY), any());
+ .checkCallingOrSelfPermission(any());
mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
}
@@ -724,10 +724,9 @@ public class VcnManagementServiceTest {
@Test(expected = SecurityException.class)
public void testRemoveVcnUnderlyingNetworkPolicyListenerInvalidPermission() {
- doThrow(new SecurityException())
+ doReturn(PackageManager.PERMISSION_DENIED)
.when(mMockContext)
- .enforceCallingOrSelfPermission(
- eq(android.Manifest.permission.NETWORK_FACTORY), any());
+ .checkCallingOrSelfPermission(any());
mVcnMgmtSvc.removeVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
}
@@ -919,10 +918,9 @@ public class VcnManagementServiceTest {
@Test(expected = SecurityException.class)
public void testGetUnderlyingNetworkPolicyInvalidPermission() {
- doThrow(new SecurityException())
+ doReturn(PackageManager.PERMISSION_DENIED)
.when(mMockContext)
- .enforceCallingOrSelfPermission(
- eq(android.Manifest.permission.NETWORK_FACTORY), any());
+ .checkCallingOrSelfPermission(any());
mVcnMgmtSvc.getUnderlyingNetworkPolicy(new NetworkCapabilities(), new LinkProperties());
}