summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-06-23 02:23:57 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-06-23 02:23:57 +0000
commit55bdbd41fb015f6d1de88b4b151771cc9557346b (patch)
tree50f364319dfae2b14f45ce5ba1d065a9a3631a88
parentff0be1919d9249006a6d6b844f8012436d64f322 (diff)
parent40580bb29da2a50be6993f1af1abf18e01664da4 (diff)
downloadbase-android12-mainline-documentsui-release.tar.gz
Snap for 7483611 from 40580bb29da2a50be6993f1af1abf18e01664da4 to mainline-documentsui-releaseandroid-mainline-12.0.0_r26android-mainline-12.0.0_r2aml_doc_310851020android12-mainline-documentsui-release
Change-Id: I64bdb7cf048c8392265965063533fa8a6e6e7274
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java22
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl4
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java6
-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/stats/SchemaMigrationStats.java189
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java27
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotDisplayedBySystemMap.java (renamed from apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java)6
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java28
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java105
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesDocument.java (renamed from apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java)14
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesMap.java (renamed from apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java)4
-rw-r--r--apex/appsearch/synced_jetpack_changeid.txt2
-rw-r--r--apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java2
-rw-r--r--apex/jobscheduler/framework/java/android/app/AlarmManager.java16
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java207
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java3
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java7
-rw-r--r--api/Android.bp73
-rw-r--r--api/OWNERS5
-rwxr-xr-xapi/api_versions_trimmer.py136
-rw-r--r--api/api_versions_trimmer_unittests.py307
-rw-r--r--core/java/android/app/ActivityThread.java15
-rw-r--r--core/java/android/app/IApplicationThread.aidl2
-rw-r--r--core/java/android/app/Notification.java14
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java62
-rw-r--r--core/java/android/app/Service.java24
-rw-r--r--core/java/android/app/WallpaperColors.java23
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java6
-rw-r--r--core/java/android/content/Context.java35
-rw-r--r--core/java/android/content/pm/IPackageInstaller.aidl2
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl5
-rw-r--r--core/java/android/content/pm/PackageManager.java7
-rw-r--r--core/java/android/content/pm/PackagePartitions.java11
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageImpl.java6
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageUtils.java63
-rw-r--r--core/java/android/content/pm/parsing/component/ParsedComponent.java2
-rw-r--r--core/java/android/hardware/biometrics/BiometricFingerprintConstants.java20
-rw-r--r--core/java/android/hardware/display/DisplayManagerInternal.java47
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java6
-rw-r--r--core/java/android/hardware/input/InputDeviceVibrator.java8
-rw-r--r--core/java/android/os/BatteryUsageStats.java42
-rw-r--r--core/java/android/os/Vibrator.java31
-rw-r--r--core/java/android/os/VibratorInfo.java275
-rw-r--r--core/java/android/security/keymaster/KeymasterDefs.java1
-rw-r--r--core/java/android/service/translation/TranslationService.java24
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java10
-rw-r--r--core/java/android/service/voice/HotwordDetectionService.java4
-rw-r--r--core/java/android/service/voice/SoftwareHotwordDetector.java34
-rw-r--r--core/java/android/view/InsetsController.java2
-rw-r--r--core/java/android/view/ScrollCaptureTarget.java27
-rw-r--r--core/java/android/view/SurfaceControl.java29
-rw-r--r--core/java/android/view/SurfaceView.java23
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/view/ViewRootInsetsControllerHost.java4
-rw-r--r--core/java/android/view/WindowInsetsAnimation.java7
-rw-r--r--core/java/android/view/translation/TranslationCapability.java22
-rw-r--r--core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl3
-rw-r--r--core/java/com/android/internal/content/om/OverlayConfig.java2
-rw-r--r--core/java/com/android/internal/infra/ServiceConnector.java2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java18
-rw-r--r--core/java/com/android/internal/view/ScrollCaptureViewSupport.java15
-rw-r--r--core/java/com/android/server/SystemConfig.java20
-rw-r--r--core/jni/android_view_SurfaceControl.cpp12
-rw-r--r--core/res/res/values-af/strings.xml2
-rw-r--r--core/res/res/values-am/strings.xml2
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-as/strings.xml2
-rw-r--r--core/res/res/values-az/strings.xml14
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml2
-rw-r--r--core/res/res/values-be/strings.xml2
-rw-r--r--core/res/res/values-bg/strings.xml2
-rw-r--r--core/res/res/values-bn/strings.xml8
-rw-r--r--core/res/res/values-bs/strings.xml2
-rw-r--r--core/res/res/values-ca/strings.xml2
-rw-r--r--core/res/res/values-cs/strings.xml2
-rw-r--r--core/res/res/values-da/strings.xml2
-rw-r--r--core/res/res/values-de/strings.xml2
-rw-r--r--core/res/res/values-el/strings.xml2
-rw-r--r--core/res/res/values-en-rAU/strings.xml2
-rw-r--r--core/res/res/values-en-rCA/strings.xml2
-rw-r--r--core/res/res/values-en-rGB/strings.xml2
-rw-r--r--core/res/res/values-en-rIN/strings.xml2
-rw-r--r--core/res/res/values-en-rXC/strings.xml1
-rw-r--r--core/res/res/values-es-rUS/strings.xml2
-rw-r--r--core/res/res/values-es/strings.xml2
-rw-r--r--core/res/res/values-et/strings.xml2
-rw-r--r--core/res/res/values-eu/strings.xml2
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml2
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/res/res/values-gl/strings.xml2
-rw-r--r--core/res/res/values-gu/strings.xml8
-rw-r--r--core/res/res/values-hi/strings.xml2
-rw-r--r--core/res/res/values-hr/strings.xml2
-rw-r--r--core/res/res/values-hu/strings.xml2
-rw-r--r--core/res/res/values-hy/strings.xml2
-rw-r--r--core/res/res/values-in/strings.xml2
-rw-r--r--core/res/res/values-is/strings.xml2
-rw-r--r--core/res/res/values-it/strings.xml2
-rw-r--r--core/res/res/values-iw/strings.xml2
-rw-r--r--core/res/res/values-ja/strings.xml2
-rw-r--r--core/res/res/values-ka/strings.xml2
-rw-r--r--core/res/res/values-kk/strings.xml2
-rw-r--r--core/res/res/values-km/strings.xml2
-rw-r--r--core/res/res/values-kn/strings.xml2
-rw-r--r--core/res/res/values-ko/strings.xml2
-rw-r--r--core/res/res/values-ky/strings.xml2
-rw-r--r--core/res/res/values-lo/strings.xml2
-rw-r--r--core/res/res/values-lt/strings.xml2
-rw-r--r--core/res/res/values-lv/strings.xml2
-rw-r--r--core/res/res/values-mk/strings.xml2
-rw-r--r--core/res/res/values-ml/strings.xml2
-rw-r--r--core/res/res/values-mn/strings.xml2
-rw-r--r--core/res/res/values-mr/strings.xml2
-rw-r--r--core/res/res/values-ms/strings.xml2
-rw-r--r--core/res/res/values-my/strings.xml2
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne/strings.xml2
-rw-r--r--core/res/res/values-nl/strings.xml2
-rw-r--r--core/res/res/values-or/strings.xml2
-rw-r--r--core/res/res/values-pa/strings.xml2
-rw-r--r--core/res/res/values-pl/strings.xml2
-rw-r--r--core/res/res/values-pt-rBR/strings.xml2
-rw-r--r--core/res/res/values-pt-rPT/strings.xml2
-rw-r--r--core/res/res/values-pt/strings.xml2
-rw-r--r--core/res/res/values-ro/strings.xml2
-rw-r--r--core/res/res/values-ru/strings.xml2
-rw-r--r--core/res/res/values-si/strings.xml2
-rw-r--r--core/res/res/values-sk/strings.xml2
-rw-r--r--core/res/res/values-sl/strings.xml2
-rw-r--r--core/res/res/values-sq/strings.xml2
-rw-r--r--core/res/res/values-sr/strings.xml2
-rw-r--r--core/res/res/values-sv/strings.xml2
-rw-r--r--core/res/res/values-sw/strings.xml2
-rw-r--r--core/res/res/values-ta/strings.xml2
-rw-r--r--core/res/res/values-te/strings.xml8
-rw-r--r--core/res/res/values-th/strings.xml2
-rw-r--r--core/res/res/values-tl/strings.xml2
-rw-r--r--core/res/res/values-tr/strings.xml2
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur/strings.xml2
-rw-r--r--core/res/res/values-uz/strings.xml2
-rw-r--r--core/res/res/values-vi/strings.xml2
-rw-r--r--core/res/res/values-zh-rCN/strings.xml2
-rw-r--r--core/res/res/values-zh-rHK/strings.xml2
-rw-r--r--core/res/res/values-zh-rTW/strings.xml2
-rw-r--r--core/res/res/values-zu/strings.xml2
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java117
-rw-r--r--core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java4
-rw-r--r--core/tests/coretests/src/android/os/VibratorInfoTest.java63
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java48
-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.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java31
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java13
-rw-r--r--location/java/android/location/GnssMeasurement.java22
-rw-r--r--obex/javax/obex/ObexHelper.java14
-rw-r--r--obex/javax/obex/ObexTransport.java2
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java8
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java1
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java20
-rw-r--r--packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java33
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml3
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java20
-rw-r--r--packages/SystemUI/docs/qs-tiles.md1
-rw-r--r--packages/SystemUI/res/drawable/rounded_bg_full.xml3
-rw-r--r--packages/SystemUI/res/layout/notif_half_shelf.xml17
-rw-r--r--packages/SystemUI/res/layout/notif_half_shelf_row.xml113
-rw-r--r--packages/SystemUI/res/values-az/strings.xml2
-rw-r--r--packages/SystemUI/res/values-be/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml3
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-de/strings.xml3
-rw-r--r--packages/SystemUI/res/values-et/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml6
-rw-r--r--packages/SystemUI/res/values-in/strings.xml6
-rw-r--r--packages/SystemUI/res/values-it/strings.xml6
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-km/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml6
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml3
-rw-r--r--packages/SystemUI/res/values-my/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml3
-rw-r--r--packages/SystemUI/res/values-night/colors.xml4
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-or/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-si/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml4
-rw-r--r--packages/SystemUI/res/values-th/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml3
-rw-r--r--packages/SystemUI/res/values/dimens.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt86
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHost.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/SmallHash.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java65
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java22
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java20
-rw-r--r--services/core/java/com/android/server/appop/DiscreteRegistry.java112
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java1
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java10
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java17
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java20
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java151
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java35
-rw-r--r--services/core/java/com/android/server/pm/PackageDexOptimizer.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java18
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java26
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java381
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java16
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java5
-rw-r--r--services/core/java/com/android/server/policy/LegacyGlobalActions.java5
-rw-r--r--services/core/java/com/android/server/recoverysystem/RecoverySystemService.java4
-rw-r--r--services/core/java/com/android/server/vcn/Vcn.java4
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java26
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationThread.java14
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorController.java38
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java34
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java69
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java146
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java6
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java13
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/ShellRoot.java12
-rw-r--r--services/core/java/com/android/server/wm/StartingData.java6
-rw-r--r--services/core/java/com/android/server/wm/Task.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java11
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java1
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp5
-rw-r--r--services/core/jni/com_android_server_vibrator_VibratorController.cpp139
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd4
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java21
-rw-r--r--services/net/Android.bp12
-rw-r--r--services/net/java/android/net/IpMemoryStore.java98
-rw-r--r--services/net/java/android/net/NetworkMonitorManager.java203
-rw-r--r--services/net/java/android/net/ip/IpClientCallbacks.java136
-rw-r--r--services/net/java/android/net/ip/IpClientManager.java326
-rw-r--r--services/net/java/android/net/ip/IpClientUtil.java204
-rw-r--r--services/net/java/android/net/util/DhcpResultsCompatUtil.java54
-rw-r--r--services/net/java/android/net/util/KeepalivePacketDataUtil.java223
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java35
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java8
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java32
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java32
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java218
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java354
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java167
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java179
-rw-r--r--services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java58
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java34
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java69
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java12
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java93
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java11
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java625
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java4
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java8
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java14
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java15
-rw-r--r--telecomm/java/com/android/internal/telecom/ITelecomService.aidl2
-rw-r--r--tests/Internal/src/android/app/WallpaperColorsTest.java23
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnTest.java21
377 files changed, 5822 insertions, 3263 deletions
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index 4ef91b5e3bc1..0b24c0d9f5c5 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -136,8 +136,6 @@ public final class AppSearchSession implements Closeable {
* @param callback Callback to receive errors resulting from setting the schema. If the
* operation succeeds, the callback will be invoked with {@code null}.
*/
- // TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
- // exposed.
public void setSchema(
@NonNull SetSchemaRequest request,
@NonNull Executor workExecutor,
@@ -152,7 +150,7 @@ public final class AppSearchSession implements Closeable {
for (AppSearchSchema schema : request.getSchemas()) {
schemaBundles.add(schema.getBundle());
}
- Map<String, List<Bundle>> schemasPackageAccessibleBundles =
+ Map<String, List<Bundle>> schemasVisibleToPackagesBundles =
new ArrayMap<>(request.getSchemasVisibleToPackagesInternal().size());
for (Map.Entry<String, Set<PackageIdentifier>> entry :
request.getSchemasVisibleToPackagesInternal().entrySet()) {
@@ -160,7 +158,7 @@ public final class AppSearchSession implements Closeable {
for (PackageIdentifier packageIdentifier : entry.getValue()) {
packageIdentifierBundles.add(packageIdentifier.getBundle());
}
- schemasPackageAccessibleBundles.put(entry.getKey(), packageIdentifierBundles);
+ schemasVisibleToPackagesBundles.put(entry.getKey(), packageIdentifierBundles);
}
// No need to trigger migration if user never set migrator
@@ -168,14 +166,14 @@ public final class AppSearchSession implements Closeable {
setSchemaNoMigrations(
request,
schemaBundles,
- schemasPackageAccessibleBundles,
+ schemasVisibleToPackagesBundles,
callbackExecutor,
callback);
} else {
setSchemaWithMigrations(
request,
schemaBundles,
- schemasPackageAccessibleBundles,
+ schemasVisibleToPackagesBundles,
workExecutor,
callbackExecutor,
callback);
@@ -704,7 +702,7 @@ public final class AppSearchSession implements Closeable {
private void setSchemaNoMigrations(
@NonNull SetSchemaRequest request,
@NonNull List<Bundle> schemaBundles,
- @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
+ @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
try {
@@ -713,7 +711,7 @@ public final class AppSearchSession implements Closeable {
mDatabaseName,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
- schemasPackageAccessibleBundles,
+ schemasVisibleToPackagesBundles,
request.isForceOverride(),
request.getVersion(),
mUserHandle,
@@ -761,7 +759,7 @@ public final class AppSearchSession implements Closeable {
private void setSchemaWithMigrations(
@NonNull SetSchemaRequest request,
@NonNull List<Bundle> schemaBundles,
- @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
+ @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
@NonNull Executor workExecutor,
@NonNull @CallbackExecutor Executor callbackExecutor,
@NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
@@ -787,7 +785,7 @@ public final class AppSearchSession implements Closeable {
// No need to trigger migration if no migrator is active.
if (activeMigrators.isEmpty()) {
- setSchemaNoMigrations(request, schemaBundles, schemasPackageAccessibleBundles,
+ setSchemaNoMigrations(request, schemaBundles, schemasVisibleToPackagesBundles,
callbackExecutor, callback);
return;
}
@@ -801,7 +799,7 @@ public final class AppSearchSession implements Closeable {
mDatabaseName,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
- schemasPackageAccessibleBundles,
+ schemasVisibleToPackagesBundles,
/*forceOverride=*/ false,
request.getVersion(),
mUserHandle,
@@ -853,7 +851,7 @@ public final class AppSearchSession implements Closeable {
mDatabaseName,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
- schemasPackageAccessibleBundles,
+ schemasVisibleToPackagesBundles,
/*forceOverride=*/ true,
request.getVersion(),
mUserHandle,
diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
index 0b26e146a7a4..c639ef604de8 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl
@@ -32,7 +32,7 @@ interface IAppSearchManager {
* @param schemaBundles List of {@link AppSearchSchema} bundles.
* @param schemasNotDisplayedBySystem Schema types that should not be surfaced on platform
* surfaces.
- * @param schemasPackageAccessibleBundles Schema types that are visible to the specified
+ * @param schemasVisibleToPackagesBundles Schema types that are visible to the specified
* packages. The value List contains PackageIdentifier Bundles.
* @param forceOverride Whether to apply the new schema even if it is incompatible. All
* incompatible documents will be deleted.
@@ -48,7 +48,7 @@ interface IAppSearchManager {
in String databaseName,
in List<Bundle> schemaBundles,
in List<String> schemasNotDisplayedBySystem,
- in Map<String, List<Bundle>> schemasPackageAccessibleBundles,
+ in Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
boolean forceOverride,
in int schemaVersion,
in UserHandle userHandle,
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 400c24138060..ac584fe4b91b 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -333,7 +333,7 @@ public class AppSearchManagerService extends SystemService {
for (int i = 0; i < schemaBundles.size(); i++) {
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
}
- Map<String, List<PackageIdentifier>> schemasPackageAccessible =
+ Map<String, List<PackageIdentifier>> schemasVisibleToPackages =
new ArrayMap<>(schemasVisibleToPackagesBundles.size());
for (Map.Entry<String, List<Bundle>> entry :
schemasVisibleToPackagesBundles.entrySet()) {
@@ -343,7 +343,7 @@ public class AppSearchManagerService extends SystemService {
packageIdentifiers.add(
new PackageIdentifier(entry.getValue().get(i)));
}
- schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
+ schemasVisibleToPackages.put(entry.getKey(), packageIdentifiers);
}
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
SetSchemaResponse setSchemaResponse = instance.getAppSearchImpl().setSchema(
@@ -352,7 +352,7 @@ public class AppSearchManagerService extends SystemService {
schemas,
instance.getVisibilityStore(),
schemasNotDisplayedBySystem,
- schemasPackageAccessible,
+ schemasVisibleToPackages,
forceOverride,
schemaVersion);
++operationSuccessCount;
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 77a1bb402bd3..4ad1c8c56979 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
@@ -346,11 +346,11 @@ public final class AppSearchImpl implements Closeable {
* @param packageName The package name that owns the schemas.
* @param databaseName The name of the database where this schema lives.
* @param schemas Schemas to set for this app.
- * @param visibilityStore If set, {@code schemasNotPlatformSurfaceable} and {@code
- * schemasPackageAccessible} will be saved here if the schema is successfully applied.
- * @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
+ * @param visibilityStore If set, {@code schemasNotDisplayedBySystem} and {@code
+ * schemasVisibleToPackages} will be saved here if the schema is successfully applied.
+ * @param schemasNotDisplayedBySystem Schema types that should not be surfaced on platform
* surfaces.
- * @param schemasPackageAccessible Schema types that are visible to the specified packages.
+ * @param schemasVisibleToPackages Schema types that are visible to the specified packages.
* @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
* which do not comply with the new schema will be deleted.
* @param version The overall version number of the request.
@@ -366,8 +366,8 @@ public final class AppSearchImpl implements Closeable {
@NonNull String databaseName,
@NonNull List<AppSearchSchema> schemas,
@Nullable VisibilityStore visibilityStore,
- @NonNull List<String> schemasNotPlatformSurfaceable,
- @NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible,
+ @NonNull List<String> schemasNotDisplayedBySystem,
+ @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages,
boolean forceOverride,
int version)
throws AppSearchException {
@@ -430,25 +430,25 @@ public final class AppSearchImpl implements Closeable {
}
if (visibilityStore != null) {
- Set<String> prefixedSchemasNotPlatformSurfaceable =
- new ArraySet<>(schemasNotPlatformSurfaceable.size());
- for (int i = 0; i < schemasNotPlatformSurfaceable.size(); i++) {
- prefixedSchemasNotPlatformSurfaceable.add(
- prefix + schemasNotPlatformSurfaceable.get(i));
+ Set<String> prefixedSchemasNotDisplayedBySystem =
+ new ArraySet<>(schemasNotDisplayedBySystem.size());
+ for (int i = 0; i < schemasNotDisplayedBySystem.size(); i++) {
+ prefixedSchemasNotDisplayedBySystem.add(
+ prefix + schemasNotDisplayedBySystem.get(i));
}
- Map<String, List<PackageIdentifier>> prefixedSchemasPackageAccessible =
- new ArrayMap<>(schemasPackageAccessible.size());
+ Map<String, List<PackageIdentifier>> prefixedSchemasVisibleToPackages =
+ new ArrayMap<>(schemasVisibleToPackages.size());
for (Map.Entry<String, List<PackageIdentifier>> entry :
- schemasPackageAccessible.entrySet()) {
- prefixedSchemasPackageAccessible.put(prefix + entry.getKey(), entry.getValue());
+ schemasVisibleToPackages.entrySet()) {
+ prefixedSchemasVisibleToPackages.put(prefix + entry.getKey(), entry.getValue());
}
visibilityStore.setVisibility(
packageName,
databaseName,
- prefixedSchemasNotPlatformSurfaceable,
- prefixedSchemasPackageAccessible);
+ prefixedSchemasNotDisplayedBySystem,
+ prefixedSchemasVisibleToPackages);
}
return SetSchemaResponseToProtoConverter.toSetSchemaResponse(
@@ -737,6 +737,9 @@ public final class AppSearchImpl implements Closeable {
if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
// Client wanted to query over some packages that weren't its own. This isn't
// allowed through local query so we can return early with no results.
+ if (logger != null) {
+ sStatsBuilder.setStatusCode(AppSearchResult.RESULT_SECURITY_ERROR);
+ }
return new SearchResultPage(Bundle.EMPTY);
}
@@ -768,7 +771,7 @@ 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
- * userContext}.
+ * callerUserHandle}.
* @param visibilityStore Optional visibility store to obtain system and package visibility
* settings from
* @param callerUid UID of the client making the globalQuery call.
@@ -1465,7 +1468,6 @@ public final class AppSearchImpl implements Closeable {
mOptimizeIntervalCountLocked = 0;
mSchemaMapLocked.clear();
mNamespaceMapLocked.clear();
-
if (initStatsBuilder != null) {
initStatsBuilder
.setHasReset(true)
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SchemaMigrationStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SchemaMigrationStats.java
new file mode 100644
index 000000000000..6e1e2d5f774b
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SchemaMigrationStats.java
@@ -0,0 +1,189 @@
+/*
+ * 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.SetSchemaRequest;
+
+import java.util.Objects;
+
+/**
+ * Class holds detailed stats for Schema migration.
+ *
+ * @hide
+ */
+// TODO(b/173532925): Hides getter and setter functions for accessing {@code
+// mFirstSetSchemaLatencyMillis} and {@code mSecondSetSchemaLatencyMillis} field.
+
+public final class SchemaMigrationStats {
+ /** GetSchema latency in milliseconds. */
+ private final int mGetSchemaLatencyMillis;
+
+ /**
+ * Latency of querying all documents that need to be migrated to new version and transforming
+ * documents to new version in milliseconds.
+ */
+ private final int mQueryAndTransformLatencyMillis;
+
+ private final int mFirstSetSchemaLatencyMillis;
+
+ private final int mSecondSetSchemaLatencyMillis;
+
+ /** Latency of putting migrated document to Icing lib in milliseconds. */
+ private final int mSaveDocumentLatencyMillis;
+
+ private final int mMigratedDocumentCount;
+
+ private final int mSavedDocumentCount;
+
+ SchemaMigrationStats(@NonNull Builder builder) {
+ Objects.requireNonNull(builder);
+ mGetSchemaLatencyMillis = builder.mGetSchemaLatencyMillis;
+ mQueryAndTransformLatencyMillis = builder.mQueryAndTransformLatencyMillis;
+ mFirstSetSchemaLatencyMillis = builder.mFirstSetSchemaLatencyMillis;
+ mSecondSetSchemaLatencyMillis = builder.mSecondSetSchemaLatencyMillis;
+ mSaveDocumentLatencyMillis = builder.mSaveDocumentLatencyMillis;
+ mMigratedDocumentCount = builder.mMigratedDocumentCount;
+ mSavedDocumentCount = builder.mSavedDocumentCount;
+ }
+
+ /** Returns GetSchema latency in milliseconds. */
+ public int getGetSchemaLatencyMillis() {
+ return mGetSchemaLatencyMillis;
+ }
+
+ /**
+ * Returns latency of querying all documents that need to be migrated to new version and
+ * transforming documents to new version in milliseconds.
+ */
+ public int getQueryAndTransformLatencyMillis() {
+ return mQueryAndTransformLatencyMillis;
+ }
+
+ /**
+ * Returns latency of first SetSchema action in milliseconds.
+ *
+ * <p>If all schema fields are backward compatible, the schema will be successful set to Icing.
+ * Otherwise, we will retrieve incompatible types here.
+ *
+ * <p>Please see {@link SetSchemaRequest} for what is "incompatible".
+ */
+ public int getFirstSetSchemaLatencyMillis() {
+ return mFirstSetSchemaLatencyMillis;
+ }
+
+ /**
+ * Returns latency of second SetSchema action in milliseconds.
+ *
+ * <p>If all schema fields are backward compatible, the schema will be successful set to Icing
+ * in the first setSchema action and this value will be 0. Otherwise, schema types will be set
+ * to Icing by this action.
+ */
+ public int getSecondSetSchemaLatencyMillis() {
+ return mSecondSetSchemaLatencyMillis;
+ }
+
+ /** Returns latency of putting migrated document to Icing lib in milliseconds. */
+ public int getSaveDocumentLatencyMillis() {
+ return mSaveDocumentLatencyMillis;
+ }
+
+ /** Returns number of migrated documents. */
+ public int getMigratedDocumentCount() {
+ return mMigratedDocumentCount;
+ }
+
+ /** Returns number of updated documents which are saved in Icing lib. */
+ public int getSavedDocumentCount() {
+ return mSavedDocumentCount;
+ }
+
+ /** Builder for {@link SchemaMigrationStats}. */
+ public static class Builder {
+ int mGetSchemaLatencyMillis;
+ int mQueryAndTransformLatencyMillis;
+ int mFirstSetSchemaLatencyMillis;
+ int mSecondSetSchemaLatencyMillis;
+ int mSaveDocumentLatencyMillis;
+ int mMigratedDocumentCount;
+ int mSavedDocumentCount;
+
+ /** Sets latency for the GetSchema action in milliseconds. */
+ @NonNull
+ public SchemaMigrationStats.Builder setGetSchemaLatencyMillis(int getSchemaLatencyMillis) {
+ mGetSchemaLatencyMillis = getSchemaLatencyMillis;
+ return this;
+ }
+
+ /**
+ * Sets latency for querying all documents that need to be migrated to new version and
+ * transforming documents to new version in milliseconds.
+ */
+ @NonNull
+ public SchemaMigrationStats.Builder setQueryAndTransformLatencyMillis(
+ int queryAndTransformLatencyMillis) {
+ mQueryAndTransformLatencyMillis = queryAndTransformLatencyMillis;
+ return this;
+ }
+
+ /** Sets latency of first SetSchema action in milliseconds. */
+ @NonNull
+ public SchemaMigrationStats.Builder setFirstSetSchemaLatencyMillis(
+ int firstSetSchemaLatencyMillis) {
+ mFirstSetSchemaLatencyMillis = firstSetSchemaLatencyMillis;
+ return this;
+ }
+
+ /** Sets latency of second SetSchema action in milliseconds. */
+ @NonNull
+ public SchemaMigrationStats.Builder setSecondSetSchemaLatencyMillis(
+ int secondSetSchemaLatencyMillis) {
+ mSecondSetSchemaLatencyMillis = secondSetSchemaLatencyMillis;
+ return this;
+ }
+
+ /** Sets latency for putting migrated document to Icing lib in milliseconds. */
+ @NonNull
+ public SchemaMigrationStats.Builder setSaveDocumentLatencyMillis(
+ int saveDocumentLatencyMillis) {
+ mSaveDocumentLatencyMillis = saveDocumentLatencyMillis;
+ return this;
+ }
+
+ /** Sets number of migrated documents. */
+ @NonNull
+ public SchemaMigrationStats.Builder setMigratedDocumentCount(int migratedDocumentCount) {
+ mMigratedDocumentCount = migratedDocumentCount;
+ return this;
+ }
+
+ /** Sets number of updated documents which are saved in Icing lib. */
+ @NonNull
+ public SchemaMigrationStats.Builder setSavedDocumentCount(int savedDocumentCount) {
+ mSavedDocumentCount = savedDocumentCount;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link SchemaMigrationStats} from the {@link SchemaMigrationStats.Builder}.
+ */
+ @NonNull
+ public SchemaMigrationStats build() {
+ return new SchemaMigrationStats(/* builder= */ this);
+ }
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
index 56a546a2e8e1..9d789a894855 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
@@ -17,6 +17,7 @@
package com.android.server.appsearch.external.localstorage.stats;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.appsearch.AppSearchResult;
import java.util.Objects;
@@ -38,6 +39,12 @@ public final class SetSchemaStats {
*/
@AppSearchResult.ResultCode private final int mStatusCode;
+ /**
+ * Stores stats of SchemaMigration in SetSchema process. Is {@code null} if no schema migration
+ * is needed.
+ */
+ @Nullable private final SchemaMigrationStats mSchemaMigrationStats;
+
private final int mTotalLatencyMillis;
/** Overall time used for the native function call. */
@@ -63,6 +70,7 @@ public final class SetSchemaStats {
mPackageName = builder.mPackageName;
mDatabase = builder.mDatabase;
mStatusCode = builder.mStatusCode;
+ mSchemaMigrationStats = builder.mSchemaMigrationStats;
mTotalLatencyMillis = builder.mTotalLatencyMillis;
mNativeLatencyMillis = builder.mNativeLatencyMillis;
mNewTypeCount = builder.mNewTypeCount;
@@ -90,6 +98,15 @@ public final class SetSchemaStats {
return mStatusCode;
}
+ /**
+ * Returns the status of schema migration, if migration is executed during the SetSchema
+ * process. Otherwise, returns {@code null}.
+ */
+ @Nullable
+ public SchemaMigrationStats getSchemaMigrationStats() {
+ return mSchemaMigrationStats;
+ }
+
/** Returns the total latency of the SetSchema action. */
public int getTotalLatencyMillis() {
return mTotalLatencyMillis;
@@ -140,6 +157,7 @@ public final class SetSchemaStats {
@NonNull final String mPackageName;
@NonNull final String mDatabase;
@AppSearchResult.ResultCode int mStatusCode;
+ @Nullable SchemaMigrationStats mSchemaMigrationStats;
int mTotalLatencyMillis;
int mNativeLatencyMillis;
int mNewTypeCount;
@@ -161,7 +179,14 @@ public final class SetSchemaStats {
return this;
}
- /** Sets total latency for the SetSchema action. */
+ /** Sets the status of schema migration. */
+ @NonNull
+ public Builder setSchemaMigrationStats(@NonNull SchemaMigrationStats schemaMigrationStats) {
+ mSchemaMigrationStats = Objects.requireNonNull(schemaMigrationStats);
+ return this;
+ }
+
+ /** Sets total latency for the SetSchema action in milliseconds. */
@NonNull
public Builder setTotalLatencyMillis(int totalLatencyMillis) {
mTotalLatencyMillis = totalLatencyMillis;
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotDisplayedBySystemMap.java
index 9e36fd02569f..95905af76123 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotPlatformSurfaceableMap.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/NotDisplayedBySystemMap.java
@@ -27,7 +27,7 @@ import java.util.Set;
*
* This object is not thread safe.
*/
-class NotPlatformSurfaceableMap {
+class NotDisplayedBySystemMap {
/**
* Maps packages to databases to the set of prefixed schemas that are platform-hidden within
* that database.
@@ -39,7 +39,7 @@ class NotPlatformSurfaceableMap {
*
* <p>Any existing mappings for this prefix are overwritten.
*/
- public void setNotPlatformSurfaceable(
+ public void setNotDisplayedBySystem(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull Set<String> prefixedSchemas) {
@@ -55,7 +55,7 @@ class NotPlatformSurfaceableMap {
* Returns whether the given prefixed schema is platform surfaceable (has not opted out) in the
* given database.
*/
- public boolean isSchemaPlatformSurfaceable(
+ public boolean isSchemaDisplayedBySystem(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String prefixedSchema) {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java
index 1771b1ddc6b6..b0108704be34 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityDocument.java
@@ -28,10 +28,10 @@ class VisibilityDocument extends GenericDocument {
/**
* Property that holds the list of platform-hidden schemas, as part of the visibility settings.
*/
- private static final String NOT_PLATFORM_SURFACEABLE_PROPERTY = "notPlatformSurfaceable";
+ private static final String NOT_DISPLAYED_BY_SYSTEM_PROPERTY = "notPlatformSurfaceable";
/** Property that holds nested documents of package accessible schemas. */
- private static final String PACKAGE_ACCESSIBLE_PROPERTY = "packageAccessible";
+ private static final String VISIBLE_TO_PACKAGES_PROPERTY = "packageAccessible";
/**
* Schema for the VisibilityStore's documents.
@@ -41,11 +41,11 @@ class VisibilityDocument extends GenericDocument {
*/
public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
- NOT_PLATFORM_SURFACEABLE_PROPERTY)
+ NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
- PACKAGE_ACCESSIBLE_PROPERTY, PackageAccessibleDocument.SCHEMA_TYPE)
+ VISIBLE_TO_PACKAGES_PROPERTY, VisibleToPackagesDocument.SCHEMA_TYPE)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.build();
@@ -55,13 +55,13 @@ class VisibilityDocument extends GenericDocument {
}
@Nullable
- public String[] getNotPlatformSurfaceableSchemas() {
- return getPropertyStringArray(NOT_PLATFORM_SURFACEABLE_PROPERTY);
+ public String[] getNotDisplayedBySystem() {
+ return getPropertyStringArray(NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
}
@Nullable
- public GenericDocument[] getPackageAccessibleSchemas() {
- return getPropertyDocumentArray(PACKAGE_ACCESSIBLE_PROPERTY);
+ public GenericDocument[] getVisibleToPackages() {
+ return getPropertyDocumentArray(VISIBLE_TO_PACKAGES_PROPERTY);
}
/** Builder for {@link VisibilityDocument}. */
@@ -72,17 +72,15 @@ class VisibilityDocument extends GenericDocument {
/** Sets which prefixed schemas have opted out of platform surfacing. */
@NonNull
- public Builder setSchemasNotPlatformSurfaceable(
- @NonNull String[] notPlatformSurfaceableSchemas) {
- return setPropertyString(
- NOT_PLATFORM_SURFACEABLE_PROPERTY, notPlatformSurfaceableSchemas);
+ public Builder setNotDisplayedBySystem(@NonNull String[] notDisplayedBySystemSchemas) {
+ return setPropertyString(NOT_DISPLAYED_BY_SYSTEM_PROPERTY, notDisplayedBySystemSchemas);
}
/** Sets which prefixed schemas have configured package access. */
@NonNull
- public Builder setPackageAccessibleSchemas(
- @NonNull PackageAccessibleDocument[] packageAccessibleSchemas) {
- return setPropertyDocument(PACKAGE_ACCESSIBLE_PROPERTY, packageAccessibleSchemas);
+ public Builder setVisibleToPackages(
+ @NonNull VisibleToPackagesDocument[] visibleToPackagesDocuments) {
+ return setPropertyDocument(VISIBLE_TO_PACKAGES_PROPERTY, visibleToPackagesDocuments);
}
}
}
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 ae1ec56b4ee6..a096aef34c71 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,9 +66,6 @@ import java.util.Set;
* @hide
*/
public class VisibilityStore {
- /** 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;
@@ -92,11 +89,10 @@ public class VisibilityStore {
private final Context mUserContext;
/** Stores the schemas that are platform-hidden. All values are prefixed. */
- private final NotPlatformSurfaceableMap mNotPlatformSurfaceableMap =
- new NotPlatformSurfaceableMap();
+ private final NotDisplayedBySystemMap mNotDisplayedBySystemMap = new NotDisplayedBySystemMap();
- /** Stores the schemas that are package accessible. All values are prefixed. */
- private final PackageAccessibleMap mPackageAccessibleMap = new PackageAccessibleMap();
+ /** Stores the schemas that are visible to 3p packages. All values are prefixed. */
+ private final VisibleToPackagesMap mVisibleToPackagesMap = new VisibleToPackagesMap();
/**
* Creates and initializes VisibilityStore.
@@ -118,28 +114,28 @@ public class VisibilityStore {
GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(PACKAGE_NAME, DATABASE_NAME);
boolean hasVisibilityType = false;
- boolean hasPackageAccessibleType = false;
+ boolean hasVisibleToPackagesType = false;
for (AppSearchSchema schema : getSchemaResponse.getSchemas()) {
if (schema.getSchemaType().equals(VisibilityDocument.SCHEMA_TYPE)) {
hasVisibilityType = true;
- } else if (schema.getSchemaType().equals(PackageAccessibleDocument.SCHEMA_TYPE)) {
- hasPackageAccessibleType = true;
+ } else if (schema.getSchemaType().equals(VisibleToPackagesDocument.SCHEMA_TYPE)) {
+ hasVisibleToPackagesType = true;
}
- if (hasVisibilityType && hasPackageAccessibleType) {
+ if (hasVisibilityType && hasVisibleToPackagesType) {
// Found both our types, can exit early.
break;
}
}
- if (!hasVisibilityType || !hasPackageAccessibleType) {
+ if (!hasVisibilityType || !hasVisibleToPackagesType) {
// Schema type doesn't exist yet. Add it.
mAppSearchImpl.setSchema(
PACKAGE_NAME,
DATABASE_NAME,
- Arrays.asList(VisibilityDocument.SCHEMA, PackageAccessibleDocument.SCHEMA),
+ Arrays.asList(VisibilityDocument.SCHEMA, VisibleToPackagesDocument.SCHEMA),
/*visibilityStore=*/ null, // Avoid recursive calls
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ SCHEMA_VERSION);
}
@@ -177,26 +173,25 @@ public class VisibilityStore {
}
// Update platform visibility settings
- String[] notPlatformSurfaceableSchemas =
- visibilityDocument.getNotPlatformSurfaceableSchemas();
- if (notPlatformSurfaceableSchemas != null) {
- mNotPlatformSurfaceableMap.setNotPlatformSurfaceable(
+ String[] notDisplayedBySystemSchemas = visibilityDocument.getNotDisplayedBySystem();
+ if (notDisplayedBySystemSchemas != null) {
+ mNotDisplayedBySystemMap.setNotDisplayedBySystem(
packageName,
databaseName,
- new ArraySet<>(notPlatformSurfaceableSchemas));
+ new ArraySet<>(notDisplayedBySystemSchemas));
}
// Update 3p package visibility settings
Map<String, Set<PackageIdentifier>> schemaToPackageIdentifierMap = new ArrayMap<>();
- GenericDocument[] packageAccessibleDocuments =
- visibilityDocument.getPackageAccessibleSchemas();
- if (packageAccessibleDocuments != null) {
- for (int i = 0; i < packageAccessibleDocuments.length; i++) {
- PackageAccessibleDocument packageAccessibleDocument =
- new PackageAccessibleDocument(packageAccessibleDocuments[i]);
+ GenericDocument[] visibleToPackagesDocuments =
+ visibilityDocument.getVisibleToPackages();
+ if (visibleToPackagesDocuments != null) {
+ for (int i = 0; i < visibleToPackagesDocuments.length; i++) {
+ VisibleToPackagesDocument visibleToPackagesDocument =
+ new VisibleToPackagesDocument(visibleToPackagesDocuments[i]);
PackageIdentifier packageIdentifier =
- packageAccessibleDocument.getPackageIdentifier();
- String prefixedSchema = packageAccessibleDocument.getAccessibleSchemaType();
+ visibleToPackagesDocument.getPackageIdentifier();
+ String prefixedSchema = visibleToPackagesDocument.getAccessibleSchemaType();
Set<PackageIdentifier> packageIdentifiers =
schemaToPackageIdentifierMap.get(prefixedSchema);
if (packageIdentifiers == null) {
@@ -206,7 +201,7 @@ public class VisibilityStore {
schemaToPackageIdentifierMap.put(prefixedSchema, packageIdentifiers);
}
}
- mPackageAccessibleMap.setPackageAccessible(
+ mVisibleToPackagesMap.setVisibleToPackages(
packageName, databaseName, schemaToPackageIdentifierMap);
}
}
@@ -216,51 +211,51 @@ public class VisibilityStore {
* Sets visibility settings for the given database. Any previous visibility settings will be
* overwritten.
*
- * @param packageName Package of app that owns the {@code schemasNotPlatformSurfaceable}.
- * @param databaseName Database that owns the {@code schemasNotPlatformSurfaceable}.
- * @param schemasNotPlatformSurfaceable Set of prefixed schemas that should be hidden from the
+ * @param packageName Package of app that owns the schemas.
+ * @param databaseName Database that owns the schemas.
+ * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from the
* platform.
- * @param schemasPackageAccessible Map of prefixed schemas to a list of package identifiers that
+ * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
* have access to the schema.
* @throws AppSearchException on AppSearchImpl error.
*/
public void setVisibility(
@NonNull String packageName,
@NonNull String databaseName,
- @NonNull Set<String> schemasNotPlatformSurfaceable,
- @NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible)
+ @NonNull Set<String> schemasNotDisplayedBySystem,
+ @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
throws AppSearchException {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
- Objects.requireNonNull(schemasNotPlatformSurfaceable);
- Objects.requireNonNull(schemasPackageAccessible);
+ Objects.requireNonNull(schemasNotDisplayedBySystem);
+ Objects.requireNonNull(schemasVisibleToPackages);
// Persist the document
VisibilityDocument.Builder visibilityDocument =
new VisibilityDocument.Builder(
NAMESPACE, /*id=*/ getVisibilityDocumentId(packageName, databaseName));
- if (!schemasNotPlatformSurfaceable.isEmpty()) {
- visibilityDocument.setSchemasNotPlatformSurfaceable(
- schemasNotPlatformSurfaceable.toArray(new String[0]));
+ if (!schemasNotDisplayedBySystem.isEmpty()) {
+ visibilityDocument.setNotDisplayedBySystem(
+ schemasNotDisplayedBySystem.toArray(new String[0]));
}
Map<String, Set<PackageIdentifier>> schemaToPackageIdentifierMap = new ArrayMap<>();
- List<PackageAccessibleDocument> packageAccessibleDocuments = new ArrayList<>();
+ List<VisibleToPackagesDocument> visibleToPackagesDocuments = new ArrayList<>();
for (Map.Entry<String, List<PackageIdentifier>> entry :
- schemasPackageAccessible.entrySet()) {
+ schemasVisibleToPackages.entrySet()) {
for (int i = 0; i < entry.getValue().size(); i++) {
- PackageAccessibleDocument packageAccessibleDocument =
- new PackageAccessibleDocument.Builder(NAMESPACE, /*id=*/ "")
+ VisibleToPackagesDocument visibleToPackagesDocument =
+ new VisibleToPackagesDocument.Builder(NAMESPACE, /*id=*/ "")
.setAccessibleSchemaType(entry.getKey())
.setPackageIdentifier(entry.getValue().get(i))
.build();
- packageAccessibleDocuments.add(packageAccessibleDocument);
+ visibleToPackagesDocuments.add(visibleToPackagesDocument);
}
schemaToPackageIdentifierMap.put(entry.getKey(), new ArraySet<>(entry.getValue()));
}
- if (!packageAccessibleDocuments.isEmpty()) {
- visibilityDocument.setPackageAccessibleSchemas(
- packageAccessibleDocuments.toArray(new PackageAccessibleDocument[0]));
+ if (!visibleToPackagesDocuments.isEmpty()) {
+ visibilityDocument.setVisibleToPackages(
+ visibleToPackagesDocuments.toArray(new VisibleToPackagesDocument[0]));
}
mAppSearchImpl.putDocument(
@@ -269,9 +264,9 @@ public class VisibilityStore {
mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
// Update derived data structures.
- mNotPlatformSurfaceableMap.setNotPlatformSurfaceable(
- packageName, databaseName, schemasNotPlatformSurfaceable);
- mPackageAccessibleMap.setPackageAccessible(
+ mNotDisplayedBySystemMap.setNotDisplayedBySystem(
+ packageName, databaseName, schemasNotDisplayedBySystem);
+ mVisibleToPackagesMap.setVisibleToPackages(
packageName, databaseName, schemaToPackageIdentifierMap);
}
@@ -313,13 +308,13 @@ public class VisibilityStore {
}
if (callerHasSystemAccess
- && mNotPlatformSurfaceableMap.isSchemaPlatformSurfaceable(
+ && mNotDisplayedBySystemMap.isSchemaDisplayedBySystem(
packageName, databaseName, prefixedSchema)) {
return true;
}
// May not be platform surfaceable, but might still be accessible through 3p access.
- return isSchemaPackageAccessible(packageName, databaseName, prefixedSchema, callerUid);
+ return isSchemaVisibleToPackages(packageName, databaseName, prefixedSchema, callerUid);
}
/**
@@ -331,13 +326,13 @@ public class VisibilityStore {
* certificate was once used to sign the package, the package will still be granted access. This
* does not handle packages that have been signed by multiple certificates.
*/
- private boolean isSchemaPackageAccessible(
+ private boolean isSchemaVisibleToPackages(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String prefixedSchema,
int callerUid) {
Set<PackageIdentifier> packageIdentifiers =
- mPackageAccessibleMap.getAccessiblePackages(
+ mVisibleToPackagesMap.getAccessiblePackages(
packageName, databaseName, prefixedSchema);
if (packageIdentifiers.isEmpty()) {
return false;
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesDocument.java
index 0b4e196fd0c4..8d503390eaaa 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleDocument.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesDocument.java
@@ -26,7 +26,7 @@ import android.app.appsearch.PackageIdentifier;
*
* @see android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage
*/
-class PackageAccessibleDocument extends GenericDocument {
+class VisibleToPackagesDocument extends GenericDocument {
/** Schema type for nested documents that hold package accessible information. */
public static final String SCHEMA_TYPE = "PackageAccessibleType";
@@ -59,7 +59,7 @@ class PackageAccessibleDocument extends GenericDocument {
.build())
.build();
- public PackageAccessibleDocument(@NonNull GenericDocument genericDocument) {
+ VisibleToPackagesDocument(@NonNull GenericDocument genericDocument) {
super(genericDocument);
}
@@ -76,9 +76,9 @@ class PackageAccessibleDocument extends GenericDocument {
return new PackageIdentifier(packageName, sha256Cert);
}
- /** Builder for {@link PackageAccessibleDocument} instances. */
- public static class Builder extends GenericDocument.Builder<PackageAccessibleDocument.Builder> {
- public Builder(@NonNull String namespace, @NonNull String id) {
+ /** Builder for {@link VisibleToPackagesDocument} instances. */
+ public static class Builder extends GenericDocument.Builder<VisibleToPackagesDocument.Builder> {
+ Builder(@NonNull String namespace, @NonNull String id) {
super(namespace, id, SCHEMA_TYPE);
}
@@ -98,8 +98,8 @@ class PackageAccessibleDocument extends GenericDocument {
@Override
@NonNull
- public PackageAccessibleDocument build() {
- return new PackageAccessibleDocument(super.build());
+ public VisibleToPackagesDocument build() {
+ return new VisibleToPackagesDocument(super.build());
}
}
}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesMap.java
index cff729aa4e8a..e2b51a75025c 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/PackageAccessibleMap.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibleToPackagesMap.java
@@ -29,7 +29,7 @@ import java.util.Set;
*
* This object is not thread safe.
*/
-class PackageAccessibleMap {
+class VisibleToPackagesMap {
/**
* Maps packages to databases to prefixed schemas to PackageIdentifiers that have access to that
* schema.
@@ -42,7 +42,7 @@ class PackageAccessibleMap {
*
* <p>Any existing mappings for this prefix are overwritten.
*/
- public void setPackageAccessible(
+ public void setVisibleToPackages(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull Map<String, Set<PackageIdentifier>> schemaToPackageIdentifier) {
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index 78d39cc6deac..9859f20643b5 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-31a54dba5bda4d0109ea91eb1ac047c937cbaae3
+04351b43fbbf9d59ffeae41903322023931c84f2
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
index d6ce3ebc267f..7b74578adfc7 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
@@ -51,8 +51,6 @@ public interface AppSearchSessionShim extends Closeable {
* @param request the schema to set or update the AppSearch database to.
* @return a {@link ListenableFuture} which resolves to a {@link SetSchemaResponse} object.
*/
- // TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
- // exposed.
@NonNull
ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request);
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 1efe5cb2f53e..4843415fdbdd 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -1285,14 +1285,20 @@ public class AlarmManager {
}
/**
- * Called to check if the caller has the permission
- * {@link Manifest.permission#SCHEDULE_EXACT_ALARM}.
- *
- * Apps can start {@link android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM} to
+ * Called to check if the caller can schedule exact alarms.
+ * <p>
+ * Apps targeting {@link Build.VERSION_CODES#S} or higher can schedule exact alarms if they
+ * have the {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission. These apps can also
+ * start {@link android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM} to
* request this from the user.
+ * <p>
+ * Apps targeting lower sdk versions, can always schedule exact alarms.
*
- * @return {@code true} if the caller has the permission, {@code false} otherwise.
+ * @return {@code true} if the caller can schedule exact alarms.
* @see android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM
+ * @see #setExact(int, long, PendingIntent)
+ * @see #setExactAndAllowWhileIdle(int, long, PendingIntent)
+ * @see #setAlarmClock(AlarmClockInfo, PendingIntent)
*/
public boolean canScheduleExactAlarms() {
return hasScheduleExactAlarm(mContext.getOpPackageName(), mContext.getUserId());
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 0e9efbcc98b8..ac2018707c75 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -442,6 +442,7 @@ public class DeviceIdleController extends SystemService
private long mNextIdlePendingDelay;
private long mNextIdleDelay;
private long mNextLightIdleDelay;
+ private long mNextLightIdleDelayFlex;
private long mNextLightAlarmTime;
private long mNextSensingTimeoutAlarmTime;
@@ -886,16 +887,20 @@ public class DeviceIdleController extends SystemService
*/
public final class Constants implements DeviceConfig.OnPropertiesChangedListener {
// Key names stored in the settings value.
- private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
- = "light_after_inactive_to";
+ private static final String KEY_FLEX_TIME_SHORT = "flex_time_short";
+ private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
+ "light_after_inactive_to";
private static final String KEY_LIGHT_PRE_IDLE_TIMEOUT = "light_pre_idle_to";
private static final String KEY_LIGHT_IDLE_TIMEOUT = "light_idle_to";
+ private static final String KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX =
+ "light_idle_to_initial_flex";
+ private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX = "light_max_idle_to_flex";
private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
- private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
- = "light_idle_maintenance_min_budget";
- private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
- = "light_idle_maintenance_max_budget";
+ private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET =
+ "light_idle_maintenance_min_budget";
+ private static final String KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET =
+ "light_idle_maintenance_max_budget";
private static final String KEY_MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time";
private static final String KEY_MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time";
private static final String KEY_INACTIVE_TIMEOUT = "inactive_to";
@@ -903,6 +908,7 @@ public class DeviceIdleController extends SystemService
private static final String KEY_LOCATING_TIMEOUT = "locating_to";
private static final String KEY_LOCATION_ACCURACY = "location_accuracy";
private static final String KEY_MOTION_INACTIVE_TIMEOUT = "motion_inactive_to";
+ private static final String KEY_MOTION_INACTIVE_TIMEOUT_FLEX = "motion_inactive_to_flex";
private static final String KEY_IDLE_AFTER_INACTIVE_TIMEOUT = "idle_after_inactive_to";
private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
@@ -929,13 +935,20 @@ public class DeviceIdleController extends SystemService
"pre_idle_factor_long";
private static final String KEY_PRE_IDLE_FACTOR_SHORT =
"pre_idle_factor_short";
+ private static final String KEY_USE_WINDOW_ALARMS = "use_window_alarms";
+ private static final long DEFAULT_FLEX_TIME_SHORT =
+ !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
private static final long DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
- !COMPRESS_TIME ? 3 * 60 * 1000L : 15 * 1000L;
+ !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L;
private static final long DEFAULT_LIGHT_PRE_IDLE_TIMEOUT =
!COMPRESS_TIME ? 3 * 60 * 1000L : 30 * 1000L;
private static final long DEFAULT_LIGHT_IDLE_TIMEOUT =
!COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L;
+ private static final long DEFAULT_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX =
+ !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
+ private static final long DEFAULT_LIGHT_MAX_IDLE_TIMEOUT_FLEX =
+ !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
private static final float DEFAULT_LIGHT_IDLE_FACTOR = 2f;
private static final long DEFAULT_LIGHT_MAX_IDLE_TIMEOUT =
!COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
@@ -958,6 +971,8 @@ public class DeviceIdleController extends SystemService
private static final float DEFAULT_LOCATION_ACCURACY = 20f;
private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT =
!COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L;
+ private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX =
+ !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT =
(30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY =
@@ -983,6 +998,14 @@ public class DeviceIdleController extends SystemService
private static final boolean DEFAULT_WAIT_FOR_UNLOCK = true;
private static final float DEFAULT_PRE_IDLE_FACTOR_LONG = 1.67f;
private static final float DEFAULT_PRE_IDLE_FACTOR_SHORT = .33f;
+ private static final boolean DEFAULT_USE_WINDOW_ALARMS = true;
+
+ /**
+ * A somewhat short alarm window size that we will tolerate for various alarm timings.
+ *
+ * @see #KEY_FLEX_TIME_SHORT
+ */
+ public long FLEX_TIME_SHORT = DEFAULT_FLEX_TIME_SHORT;
/**
* This is the time, after becoming inactive, that we go in to the first
@@ -1002,13 +1025,28 @@ public class DeviceIdleController extends SystemService
public long LIGHT_PRE_IDLE_TIMEOUT = DEFAULT_LIGHT_PRE_IDLE_TIMEOUT;
/**
- * This is the initial time that we will run in idle maintenance mode.
+ * This is the initial time that we will run in light idle maintenance mode.
*
* @see #KEY_LIGHT_IDLE_TIMEOUT
*/
public long LIGHT_IDLE_TIMEOUT = DEFAULT_LIGHT_IDLE_TIMEOUT;
/**
+ * This is the initial alarm window size that we will tolerate for light idle maintenance
+ * timing.
+ *
+ * @see #KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX
+ */
+ public long LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = DEFAULT_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX;
+
+ /**
+ * This is the maximum value that {@link #LIGHT_IDLE_TIMEOUT_INITIAL_FLEX} should take.
+ *
+ * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX
+ */
+ public long LIGHT_MAX_IDLE_TIMEOUT_FLEX = DEFAULT_LIGHT_MAX_IDLE_TIMEOUT_FLEX;
+
+ /**
* Scaling factor to apply to the light idle mode time each time we complete a cycle.
*
* @see #KEY_LIGHT_IDLE_FACTOR
@@ -1016,7 +1054,7 @@ public class DeviceIdleController extends SystemService
public float LIGHT_IDLE_FACTOR = DEFAULT_LIGHT_IDLE_FACTOR;
/**
- * This is the maximum time we will run in idle maintenance mode.
+ * This is the maximum time we will stay in light idle mode.
*
* @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
*/
@@ -1099,13 +1137,22 @@ public class DeviceIdleController extends SystemService
/**
* This is the time, after seeing motion, that we wait after becoming inactive from
* that until we start looking for motion again.
+ *
* @see #KEY_MOTION_INACTIVE_TIMEOUT
*/
public long MOTION_INACTIVE_TIMEOUT = DEFAULT_MOTION_INACTIVE_TIMEOUT;
/**
+ * This is the alarm window size we will tolerate for motion detection timings.
+ *
+ * @see #KEY_MOTION_INACTIVE_TIMEOUT_FLEX
+ */
+ public long MOTION_INACTIVE_TIMEOUT_FLEX = DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX;
+
+ /**
* This is the time, after the inactive timeout elapses, that we will wait looking
* for motion until we truly consider the device to be idle.
+ *
* @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
*/
public long IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT;
@@ -1204,6 +1251,12 @@ public class DeviceIdleController extends SystemService
public boolean WAIT_FOR_UNLOCK = DEFAULT_WAIT_FOR_UNLOCK;
+ /**
+ * Whether to use window alarms. True to use window alarms (call AlarmManager.setWindow()).
+ * False to use the legacy inexact alarms (call AlarmManager.set()).
+ */
+ public boolean USE_WINDOW_ALARMS = DEFAULT_USE_WINDOW_ALARMS;
+
private final boolean mSmallBatteryDevice;
public Constants() {
@@ -1227,6 +1280,10 @@ public class DeviceIdleController extends SystemService
continue;
}
switch (name) {
+ case KEY_FLEX_TIME_SHORT:
+ FLEX_TIME_SHORT = properties.getLong(
+ KEY_FLEX_TIME_SHORT, DEFAULT_FLEX_TIME_SHORT);
+ break;
case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT:
LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
@@ -1240,9 +1297,19 @@ public class DeviceIdleController extends SystemService
LIGHT_IDLE_TIMEOUT = properties.getLong(
KEY_LIGHT_IDLE_TIMEOUT, DEFAULT_LIGHT_IDLE_TIMEOUT);
break;
+ case KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX:
+ LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = properties.getLong(
+ KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX,
+ DEFAULT_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX);
+ break;
+ case KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX:
+ LIGHT_MAX_IDLE_TIMEOUT_FLEX = properties.getLong(
+ KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX,
+ DEFAULT_LIGHT_MAX_IDLE_TIMEOUT_FLEX);
+ break;
case KEY_LIGHT_IDLE_FACTOR:
- LIGHT_IDLE_FACTOR = properties.getFloat(
- KEY_LIGHT_IDLE_FACTOR, DEFAULT_LIGHT_IDLE_FACTOR);
+ LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat(
+ KEY_LIGHT_IDLE_FACTOR, DEFAULT_LIGHT_IDLE_FACTOR));
break;
case KEY_LIGHT_MAX_IDLE_TIMEOUT:
LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
@@ -1291,6 +1358,11 @@ public class DeviceIdleController extends SystemService
MOTION_INACTIVE_TIMEOUT = properties.getLong(
KEY_MOTION_INACTIVE_TIMEOUT, DEFAULT_MOTION_INACTIVE_TIMEOUT);
break;
+ case KEY_MOTION_INACTIVE_TIMEOUT_FLEX:
+ MOTION_INACTIVE_TIMEOUT_FLEX = properties.getLong(
+ KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
+ DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX);
+ break;
case KEY_IDLE_AFTER_INACTIVE_TIMEOUT:
final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
@@ -1362,6 +1434,10 @@ public class DeviceIdleController extends SystemService
PRE_IDLE_FACTOR_SHORT = properties.getFloat(
KEY_PRE_IDLE_FACTOR_SHORT, DEFAULT_PRE_IDLE_FACTOR_SHORT);
break;
+ case KEY_USE_WINDOW_ALARMS:
+ USE_WINDOW_ALARMS = properties.getBoolean(
+ KEY_USE_WINDOW_ALARMS, DEFAULT_USE_WINDOW_ALARMS);
+ break;
default:
Slog.e(TAG, "Unknown configuration key: " + name);
break;
@@ -1373,6 +1449,10 @@ public class DeviceIdleController extends SystemService
void dump(PrintWriter pw) {
pw.println(" Settings:");
+ pw.print(" "); pw.print(KEY_FLEX_TIME_SHORT); pw.print("=");
+ TimeUtils.formatDuration(FLEX_TIME_SHORT, pw);
+ pw.println();
+
pw.print(" ");
pw.print(KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
pw.print("=");
@@ -1387,6 +1467,14 @@ public class DeviceIdleController extends SystemService
TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT, pw);
pw.println();
+ pw.print(" "); pw.print(KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX); pw.print("=");
+ TimeUtils.formatDuration(LIGHT_IDLE_TIMEOUT_INITIAL_FLEX, pw);
+ pw.println();
+
+ pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT_FLEX); pw.print("=");
+ TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT_FLEX, pw);
+ pw.println();
+
pw.print(" "); pw.print(KEY_LIGHT_IDLE_FACTOR); pw.print("=");
pw.print(LIGHT_IDLE_FACTOR);
pw.println();
@@ -1431,6 +1519,10 @@ public class DeviceIdleController extends SystemService
TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw);
pw.println();
+ pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT_FLEX); pw.print("=");
+ TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT_FLEX, pw);
+ pw.println();
+
pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("=");
TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw);
pw.println();
@@ -1489,6 +1581,9 @@ public class DeviceIdleController extends SystemService
pw.print(" "); pw.print(KEY_PRE_IDLE_FACTOR_SHORT); pw.print("=");
pw.println(PRE_IDLE_FACTOR_SHORT);
+
+ pw.print(" "); pw.print(KEY_USE_WINDOW_ALARMS); pw.print("=");
+ pw.println(USE_WINDOW_ALARMS);
}
}
@@ -3199,7 +3294,8 @@ public class DeviceIdleController extends SystemService
mLightState = LIGHT_STATE_INACTIVE;
if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
resetLightIdleManagementLocked();
- scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
+ scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
+ mConstants.FLEX_TIME_SHORT);
EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
}
}
@@ -3219,6 +3315,7 @@ public class DeviceIdleController extends SystemService
private void resetLightIdleManagementLocked() {
mNextLightIdleDelay = 0;
+ mNextLightIdleDelayFlex = 0;
mCurLightIdleBudget = 0;
cancelLightAlarmLocked();
}
@@ -3265,13 +3362,15 @@ public class DeviceIdleController extends SystemService
mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
// Reset the upcoming idle delays.
mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
+ mNextLightIdleDelayFlex = mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX;
mMaintenanceStartTime = 0;
if (!isOpsInactiveLocked()) {
// We have some active ops going on... give them a chance to finish
// before going in to our first idle.
mLightState = LIGHT_STATE_PRE_IDLE;
EventLogTags.writeDeviceIdleLight(mLightState, reason);
- scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT);
+ scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT,
+ mConstants.FLEX_TIME_SHORT);
break;
}
// Nothing active, fall through to immediately idle.
@@ -3290,12 +3389,11 @@ public class DeviceIdleController extends SystemService
}
}
mMaintenanceStartTime = 0;
- scheduleLightAlarmLocked(mNextLightIdleDelay);
+ scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex);
mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
- (long)(mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
- if (mNextLightIdleDelay < mConstants.LIGHT_IDLE_TIMEOUT) {
- mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
- }
+ (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
+ mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT_FLEX,
+ (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR));
if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
mLightState = LIGHT_STATE_IDLE;
EventLogTags.writeDeviceIdleLight(mLightState, reason);
@@ -3315,7 +3413,7 @@ public class DeviceIdleController extends SystemService
} else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
}
- scheduleLightAlarmLocked(mCurLightIdleBudget);
+ scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT);
if (DEBUG) Slog.d(TAG,
"Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
@@ -3326,7 +3424,7 @@ public class DeviceIdleController extends SystemService
// We'd like to do maintenance, but currently don't have network
// connectivity... let's try to wait until the network comes back.
// We'll only wait for another full idle period, however, and then give up.
- scheduleLightAlarmLocked(mNextLightIdleDelay);
+ scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex / 2);
if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
EventLogTags.writeDeviceIdleLight(mLightState, reason);
@@ -3844,40 +3942,75 @@ public class DeviceIdleController extends SystemService
mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
} else {
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
+ if (mConstants.USE_WINDOW_ALARMS) {
+ mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ mConstants.FLEX_TIME_SHORT,
+ mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
+ } else {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
+ }
}
}
- void scheduleLightAlarmLocked(long delay) {
- if (DEBUG) Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + ")");
+ void scheduleLightAlarmLocked(long delay, long flex) {
+ if (DEBUG) {
+ Slog.d(TAG, "scheduleLightAlarmLocked(" + delay
+ + (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "") + ")");
+ }
mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
+ if (mConstants.USE_WINDOW_ALARMS) {
+ mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, flex,
+ "DeviceIdleController.light", mLightAlarmListener, mHandler);
+ } else {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime,
+ "DeviceIdleController.light", mLightAlarmListener, mHandler);
+ }
}
private void scheduleMotionRegistrationAlarmLocked() {
if (DEBUG) Slog.d(TAG, "scheduleMotionRegistrationAlarmLocked");
long nextMotionRegistrationAlarmTime =
mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT / 2;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionRegistrationAlarmTime,
- "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
- mHandler);
+ if (mConstants.USE_WINDOW_ALARMS) {
+ mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ nextMotionRegistrationAlarmTime, mConstants.MOTION_INACTIVE_TIMEOUT_FLEX,
+ "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
+ mHandler);
+ } else {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionRegistrationAlarmTime,
+ "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
+ mHandler);
+ }
}
private void scheduleMotionTimeoutAlarmLocked() {
if (DEBUG) Slog.d(TAG, "scheduleMotionAlarmLocked");
long nextMotionTimeoutAlarmTime =
mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionTimeoutAlarmTime,
- "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler);
+ if (mConstants.USE_WINDOW_ALARMS) {
+ mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ nextMotionTimeoutAlarmTime,
+ mConstants.MOTION_INACTIVE_TIMEOUT_FLEX,
+ "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler);
+ } else {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionTimeoutAlarmTime,
+ "DeviceIdleController.motion", mMotionTimeoutAlarmListener, mHandler);
+ }
}
void scheduleSensingTimeoutAlarmLocked(long delay) {
if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")");
mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
- "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
+ if (mConstants.USE_WINDOW_ALARMS) {
+ mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ mNextSensingTimeoutAlarmTime,
+ mConstants.FLEX_TIME_SHORT,
+ "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
+ } else {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime,
+ "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler);
+ }
}
private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps,
@@ -4852,7 +4985,13 @@ public class DeviceIdleController extends SystemService
if (mNextLightIdleDelay != 0) {
pw.print(" mNextIdleDelay=");
TimeUtils.formatDuration(mNextLightIdleDelay, pw);
- pw.println();
+ if (mConstants.USE_WINDOW_ALARMS) {
+ pw.print(" (flex=");
+ TimeUtils.formatDuration(mNextLightIdleDelayFlex, pw);
+ pw.println(")");
+ } else {
+ pw.println();
+ }
}
if (mNextLightAlarmTime != 0) {
pw.print(" mNextLightAlarmTime=");
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 fb5129f18417..70e548d4c547 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2572,6 +2572,9 @@ public class AlarmManagerService extends SystemService {
throw new SecurityException("Uid " + callingUid
+ " cannot query hasScheduleExactAlarm for uid " + uid);
}
+ if (!isExactAlarmChangeEnabled(packageName, userId)) {
+ return true;
+ }
return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index 37b3c0431455..d532e20a0158 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -20,6 +20,7 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
import static android.app.usage.UsageStatsManager.REASON_MAIN_MASK;
import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_MASK;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION;
@@ -259,8 +260,10 @@ public class AppIdleHistory {
int bucketingReason = REASON_MAIN_USAGE | usageReason;
final boolean isUserUsage = isUserUsage(bucketingReason);
- if (appUsageHistory.currentBucket == STANDBY_BUCKET_RESTRICTED && !isUserUsage) {
- // Only user usage should bring an app out of the RESTRICTED bucket.
+ if (appUsageHistory.currentBucket == STANDBY_BUCKET_RESTRICTED && !isUserUsage
+ && (appUsageHistory.bucketingReason & REASON_MAIN_MASK) != REASON_MAIN_TIMEOUT) {
+ // Only user usage should bring an app out of the RESTRICTED bucket, unless the app
+ // just timed out into RESTRICTED.
newBucket = STANDBY_BUCKET_RESTRICTED;
bucketingReason = appUsageHistory.bucketingReason;
} else {
diff --git a/api/Android.bp b/api/Android.bp
index a84e6a6cb031..2ea180ebf598 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -24,6 +24,41 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
+python_binary_host {
+ name: "api_versions_trimmer",
+ srcs: ["api_versions_trimmer.py"],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: false,
+ },
+ },
+}
+
+python_test_host {
+ name: "api_versions_trimmer_unittests",
+ main: "api_versions_trimmer_unittests.py",
+ srcs: [
+ "api_versions_trimmer_unittests.py",
+ "api_versions_trimmer.py",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: false,
+ },
+ },
+}
+
metalava_cmd = "$(location metalava)"
// Silence reflection warnings. See b/168689341
metalava_cmd += " -J--add-opens=java.base/java.util=ALL-UNNAMED "
@@ -431,3 +466,41 @@ genrule {
},
],
}
+
+// This rule will filter classes present in the jar files of mainline modules
+// from the lint database in api-versions.xml.
+// This is done to reduce the number of false positive NewApi findings in
+// java libraries that compile against the module SDK
+genrule {
+ name: "api-versions-xml-public-filtered",
+ srcs: [
+ // Note: order matters: first parameter is the full api-versions.xml
+ // after that the stubs files in any order
+ // stubs files are all modules that export API surfaces EXCEPT ART
+ ":framework-doc-stubs{.api_versions.xml}",
+ ":android.net.ipsec.ike.stubs{.jar}",
+ ":conscrypt.module.public.api.stubs{.jar}",
+ ":framework-appsearch.stubs{.jar}",
+ ":framework-connectivity.stubs{.jar}",
+ ":framework-graphics.stubs{.jar}",
+ ":framework-media.stubs{.jar}",
+ ":framework-mediaprovider.stubs{.jar}",
+ ":framework-permission.stubs{.jar}",
+ ":framework-permission-s.stubs{.jar}",
+ ":framework-scheduling.stubs{.jar}",
+ ":framework-sdkextensions.stubs{.jar}",
+ ":framework-statsd.stubs{.jar}",
+ ":framework-tethering.stubs{.jar}",
+ ":framework-wifi.stubs{.jar}",
+ ":i18n.module.public.api.stubs{.jar}",
+ ],
+ out: ["api-versions-public-filtered.xml"],
+ tools: ["api_versions_trimmer"],
+ cmd: "$(location api_versions_trimmer) $(out) $(in)",
+ dist: {
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
+ },
+}
diff --git a/api/OWNERS b/api/OWNERS
index 88d0b61a2ab6..a0272709ffc0 100644
--- a/api/OWNERS
+++ b/api/OWNERS
@@ -1 +1,6 @@
+hansson@google.com
+
+# Modularization team
+file:platform/packages/modules/common:/OWNERS
+
per-file Android.bp = file:platform/build/soong:/OWNERS
diff --git a/api/api_versions_trimmer.py b/api/api_versions_trimmer.py
new file mode 100755
index 000000000000..9afd95a3003a
--- /dev/null
+++ b/api/api_versions_trimmer.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Script to remove mainline APIs from the api-versions.xml."""
+
+import argparse
+import re
+import xml.etree.ElementTree as ET
+import zipfile
+
+
+def read_classes(stubs):
+ """Read classes from the stubs file.
+
+ Args:
+ stubs: argument can be a path to a file (a string), a file-like object or a
+ path-like object
+
+ Returns:
+ a set of the classes found in the file (set of strings)
+ """
+ classes = set()
+ with zipfile.ZipFile(stubs) as z:
+ for info in z.infolist():
+ if (not info.is_dir()
+ and info.filename.endswith(".class")
+ and not info.filename.startswith("META-INF")):
+ # drop ".class" extension
+ classes.add(info.filename[:-6])
+ return classes
+
+
+def filter_method_tag(method, classes_to_remove):
+ """Updates the signature of this method by calling filter_method_signature.
+
+ Updates the method passed into this function.
+
+ Args:
+ method: xml element that represents a method
+ classes_to_remove: set of classes you to remove
+ """
+ filtered = filter_method_signature(method.get("name"), classes_to_remove)
+ method.set("name", filtered)
+
+
+def filter_method_signature(signature, classes_to_remove):
+ """Removes mentions of certain classes from this method signature.
+
+ Replaces any existing classes that need to be removed, with java/lang/Object
+
+ Args:
+ signature: string that is a java representation of a method signature
+ classes_to_remove: set of classes you to remove
+ """
+ regex = re.compile("L.*?;")
+ start = signature.find("(")
+ matches = set(regex.findall(signature[start:]))
+ for m in matches:
+ # m[1:-1] to drop the leading `L` and `;` ending
+ if m[1:-1] in classes_to_remove:
+ signature = signature.replace(m, "Ljava/lang/Object;")
+ return signature
+
+
+def filter_lint_database(database, classes_to_remove, output):
+ """Reads a lint database and writes a filtered version without some classes.
+
+ Reads database from api-versions.xml and removes any references to classes
+ in the second argument. Writes the result (another xml with the same format
+ of the database) to output.
+
+ Args:
+ database: path to xml with lint database to read
+ classes_to_remove: iterable (ideally a set or similar for quick
+ lookups) that enumerates the classes that should be removed
+ output: path to write the filtered database
+ """
+ xml = ET.parse(database)
+ root = xml.getroot()
+ for c in xml.findall("class"):
+ cname = c.get("name")
+ if cname in classes_to_remove:
+ root.remove(c)
+ else:
+ # find the <extends /> tag inside this class to see if the parent
+ # has been removed from the known classes (attribute called name)
+ super_classes = c.findall("extends")
+ for super_class in super_classes:
+ super_class_name = super_class.get("name")
+ if super_class_name in classes_to_remove:
+ super_class.set("name", "java/lang/Object")
+ interfaces = c.findall("implements")
+ for interface in interfaces:
+ interface_name = interface.get("name")
+ if interface_name in classes_to_remove:
+ c.remove(interface)
+ for method in c.findall("method"):
+ filter_method_tag(method, classes_to_remove)
+ xml.write(output)
+
+
+def main():
+ """Run the program."""
+ parser = argparse.ArgumentParser(
+ description=
+ ("Read a lint database (api-versions.xml) and many stubs jar files. "
+ "Produce another database file that doesn't include the classes present "
+ "in the stubs file(s)."))
+ parser.add_argument("output", help="Destination of the result (xml file).")
+ parser.add_argument(
+ "api_versions",
+ help="The lint database (api-versions.xml file) to read data from"
+ )
+ parser.add_argument("stubs", nargs="+", help="The stubs jar file(s)")
+ parsed = parser.parse_args()
+ classes = set()
+ for stub in parsed.stubs:
+ classes.update(read_classes(stub))
+ filter_lint_database(parsed.api_versions, classes, parsed.output)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/api/api_versions_trimmer_unittests.py b/api/api_versions_trimmer_unittests.py
new file mode 100644
index 000000000000..4eb929ea1b5d
--- /dev/null
+++ b/api/api_versions_trimmer_unittests.py
@@ -0,0 +1,307 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+import io
+import re
+import unittest
+import xml.etree.ElementTree as ET
+import zipfile
+
+import api_versions_trimmer
+
+
+def create_in_memory_zip_file(files):
+ f = io.BytesIO()
+ with zipfile.ZipFile(f, "w") as z:
+ for fname in files:
+ with z.open(fname, mode="w") as class_file:
+ class_file.write(b"")
+ return f
+
+
+def indent(elem, level=0):
+ i = "\n" + level * " "
+ j = "\n" + (level - 1) * " "
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + " "
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for subelem in elem:
+ indent(subelem, level + 1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = j
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = j
+ return elem
+
+
+def pretty_print(s):
+ tree = ET.parse(io.StringIO(s))
+ el = indent(tree.getroot())
+ res = ET.tostring(el).decode("utf-8")
+ # remove empty lines inside the result because this still breaks some
+ # comparisons
+ return re.sub(r"\n\s*\n", "\n", res, re.MULTILINE)
+
+
+class ApiVersionsTrimmerUnittests(unittest.TestCase):
+
+ def setUp(self):
+ # so it prints diffs in long strings (xml files)
+ self.maxDiff = None
+
+ def test_read_classes(self):
+ f = create_in_memory_zip_file(
+ ["a/b/C.class",
+ "a/b/D.class",
+ ]
+ )
+ res = api_versions_trimmer.read_classes(f)
+ self.assertEqual({"a/b/C", "a/b/D"}, res)
+
+ def test_read_classes_ignore_dex(self):
+ f = create_in_memory_zip_file(
+ ["a/b/C.class",
+ "a/b/D.class",
+ "a/b/E.dex",
+ "f.dex",
+ ]
+ )
+ res = api_versions_trimmer.read_classes(f)
+ self.assertEqual({"a/b/C", "a/b/D"}, res)
+
+ def test_read_classes_ignore_manifest(self):
+ f = create_in_memory_zip_file(
+ ["a/b/C.class",
+ "a/b/D.class",
+ "META-INFO/G.class"
+ ]
+ )
+ res = api_versions_trimmer.read_classes(f)
+ self.assertEqual({"a/b/C", "a/b/D"}, res)
+
+ def test_filter_method_signature(self):
+ xml = """
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
+ """
+ method = ET.fromstring(xml)
+ classes_to_remove = {"android/accessibilityservice/GestureDescription"}
+ expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
+ api_versions_trimmer.filter_method_tag(method, classes_to_remove)
+ self.assertEqual(expected, method.get("name"))
+
+ def test_filter_method_signature_with_L_in_method(self):
+ xml = """
+ <method name="dispatchLeftGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
+ """
+ method = ET.fromstring(xml)
+ classes_to_remove = {"android/accessibilityservice/GestureDescription"}
+ expected = "dispatchLeftGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
+ api_versions_trimmer.filter_method_tag(method, classes_to_remove)
+ self.assertEqual(expected, method.get("name"))
+
+ def test_filter_method_signature_with_L_in_class(self):
+ xml = """
+ <method name="dispatchGesture(Landroid/accessibilityservice/LeftGestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
+ """
+ method = ET.fromstring(xml)
+ classes_to_remove = {"android/accessibilityservice/LeftGestureDescription"}
+ expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
+ api_versions_trimmer.filter_method_tag(method, classes_to_remove)
+ self.assertEqual(expected, method.get("name"))
+
+ def test_filter_method_signature_with_inner_class(self):
+ xml = """
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription$Inner;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
+ """
+ method = ET.fromstring(xml)
+ classes_to_remove = {"android/accessibilityservice/GestureDescription$Inner"}
+ expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
+ api_versions_trimmer.filter_method_tag(method, classes_to_remove)
+ self.assertEqual(expected, method.get("name"))
+
+ def _run_filter_db_test(self, database_str, expected):
+ """Performs the pattern of testing the filter_lint_database method.
+
+ Filters instances of the class "a/b/C" (hard-coded) from the database string
+ and compares the result with the expected result (performs formatting of
+ the xml of both inputs)
+
+ Args:
+ database_str: string, the contents of the lint database (api-versions.xml)
+ expected: string, the expected result after filtering the original
+ database
+ """
+ database = io.StringIO(database_str)
+ classes_to_remove = {"a/b/C"}
+ output = io.BytesIO()
+ api_versions_trimmer.filter_lint_database(
+ database,
+ classes_to_remove,
+ output
+ )
+ expected = pretty_print(expected)
+ res = pretty_print(output.getvalue().decode("utf-8"))
+ self.assertEqual(expected, res)
+
+ def test_filter_lint_database_updates_method_signature_params(self):
+ self._run_filter_db_test(
+ database_str="""
+ <api version="2">
+ <!-- will be removed -->
+ <class name="a/b/C" since="1">
+ <extends name="java/lang/Object"/>
+ </class>
+
+ <class name="a/b/E" since="1">
+ <!-- extends will be modified -->
+ <extends name="a/b/C"/>
+ <!-- first parameter will be modified -->
+ <method name="dispatchGesture(La/b/C;Landroid/os/Handler;)Z" since="24"/>
+ <!-- second should remain untouched -->
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """,
+ expected="""
+ <api version="2">
+ <class name="a/b/E" since="1">
+ <extends name="java/lang/Object"/>
+ <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """)
+
+ def test_filter_lint_database_updates_method_signature_return(self):
+ self._run_filter_db_test(
+ database_str="""
+ <api version="2">
+ <!-- will be removed -->
+ <class name="a/b/C" since="1">
+ <extends name="java/lang/Object"/>
+ </class>
+
+ <class name="a/b/E" since="1">
+ <!-- extends will be modified -->
+ <extends name="a/b/C"/>
+ <!-- return type should be changed -->
+ <method name="gestureIdToString(I)La/b/C;" since="24"/>
+ </class>
+ </api>
+ """,
+ expected="""
+ <api version="2">
+ <class name="a/b/E" since="1">
+
+ <extends name="java/lang/Object"/>
+
+ <method name="gestureIdToString(I)Ljava/lang/Object;" since="24"/>
+ </class>
+ </api>
+ """)
+
+ def test_filter_lint_database_removes_implements(self):
+ self._run_filter_db_test(
+ database_str="""
+ <api version="2">
+ <!-- will be removed -->
+ <class name="a/b/C" since="1">
+ <extends name="java/lang/Object"/>
+ </class>
+
+ <class name="a/b/D" since="1">
+ <extends name="java/lang/Object"/>
+ <implements name="a/b/C"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """,
+ expected="""
+ <api version="2">
+
+ <class name="a/b/D" since="1">
+ <extends name="java/lang/Object"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """)
+
+ def test_filter_lint_database_updates_extends(self):
+ self._run_filter_db_test(
+ database_str="""
+ <api version="2">
+ <!-- will be removed -->
+ <class name="a/b/C" since="1">
+ <extends name="java/lang/Object"/>
+ </class>
+
+ <class name="a/b/E" since="1">
+ <!-- extends will be modified -->
+ <extends name="a/b/C"/>
+ <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """,
+ expected="""
+ <api version="2">
+ <class name="a/b/E" since="1">
+ <extends name="java/lang/Object"/>
+ <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """)
+
+ def test_filter_lint_database_removes_class(self):
+ self._run_filter_db_test(
+ database_str="""
+ <api version="2">
+ <!-- will be removed -->
+ <class name="a/b/C" since="1">
+ <extends name="java/lang/Object"/>
+ </class>
+
+ <class name="a/b/D" since="1">
+ <extends name="java/lang/Object"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """,
+ expected="""
+ <api version="2">
+
+ <class name="a/b/D" since="1">
+ <extends name="java/lang/Object"/>
+ <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
+sultCallback;Landroid/os/Handler;)Z" since="24"/>
+ </class>
+ </api>
+ """)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 02ab3143eed9..034ad8e83fd3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -447,7 +447,7 @@ public final class ActivityThread extends ClientTransactionHandler
@GuardedBy("mLock")
ContentProviderHolder mHolder; // Temp holder to be used between notifier and waiter
- Object mLock; // The lock to be used to get notified when the provider is ready
+ final Object mLock; // The lock to be used to get notified when the provider is ready
public ProviderKey(String authority, int userId) {
this.authority = authority;
@@ -1827,11 +1827,14 @@ public final class ActivityThread extends ClientTransactionHandler
@Override
public void notifyContentProviderPublishStatus(@NonNull ContentProviderHolder holder,
- @NonNull String auth, int userId, boolean published) {
- final ProviderKey key = getGetProviderKey(auth, userId);
- synchronized (key.mLock) {
- key.mHolder = holder;
- key.mLock.notifyAll();
+ @NonNull String authorities, int userId, boolean published) {
+ final String auths[] = authorities.split(";");
+ for (String auth: auths) {
+ final ProviderKey key = getGetProviderKey(auth, userId);
+ synchronized (key.mLock) {
+ key.mHolder = holder;
+ key.mLock.notifyAll();
+ }
}
}
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 4555c1725a56..d6ff6d3dfc3a 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -153,7 +153,7 @@ oneway interface IApplicationThread {
void performDirectAction(IBinder activityToken, String actionId,
in Bundle arguments, in RemoteCallback cancellationCallback,
in RemoteCallback resultCallback);
- void notifyContentProviderPublishStatus(in ContentProviderHolder holder, String auth,
+ void notifyContentProviderPublishStatus(in ContentProviderHolder holder, String authorities,
int userId, boolean published);
void instrumentWithoutRestart(in ComponentName instrumentationName,
in Bundle instrumentationArgs,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ba0bc555eb57..506dfe09f3fa 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5606,14 +5606,24 @@ public class Notification implements Parcelable
final boolean snoozeEnabled = !hideSnoozeButton
&& mContext.getContentResolver() != null
- && (Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1);
+ && isSnoozeSettingEnabled();
if (snoozeEnabled) {
big.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
RemoteViews.MARGIN_BOTTOM, 0);
}
}
+ private boolean isSnoozeSettingEnabled() {
+ try {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1;
+ } catch (SecurityException ex) {
+ // Most 3p apps can't access this snooze setting, so their NotificationListeners
+ // would be unable to create notification views if we propagated this exception.
+ return false;
+ }
+ }
+
/**
* Returns the actions that are not contextual.
*/
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 04a12afb8039..6ca7dfbe2284 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -34,6 +34,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
@@ -260,12 +261,19 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
private static final HashMap<String, Integer> sCorks = new HashMap<>();
/**
+ * A map of cache keys that have been disabled in the local process. When a key is
+ * disabled locally, existing caches are disabled and the key is saved in this map.
+ * Future cache instances that use the same key will be disabled in their constructor.
+ */
+ @GuardedBy("sCorkLock")
+ private static final HashSet<String> sDisabledKeys = new HashSet<>();
+
+ /**
* Weakly references all cache objects in the current process, allowing us to iterate over
* them all for purposes like issuing debug dumps and reacting to memory pressure.
*/
@GuardedBy("sCorkLock")
- private static final WeakHashMap<PropertyInvalidatedCache, Void> sCaches =
- new WeakHashMap<>();
+ private static final WeakHashMap<PropertyInvalidatedCache, Void> sCaches = new WeakHashMap<>();
private final Object mLock = new Object();
@@ -348,6 +356,9 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
};
synchronized (sCorkLock) {
sCaches.put(this, null);
+ if (sDisabledKeys.contains(mCacheName)) {
+ disableInstance();
+ }
}
}
@@ -372,6 +383,14 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
protected abstract Result recompute(Query query);
/**
+ * Return true if the query should bypass the cache. The default behavior is to
+ * always use the cache but the method can be overridden for a specific class.
+ */
+ protected boolean bypass(Query query) {
+ return false;
+ }
+
+ /**
* Determines if a pair of responses are considered equal. Used to determine whether
* a cache is inadvertently returning stale results when VERIFY is set to true.
*/
@@ -414,7 +433,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
/**
* Disable the use of this cache in this process.
*/
- public final void disableLocal() {
+ public final void disableInstance() {
synchronized (mLock) {
mDisabled = true;
clear();
@@ -422,6 +441,30 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
}
/**
+ * Disable the local use of all caches with the same name. All currently registered caches
+ * using the key will be disabled now, and all future cache instances that use the key will be
+ * disabled in their constructor.
+ */
+ public static final void disableLocal(@NonNull String name) {
+ synchronized (sCorkLock) {
+ sDisabledKeys.add(name);
+ for (PropertyInvalidatedCache cache : sCaches.keySet()) {
+ if (name.equals(cache.mCacheName)) {
+ cache.disableInstance();
+ }
+ }
+ }
+ }
+
+ /**
+ * Disable this cache in the current process, and all other caches that use the same
+ * property.
+ */
+ public final void disableLocal() {
+ disableLocal(mCacheName);
+ }
+
+ /**
* Return whether the cache is disabled in this process.
*/
public final boolean isDisabledLocal() {
@@ -435,8 +478,8 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
// Let access to mDisabled race: it's atomic anyway.
long currentNonce = (!isDisabledLocal()) ? getCurrentNonce() : NONCE_DISABLED;
for (;;) {
- if (currentNonce == NONCE_DISABLED || currentNonce == NONCE_UNSET ||
- currentNonce == NONCE_CORKED) {
+ if (currentNonce == NONCE_DISABLED || currentNonce == NONCE_UNSET
+ || currentNonce == NONCE_CORKED || bypass(query)) {
if (!mDisabled) {
// Do not bother collecting statistics if the cache is
// locally disabled.
@@ -875,6 +918,15 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
}
/**
+ * Report the disabled status of this cache instance. The return value does not
+ * reflect status of the property key.
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public boolean getDisabledState() {
+ return isDisabledLocal();
+ }
+
+ /**
* Returns a list of caches alive at the current time.
*/
public static ArrayList<PropertyInvalidatedCache> getActiveCaches() {
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 0ab3f2f4be46..7cb1d89aa954 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -697,6 +697,18 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
* service element of manifest file. The value of attribute
* {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.</p>
*
+ * <div class="caution">
+ * <p><strong>Note:</strong>
+ * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#S},
+ * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S}
+ * or higher are not allowed to start foreground services from the background.
+ * See
+ * <a href="{@docRoot}/about/versions/12/behavior-changes-12">
+ * Behavior changes: Apps targeting Android 12
+ * </a>
+ * for more details.
+ * </div>
+ *
* @throws ForegroundServiceStartNotAllowedException
* If the app targeting API is
* {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from
@@ -733,6 +745,18 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
* {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST} to use all flags that
* is specified in manifest attribute foregroundServiceType.</p>
*
+ * <div class="caution">
+ * <p><strong>Note:</strong>
+ * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#S},
+ * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S}
+ * or higher are not allowed to start foreground services from the background.
+ * See
+ * <a href="{@docRoot}/about/versions/12/behavior-changes-12">
+ * Behavior changes: Apps targeting Android 12
+ * </a>
+ * for more details.
+ * </div>
+ *
* @param id The identifier for this notification as per
* {@link NotificationManager#notify(int, Notification)
* NotificationManager.notify(int, Notification)}; must not be 0.
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index cd82deb13e9b..2777a7aae517 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -111,12 +111,15 @@ public final class WallpaperColors implements Parcelable {
public WallpaperColors(Parcel parcel) {
mMainColors = new ArrayList<>();
mAllColors = new HashMap<>();
- final int count = parcel.readInt();
+ int count = parcel.readInt();
for (int i = 0; i < count; i++) {
final int colorInt = parcel.readInt();
Color color = Color.valueOf(colorInt);
mMainColors.add(color);
-
+ }
+ count = parcel.readInt();
+ for (int i = 0; i < count; i++) {
+ final int colorInt = parcel.readInt();
final int population = parcel.readInt();
mAllColors.put(colorInt, population);
}
@@ -411,9 +414,16 @@ public final class WallpaperColors implements Parcelable {
for (int i = 0; i < count; i++) {
Color color = mainColors.get(i);
dest.writeInt(color.toArgb());
- Integer population = mAllColors.get(color.toArgb());
- int populationInt = (population != null) ? population : 0;
- dest.writeInt(populationInt);
+ }
+ count = mAllColors.size();
+ dest.writeInt(count);
+ for (Map.Entry<Integer, Integer> colorEntry : mAllColors.entrySet()) {
+ if (colorEntry.getKey() != null) {
+ dest.writeInt(colorEntry.getKey());
+ Integer population = mAllColors.get(colorEntry.getValue());
+ int populationInt = (population != null) ? population : 0;
+ dest.writeInt(populationInt);
+ }
}
dest.writeInt(mColorHints);
}
@@ -476,12 +486,13 @@ public final class WallpaperColors implements Parcelable {
WallpaperColors other = (WallpaperColors) o;
return mMainColors.equals(other.mMainColors)
+ && mAllColors.equals(other.mAllColors)
&& mColorHints == other.mColorHints;
}
@Override
public int hashCode() {
- return 31 * mMainColors.hashCode() + mColorHints;
+ return (31 * mMainColors.hashCode() * mAllColors.hashCode()) + mColorHints;
}
/**
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b5b7dbdff172..8284cdde3d06 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -13896,7 +13896,11 @@ public class DevicePolicyManager {
}
/**
- * Returns whether USB data signaling is currently enabled by the admin. Callable by any app.
+ * Returns whether USB data signaling is currently enabled.
+ *
+ * <p> When called by a device owner or profile owner of an organization-owned managed profile,
+ * this API returns whether USB data signaling is currently enabled by that admin. When called
+ * by any other app, returns whether USB data signaling is currently enabled on the device.
*
* @return {@code true} if USB data signaling is enabled, {@code false} otherwise.
*/
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ea0e321377c8..9c60f431b06e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3182,7 +3182,8 @@ public abstract class Context {
* <p>This function will throw {@link SecurityException} if you do not
* have permission to start the given service.
*
- * <p class="note"><strong>Note:</strong> Each call to startService()
+ * <div class="caution">
+ * <p><strong>Note:</strong> Each call to startService()
* results in significant work done by the system to manage service
* lifecycle surrounding the processing of the intent, which can take
* multiple milliseconds of CPU time. Due to this cost, startService()
@@ -3191,6 +3192,25 @@ public abstract class Context {
* for high frequency calls.
* </p>
*
+ * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#O},
+ * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#O}
+ * or higher are not allowed to start background services from the background.
+ * See
+ * <a href="{@docRoot}/about/versions/oreo/background">
+ * Background Execution Limits</a>
+ * for more details.
+ *
+ * <p><strong>Note:</strong>
+ * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#S},
+ * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S}
+ * or higher are not allowed to start foreground services from the background.
+ * See
+ * <a href="{@docRoot}/about/versions/12/behavior-changes-12">
+ * Behavior changes: Apps targeting Android 12
+ * </a>
+ * for more details.
+ * </div>
+ *
* @param service Identifies the service to be started. The Intent must be
* fully explicit (supplying a component name). Additional values
* may be included in the Intent extras to supply arguments along with
@@ -3215,6 +3235,7 @@ public abstract class Context {
* This excemption extends {@link IllegalStateException}, so apps can
* use {@code catch (IllegalStateException)} to catch both.
*
+ * @see #startForegroundService(Intent)
* @see #stopService
* @see #bindService
*/
@@ -3232,6 +3253,18 @@ public abstract class Context {
* at any time, regardless of whether the app hosting the service is in a foreground
* state.
*
+ * <div class="caution">
+ * <p><strong>Note:</strong>
+ * Beginning with SDK Version {@link android.os.Build.VERSION_CODES#S},
+ * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#S}
+ * or higher are not allowed to start foreground services from the background.
+ * See
+ * <a href="{@docRoot}/about/versions/12/behavior-changes-12">
+ * Behavior changes: Apps targeting Android 12
+ * </a>
+ * for more details.
+ * </div>
+ *
* @param service Identifies the service to be started. The Intent must be
* fully explicit (supplying a component name). Additional values
* may be included in the Intent extras to supply arguments along with
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index b0ce6a55e9ba..12911d6e1232 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -62,6 +62,8 @@ interface IPackageInstaller {
void bypassNextStagedInstallerCheck(boolean value);
+ void bypassNextAllowedApexUpdateCheck(boolean value);
+
void setAllowUnlimitedSilentUpdates(String installerPackageName);
void setSilentUpdatesThrottleTime(long throttleTimeInSeconds);
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c2ac80e7c98f..d3ed00608324 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -586,11 +586,6 @@ interface IPackageManager {
String targetCompilerFilter, boolean force);
/**
- * Ask the package manager to compile layouts in the given package.
- */
- boolean compileLayouts(String packageName);
-
- /**
* Ask the package manager to dump profiles associated with a package.
*/
void dumpProfiles(String packageName);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 33a34be1b968..2ed00b5d2982 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1278,6 +1278,13 @@ public abstract class PackageManager {
*/
public static final int INSTALL_STAGED = 0x00200000;
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that check whether given APEX can be
+ * updated should be disabled for this install.
+ * @hide
+ */
+ public static final int INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK = 0x00400000;
+
/** @hide */
@IntDef(flag = true, value = {
DONT_KILL_APP,
diff --git a/core/java/android/content/pm/PackagePartitions.java b/core/java/android/content/pm/PackagePartitions.java
index 52ee4de5bed6..d1577684aac6 100644
--- a/core/java/android/content/pm/PackagePartitions.java
+++ b/core/java/android/content/pm/PackagePartitions.java
@@ -119,6 +119,9 @@ public class PackagePartitions {
@Nullable
private final DeferredCanonicalFile mOverlayFolder;
+ @NonNull
+ private final File mNonConicalFolder;
+
private SystemPartition(@NonNull File folder, @PartitionType int type,
boolean containsPrivApp, boolean containsOverlay) {
this.type = type;
@@ -128,6 +131,7 @@ public class PackagePartitions {
: null;
this.mOverlayFolder = containsOverlay ? new DeferredCanonicalFile(folder, "overlay")
: null;
+ this.mNonConicalFolder = folder;
}
public SystemPartition(@NonNull SystemPartition original) {
@@ -136,6 +140,7 @@ public class PackagePartitions {
this.mAppFolder = original.mAppFolder;
this.mPrivAppFolder = original.mPrivAppFolder;
this.mOverlayFolder = original.mOverlayFolder;
+ this.mNonConicalFolder = original.mNonConicalFolder;
}
/**
@@ -153,6 +158,12 @@ public class PackagePartitions {
return mFolder.getFile();
}
+ /** Returns the non-canonical folder of the partition. */
+ @NonNull
+ public File getNonConicalFolder() {
+ return mNonConicalFolder;
+ }
+
/** Returns the canonical app folder of the partition. */
@Nullable
public File getAppFolder() {
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index 4c44ba1fc9ef..5a7f21040d0a 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -1164,7 +1164,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
dest.writeTypedList(this.usesPermissions);
sForInternedStringList.parcel(this.implicitPermissions, dest, flags);
sForStringSet.parcel(this.upgradeKeySets, dest, flags);
- dest.writeMap(this.keySetMapping);
+ ParsingPackageUtils.writeKeySetMapping(dest, this.keySetMapping);
sForInternedStringList.parcel(this.protectedBroadcasts, dest, flags);
dest.writeTypedList(this.activities);
dest.writeTypedList(this.receivers);
@@ -1180,7 +1180,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
sForInternedString.parcel(this.volumeUuid, dest, flags);
dest.writeParcelable(this.signingDetails, flags);
dest.writeString(this.mPath);
- dest.writeParcelableList(this.queriesIntents, flags);
+ dest.writeTypedList(this.queriesIntents, flags);
sForInternedStringList.parcel(this.queriesPackages, dest, flags);
sForInternedStringSet.parcel(this.queriesProviders, dest, flags);
dest.writeString(this.appComponentFactory);
@@ -1287,7 +1287,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
this.usesPermissions = in.createTypedArrayList(ParsedUsesPermission.CREATOR);
this.implicitPermissions = sForInternedStringList.unparcel(in);
this.upgradeKeySets = sForStringSet.unparcel(in);
- this.keySetMapping = in.readHashMap(boot);
+ this.keySetMapping = ParsingPackageUtils.readKeySetMapping(in);
this.protectedBroadcasts = sForInternedStringList.unparcel(in);
this.activities = in.createTypedArrayList(ParsedActivity.CREATOR);
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 6fd533355aad..dce242c9d87c 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -87,6 +87,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
+import android.os.Parcel;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
@@ -3160,6 +3161,68 @@ public class ParsingPackageUtils {
}
/**
+ * Writes the keyset mapping to the provided package. {@code null} mappings are permitted.
+ */
+ public static void writeKeySetMapping(@NonNull Parcel dest,
+ @NonNull Map<String, ArraySet<PublicKey>> keySetMapping) {
+ if (keySetMapping == null) {
+ dest.writeInt(-1);
+ return;
+ }
+
+ final int N = keySetMapping.size();
+ dest.writeInt(N);
+
+ for (String key : keySetMapping.keySet()) {
+ dest.writeString(key);
+ ArraySet<PublicKey> keys = keySetMapping.get(key);
+ if (keys == null) {
+ dest.writeInt(-1);
+ continue;
+ }
+
+ final int M = keys.size();
+ dest.writeInt(M);
+ for (int j = 0; j < M; j++) {
+ dest.writeSerializable(keys.valueAt(j));
+ }
+ }
+ }
+
+ /**
+ * Reads a keyset mapping from the given parcel at the given data position. May return
+ * {@code null} if the serialized mapping was {@code null}.
+ */
+ @NonNull
+ public static ArrayMap<String, ArraySet<PublicKey>> readKeySetMapping(@NonNull Parcel in) {
+ final int N = in.readInt();
+ if (N == -1) {
+ return null;
+ }
+
+ ArrayMap<String, ArraySet<PublicKey>> keySetMapping = new ArrayMap<>();
+ for (int i = 0; i < N; ++i) {
+ String key = in.readString();
+ final int M = in.readInt();
+ if (M == -1) {
+ keySetMapping.put(key, null);
+ continue;
+ }
+
+ ArraySet<PublicKey> keys = new ArraySet<>(M);
+ for (int j = 0; j < M; ++j) {
+ PublicKey pk = (PublicKey) in.readSerializable();
+ keys.add(pk);
+ }
+
+ keySetMapping.put(key, keys);
+ }
+
+ return keySetMapping;
+ }
+
+
+ /**
* Callback interface for retrieving information that may be needed while parsing
* a package.
*/
diff --git a/core/java/android/content/pm/parsing/component/ParsedComponent.java b/core/java/android/content/pm/parsing/component/ParsedComponent.java
index 4aed77ae641b..9d830ec7a227 100644
--- a/core/java/android/content/pm/parsing/component/ParsedComponent.java
+++ b/core/java/android/content/pm/parsing/component/ParsedComponent.java
@@ -172,7 +172,7 @@ public abstract class ParsedComponent implements Parcelable {
this.packageName = sForInternedString.unparcel(in);
this.intents = sForIntentInfos.unparcel(in);
this.metaData = in.readBundle(boot);
- this.mProperties = in.createTypedArrayMap(Property.CREATOR);
+ this.mProperties = in.readHashMap(boot);
}
@NonNull
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index 79f716cd5ce9..e665d0fcc836 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -60,7 +60,8 @@ public interface BiometricFingerprintConstants {
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
BIOMETRIC_ERROR_RE_ENROLL,
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
- FINGERPRINT_ERROR_UNKNOWN})
+ FINGERPRINT_ERROR_UNKNOWN,
+ FINGERPRINT_ERROR_BAD_CALIBARTION})
@Retention(RetentionPolicy.SOURCE)
@interface FingerprintError {}
@@ -181,6 +182,12 @@ public interface BiometricFingerprintConstants {
int FINGERPRINT_ERROR_UNKNOWN = 17;
/**
+ * Error indicating that the fingerprint sensor has bad calibration.
+ * @hide
+ */
+ int FINGERPRINT_ERROR_BAD_CALIBARTION = 18;
+
+ /**
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -201,7 +208,8 @@ public interface BiometricFingerprintConstants {
FINGERPRINT_ACQUIRED_TOO_FAST,
FINGERPRINT_ACQUIRED_VENDOR,
FINGERPRINT_ACQUIRED_START,
- FINGERPRINT_ACQUIRED_UNKNOWN})
+ FINGERPRINT_ACQUIRED_UNKNOWN,
+ FINGERPRINT_ACQUIRED_IMMOBILE})
@Retention(RetentionPolicy.SOURCE)
@interface FingerprintAcquired {}
@@ -271,6 +279,14 @@ public interface BiometricFingerprintConstants {
int FINGERPRINT_ACQUIRED_UNKNOWN = 8;
/**
+ * This message may be sent during enrollment if the same area of the finger has already
+ * been captured during this enrollment session. In general, enrolling multiple areas of the
+ * same finger can help against false rejections.
+ * @hide
+ */
+ int FINGERPRINT_ACQUIRED_IMMOBILE = 9;
+
+ /**
* @hide
*/
int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index a39bc4e0bee5..1c0ae281d9fe 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -16,6 +16,7 @@
package android.hardware.display;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Point;
import android.hardware.SensorManager;
@@ -29,6 +30,9 @@ import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
import java.util.Objects;
/**
@@ -37,6 +41,16 @@ import java.util.Objects;
* @hide Only for use within the system server.
*/
public abstract class DisplayManagerInternal {
+
+ @IntDef(prefix = {"REFRESH_RATE_LIMIT_"}, value = {
+ REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RefreshRateLimitType {}
+
+ /** Refresh rate should be limited when High Brightness Mode is active. */
+ public static final int REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE = 1;
+
/**
* Called by the power manager to initialize power management facilities.
*/
@@ -296,9 +310,10 @@ public abstract class DisplayManagerInternal {
public abstract int getRefreshRateSwitchingType();
/**
+ * TODO: b/191384041 - Replace this with getRefreshRateLimitations()
* Return the refresh rate restriction for the specified display and sensor pairing. If the
* specified sensor is identified as an associated sensor in the specified display's
- * display-device-config file, then return any refresh rate restrictions that it might specify.
+ * display-device-config file, then return any refresh rate restrictions that it might define.
* If no restriction is specified, or the sensor is not associated with the display, then null
* will be returned.
*
@@ -313,6 +328,15 @@ public abstract class DisplayManagerInternal {
int displayId, String name, String type);
/**
+ * Returns a list of various refresh rate limitations for the specified display.
+ *
+ * @param displayId The display to get limitations for.
+ *
+ * @return a list of {@link RefreshRateLimitation}s describing the various limits.
+ */
+ public abstract List<RefreshRateLimitation> getRefreshRateLimitations(int displayId);
+
+ /**
* Describes the requested power state of the display.
*
* This object is intended to describe the general characteristics of the
@@ -613,4 +637,25 @@ public abstract class DisplayManagerInternal {
return "(" + min + " " + max + ")";
}
}
+
+ /**
+ * Describes a limitation on a display's refresh rate. Includes the allowed refresh rate
+ * range as well as information about when it applies, such as high-brightness-mode.
+ */
+ public static final class RefreshRateLimitation {
+ @RefreshRateLimitType public int type;
+
+ /** The range the that refresh rate should be limited to. */
+ public RefreshRateRange range;
+
+ public RefreshRateLimitation(@RefreshRateLimitType int type, float min, float max) {
+ this.type = type;
+ range = new RefreshRateRange(min, max);
+ }
+
+ @Override
+ public String toString() {
+ return "RefreshRateLimitation(" + type + ": " + range + ")";
+ }
+ }
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index e5946663df47..0819835f5fb5 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1375,6 +1375,9 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
case BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
return context.getString(
com.android.internal.R.string.fingerprint_error_security_update_required);
+ case FINGERPRINT_ERROR_BAD_CALIBARTION:
+ context.getString(
+ com.android.internal.R.string.fingerprint_error_bad_calibration);
case FINGERPRINT_ERROR_VENDOR: {
String[] msgArray = context.getResources().getStringArray(
com.android.internal.R.array.fingerprint_error_vendor);
@@ -1414,6 +1417,9 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
case FINGERPRINT_ACQUIRED_TOO_FAST:
return context.getString(
com.android.internal.R.string.fingerprint_acquired_too_fast);
+ case FINGERPRINT_ACQUIRED_IMMOBILE:
+ return context.getString(
+ com.android.internal.R.string.fingerprint_acquired_immobile);
case FINGERPRINT_ACQUIRED_VENDOR: {
String[] msgArray = context.getResources().getStringArray(
com.android.internal.R.array.fingerprint_acquired_vendor);
diff --git a/core/java/android/hardware/input/InputDeviceVibrator.java b/core/java/android/hardware/input/InputDeviceVibrator.java
index d8150e483fd6..653c622386d6 100644
--- a/core/java/android/hardware/input/InputDeviceVibrator.java
+++ b/core/java/android/hardware/input/InputDeviceVibrator.java
@@ -56,10 +56,10 @@ final class InputDeviceVibrator extends Vibrator {
mDeviceId = deviceId;
mVibratorInfo = new VibratorInfo.Builder(vibratorId)
.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
- // Set predefined support to empty as we know input devices do not support them.
- .setSupportedEffects()
- .setSupportedPrimitives()
- .setSupportedBraking()
+ // The supported effect and braking lists are known to be empty for input devices,
+ // which is different from not being set (that means the device support is unknown).
+ .setSupportedEffects(new int[0])
+ .setSupportedBraking(new int[0])
.build();
mToken = new Binder();
}
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 77f8a87cdcd1..f48375246616 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -306,14 +306,23 @@ public final class BatteryUsageStats implements Parcelable {
AggregateBatteryConsumer.CREATOR.createFromParcel(source);
mAggregateBatteryConsumers[i].setCustomPowerComponentNames(mCustomPowerComponentNames);
}
- int uidCount = source.readInt();
+
+ // UidBatteryConsumers are included as a blob to avoid a TransactionTooLargeException
+ final Parcel blob = Parcel.obtain();
+ final byte[] bytes = source.readBlob();
+ blob.unmarshall(bytes, 0, bytes.length);
+ blob.setDataPosition(0);
+
+ final int uidCount = blob.readInt();
mUidBatteryConsumers = new ArrayList<>(uidCount);
for (int i = 0; i < uidCount; i++) {
final UidBatteryConsumer consumer =
- UidBatteryConsumer.CREATOR.createFromParcel(source);
+ UidBatteryConsumer.CREATOR.createFromParcel(blob);
consumer.setCustomPowerComponentNames(mCustomPowerComponentNames);
mUidBatteryConsumers.add(consumer);
}
+ blob.recycle();
+
int userCount = source.readInt();
mUserBatteryConsumers = new ArrayList<>(userCount);
for (int i = 0; i < userCount; i++) {
@@ -323,14 +332,10 @@ public final class BatteryUsageStats implements Parcelable {
mUserBatteryConsumers.add(consumer);
}
if (source.readBoolean()) {
- mHistoryBuffer = Parcel.obtain();
- mHistoryBuffer.setDataSize(0);
- mHistoryBuffer.setDataPosition(0);
+ final byte[] historyBlob = source.readBlob();
- int historyBufferSize = source.readInt();
- int curPos = source.dataPosition();
- mHistoryBuffer.appendFrom(source, curPos, historyBufferSize);
- source.setDataPosition(curPos + historyBufferSize);
+ mHistoryBuffer = Parcel.obtain();
+ mHistoryBuffer.unmarshall(historyBlob, 0, historyBlob.length);
int historyTagCount = source.readInt();
mHistoryTagPool = new ArrayList<>(historyTagCount);
@@ -362,21 +367,26 @@ public final class BatteryUsageStats implements Parcelable {
for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) {
mAggregateBatteryConsumers[i].writeToParcel(dest, flags);
}
- dest.writeInt(mUidBatteryConsumers.size());
+
+ // UidBatteryConsumers are included as a blob, because each UidBatteryConsumer
+ // takes > 300 bytes, so a typical number of UIDs in the system, 300 would result
+ // in a 90 kB Parcel, which is not safe to pass in a binder transaction because
+ // of the possibility of TransactionTooLargeException
+ final Parcel blob = Parcel.obtain();
+ blob.writeInt(mUidBatteryConsumers.size());
for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) {
- mUidBatteryConsumers.get(i).writeToParcel(dest, flags);
+ mUidBatteryConsumers.get(i).writeToParcel(blob, flags);
}
+ dest.writeBlob(blob.marshall());
+ blob.recycle();
+
dest.writeInt(mUserBatteryConsumers.size());
for (int i = mUserBatteryConsumers.size() - 1; i >= 0; i--) {
mUserBatteryConsumers.get(i).writeToParcel(dest, flags);
}
if (mHistoryBuffer != null) {
dest.writeBoolean(true);
-
- final int historyBufferSize = mHistoryBuffer.dataSize();
- dest.writeInt(historyBufferSize);
- dest.appendFrom(mHistoryBuffer, 0, historyBufferSize);
-
+ dest.writeBlob(mHistoryBuffer.marshall());
dest.writeInt(mHistoryTagPool.size());
for (int i = mHistoryTagPool.size() - 1; i >= 0; i--) {
final BatteryStats.HistoryTag tag = mHistoryTagPool.get(i);
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 12538e6cd46b..d7893e4bbefd 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -126,6 +126,7 @@ public abstract class Vibrator {
// The default vibration intensity level for ringtones.
@VibrationIntensity
private int mDefaultRingVibrationIntensity;
+ private float mHapticChannelMaxVibrationAmplitude;
/**
* @hide to prevent subclassing from outside of the framework
@@ -134,7 +135,7 @@ public abstract class Vibrator {
public Vibrator() {
mPackageName = ActivityThread.currentPackageName();
final Context ctx = ActivityThread.currentActivityThread().getSystemContext();
- loadVibrationIntensities(ctx);
+ loadVibrationConfig(ctx);
}
/**
@@ -142,22 +143,28 @@ public abstract class Vibrator {
*/
protected Vibrator(Context context) {
mPackageName = context.getOpPackageName();
- loadVibrationIntensities(context);
+ loadVibrationConfig(context);
}
- private void loadVibrationIntensities(Context context) {
+ private void loadVibrationConfig(Context context) {
mDefaultHapticFeedbackIntensity = loadDefaultIntensity(context,
com.android.internal.R.integer.config_defaultHapticFeedbackIntensity);
mDefaultNotificationVibrationIntensity = loadDefaultIntensity(context,
com.android.internal.R.integer.config_defaultNotificationVibrationIntensity);
mDefaultRingVibrationIntensity = loadDefaultIntensity(context,
com.android.internal.R.integer.config_defaultRingVibrationIntensity);
+ mHapticChannelMaxVibrationAmplitude = loadFloat(context,
+ com.android.internal.R.dimen.config_hapticChannelMaxVibrationAmplitude, 0);
}
private int loadDefaultIntensity(Context ctx, int resId) {
return ctx != null ? ctx.getResources().getInteger(resId) : VIBRATION_INTENSITY_MEDIUM;
}
+ private float loadFloat(Context ctx, int resId, float defaultValue) {
+ return ctx != null ? ctx.getResources().getFloat(resId) : defaultValue;
+ }
+
/** @hide */
protected VibratorInfo getInfo() {
return VibratorInfo.EMPTY_VIBRATOR_INFO;
@@ -297,6 +304,24 @@ public abstract class Vibrator {
}
/**
+ * Return the maximum amplitude the vibrator can play using the audio haptic channels.
+ *
+ * <p>This is a positive value, or {@link Float#NaN NaN} if it's unknown. If this returns a
+ * positive value <code>maxAmplitude</code>, then the signals from the haptic channels of audio
+ * tracks should be in the range <code>[-maxAmplitude, maxAmplitude]</code>.
+ *
+ * @return a positive value representing the maximum absolute value the device can play signals
+ * from audio haptic channels, or {@link Float#NaN NaN} if it's unknown.
+ * @hide
+ */
+ public float getHapticChannelMaximumAmplitude() {
+ if (mHapticChannelMaxVibrationAmplitude <= 0) {
+ return Float.NaN;
+ }
+ return mHapticChannelMaxVibrationAmplitude;
+ }
+
+ /**
* Configure an always-on haptics effect.
*
* @param alwaysOnId The board-specific always-on ID to configure.
diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java
index 597df0811e20..486f9f139e0a 100644
--- a/core/java/android/os/VibratorInfo.java
+++ b/core/java/android/os/VibratorInfo.java
@@ -51,8 +51,11 @@ public class VibratorInfo implements Parcelable {
private final SparseBooleanArray mSupportedEffects;
@Nullable
private final SparseBooleanArray mSupportedBraking;
- @Nullable
private final SparseIntArray mSupportedPrimitives;
+ private final int mPrimitiveDelayMax;
+ private final int mCompositionSizeMax;
+ private final int mPwlePrimitiveDurationMax;
+ private final int mPwleSizeMax;
private final float mQFactor;
private final FrequencyMapping mFrequencyMapping;
@@ -62,6 +65,10 @@ public class VibratorInfo implements Parcelable {
mSupportedEffects = in.readSparseBooleanArray();
mSupportedBraking = in.readSparseBooleanArray();
mSupportedPrimitives = in.readSparseIntArray();
+ mPrimitiveDelayMax = in.readInt();
+ mCompositionSizeMax = in.readInt();
+ mPwlePrimitiveDurationMax = in.readInt();
+ mPwleSizeMax = in.readInt();
mQFactor = in.readFloat();
mFrequencyMapping = in.readParcelable(VibratorInfo.class.getClassLoader());
}
@@ -69,48 +76,50 @@ public class VibratorInfo implements Parcelable {
/**
* Default constructor.
*
- * @param id The vibrator id.
- * @param capabilities All capability flags of the vibrator, defined in IVibrator.CAP_*.
- * @param supportedEffects All supported predefined effects, enum values from {@link
- * android.hardware.vibrator.Effect}.
- * @param supportedBraking All supported braking types, enum values from {@link Braking}.
- * @param supportedPrimitives All supported primitive effects, enum values from {@link
- * android.hardware.vibrator.CompositePrimitive}.
- * @param primitiveDurations A mapping of primitive durations, where indexes are enum values
- * from {@link android.hardware.vibrator.CompositePrimitive} and the
- * values are estimated durations in milliseconds.
- * @param qFactor The vibrator quality factor.
- * @param frequencyMapping The description of the vibrator supported frequencies and max
- * amplitude mappings.
+ * @param id The vibrator id.
+ * @param capabilities All capability flags of the vibrator, defined in
+ * IVibrator.CAP_*.
+ * @param supportedEffects All supported predefined effects, enum values from
+ * {@link android.hardware.vibrator.Effect}.
+ * @param supportedBraking All supported braking types, enum values from {@link
+ * Braking}.
+ * @param supportedPrimitives All supported primitive effects, key are enum values from
+ * {@link android.hardware.vibrator.CompositePrimitive} and
+ * values are estimated durations in milliseconds.
+ * @param primitiveDelayMax The maximum delay that can be set to a composition primitive
+ * in milliseconds.
+ * @param compositionSizeMax The maximum number of primitives supported by a composition.
+ * @param pwlePrimitiveDurationMax The maximum duration of a PWLE primitive in milliseconds.
+ * @param pwleSizeMax The maximum number of primitives supported by a PWLE
+ * composition.
+ * @param qFactor The vibrator quality factor.
+ * @param frequencyMapping The description of the vibrator supported frequencies and max
+ * amplitude mappings.
* @hide
*/
- public VibratorInfo(int id, long capabilities, int[] supportedEffects, int[] supportedBraking,
- int[] supportedPrimitives, int[] primitiveDurations, float qFactor,
- @NonNull FrequencyMapping frequencyMapping) {
+ public VibratorInfo(int id, long capabilities, @Nullable SparseBooleanArray supportedEffects,
+ @Nullable SparseBooleanArray supportedBraking,
+ @NonNull SparseIntArray supportedPrimitives, int primitiveDelayMax,
+ int compositionSizeMax, int pwlePrimitiveDurationMax, int pwleSizeMax,
+ float qFactor, @NonNull FrequencyMapping frequencyMapping) {
mId = id;
mCapabilities = capabilities;
- mSupportedEffects = toSparseBooleanArray(supportedEffects);
- mSupportedBraking = toSparseBooleanArray(supportedBraking);
- mSupportedPrimitives = toSparseIntArray(supportedPrimitives, primitiveDurations);
+ mSupportedEffects = supportedEffects == null ? null : supportedEffects.clone();
+ mSupportedBraking = supportedBraking == null ? null : supportedBraking.clone();
+ mSupportedPrimitives = supportedPrimitives.clone();
+ mPrimitiveDelayMax = primitiveDelayMax;
+ mCompositionSizeMax = compositionSizeMax;
+ mPwlePrimitiveDurationMax = pwlePrimitiveDurationMax;
+ mPwleSizeMax = pwleSizeMax;
mQFactor = qFactor;
mFrequencyMapping = frequencyMapping;
}
protected VibratorInfo(int id, int capabilities, VibratorInfo baseVibrator) {
- mId = id;
- mCapabilities = capabilities;
- mSupportedEffects = baseVibrator.mSupportedEffects == null ? null :
- baseVibrator.mSupportedEffects.clone();
- mSupportedBraking = baseVibrator.mSupportedBraking == null ? null :
- baseVibrator.mSupportedBraking.clone();
- mSupportedPrimitives = baseVibrator.mSupportedPrimitives == null ? null :
- baseVibrator.mSupportedPrimitives.clone();
- mQFactor = baseVibrator.mQFactor;
- mFrequencyMapping = new FrequencyMapping(baseVibrator.mFrequencyMapping.mMinFrequencyHz,
- baseVibrator.mFrequencyMapping.mResonantFrequencyHz,
- baseVibrator.mFrequencyMapping.mFrequencyResolutionHz,
- baseVibrator.mFrequencyMapping.mSuggestedSafeRangeHz,
- baseVibrator.mFrequencyMapping.mMaxAmplitudes);
+ this(id, capabilities, baseVibrator.mSupportedEffects, baseVibrator.mSupportedBraking,
+ baseVibrator.mSupportedPrimitives, baseVibrator.mPrimitiveDelayMax,
+ baseVibrator.mCompositionSizeMax, baseVibrator.mPwlePrimitiveDurationMax,
+ baseVibrator.mPwleSizeMax, baseVibrator.mQFactor, baseVibrator.mFrequencyMapping);
}
@Override
@@ -120,6 +129,10 @@ public class VibratorInfo implements Parcelable {
dest.writeSparseBooleanArray(mSupportedEffects);
dest.writeSparseBooleanArray(mSupportedBraking);
dest.writeSparseIntArray(mSupportedPrimitives);
+ dest.writeInt(mPrimitiveDelayMax);
+ dest.writeInt(mCompositionSizeMax);
+ dest.writeInt(mPwlePrimitiveDurationMax);
+ dest.writeInt(mPwleSizeMax);
dest.writeFloat(mQFactor);
dest.writeParcelable(mFrequencyMapping, flags);
}
@@ -138,24 +151,23 @@ public class VibratorInfo implements Parcelable {
return false;
}
VibratorInfo that = (VibratorInfo) o;
- if (mSupportedPrimitives == null || that.mSupportedPrimitives == null) {
- if (mSupportedPrimitives != that.mSupportedPrimitives) {
+ int supportedPrimitivesCount = mSupportedPrimitives.size();
+ if (supportedPrimitivesCount != that.mSupportedPrimitives.size()) {
+ return false;
+ }
+ for (int i = 0; i < supportedPrimitivesCount; i++) {
+ if (mSupportedPrimitives.keyAt(i) != that.mSupportedPrimitives.keyAt(i)) {
return false;
}
- } else {
- if (mSupportedPrimitives.size() != that.mSupportedPrimitives.size()) {
+ if (mSupportedPrimitives.valueAt(i) != that.mSupportedPrimitives.valueAt(i)) {
return false;
}
- for (int i = 0; i < mSupportedPrimitives.size(); i++) {
- if (mSupportedPrimitives.keyAt(i) != that.mSupportedPrimitives.keyAt(i)) {
- return false;
- }
- if (mSupportedPrimitives.valueAt(i) != that.mSupportedPrimitives.valueAt(i)) {
- return false;
- }
- }
}
return mId == that.mId && mCapabilities == that.mCapabilities
+ && mPrimitiveDelayMax == that.mPrimitiveDelayMax
+ && mCompositionSizeMax == that.mCompositionSizeMax
+ && mPwlePrimitiveDurationMax == that.mPwlePrimitiveDurationMax
+ && mPwleSizeMax == that.mPwleSizeMax
&& Objects.equals(mSupportedEffects, that.mSupportedEffects)
&& Objects.equals(mSupportedBraking, that.mSupportedBraking)
&& Objects.equals(mQFactor, that.mQFactor)
@@ -166,11 +178,9 @@ public class VibratorInfo implements Parcelable {
public int hashCode() {
int hashCode = Objects.hash(mId, mCapabilities, mSupportedEffects, mSupportedBraking,
mQFactor, mFrequencyMapping);
- if (mSupportedPrimitives != null) {
- for (int i = 0; i < mSupportedPrimitives.size(); i++) {
- hashCode = 31 * hashCode + mSupportedPrimitives.keyAt(i);
- hashCode = 31 * hashCode + mSupportedPrimitives.valueAt(i);
- }
+ for (int i = 0; i < mSupportedPrimitives.size(); i++) {
+ hashCode = 31 * hashCode + mSupportedPrimitives.keyAt(i);
+ hashCode = 31 * hashCode + mSupportedPrimitives.valueAt(i);
}
return hashCode;
}
@@ -184,6 +194,10 @@ public class VibratorInfo implements Parcelable {
+ ", mSupportedEffects=" + Arrays.toString(getSupportedEffectsNames())
+ ", mSupportedBraking=" + Arrays.toString(getSupportedBrakingNames())
+ ", mSupportedPrimitives=" + Arrays.toString(getSupportedPrimitivesNames())
+ + ", mPrimitiveDelayMax=" + mPrimitiveDelayMax
+ + ", mCompositionSizeMax=" + mCompositionSizeMax
+ + ", mPwlePrimitiveDurationMax=" + mPwlePrimitiveDurationMax
+ + ", mPwleSizeMax=" + mPwleSizeMax
+ ", mQFactor=" + mQFactor
+ ", mFrequencyMapping=" + mFrequencyMapping
+ '}';
@@ -247,7 +261,7 @@ public class VibratorInfo implements Parcelable {
*/
public boolean isPrimitiveSupported(
@VibrationEffect.Composition.PrimitiveType int primitiveId) {
- return hasCapability(IVibrator.CAP_COMPOSE_EFFECTS) && mSupportedPrimitives != null
+ return hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)
&& (mSupportedPrimitives.indexOfKey(primitiveId) >= 0);
}
@@ -260,7 +274,43 @@ public class VibratorInfo implements Parcelable {
*/
public int getPrimitiveDuration(
@VibrationEffect.Composition.PrimitiveType int primitiveId) {
- return mSupportedPrimitives != null ? mSupportedPrimitives.get(primitiveId) : 0;
+ return mSupportedPrimitives.get(primitiveId);
+ }
+
+ /**
+ * Query the maximum delay supported for a primitive in a composed effect.
+ *
+ * @return The max delay in milliseconds, or zero if unlimited.
+ */
+ public int getPrimitiveDelayMax() {
+ return mPrimitiveDelayMax;
+ }
+
+ /**
+ * Query the maximum number of primitives supported in a composed effect.
+ *
+ * @return The max number of primitives supported, or zero if unlimited.
+ */
+ public int getCompositionSizeMax() {
+ return mCompositionSizeMax;
+ }
+
+ /**
+ * Query the maximum duration supported for a primitive in a PWLE composition.
+ *
+ * @return The max duration in milliseconds, or zero if unlimited.
+ */
+ public int getPwlePrimitiveDurationMax() {
+ return mPwlePrimitiveDurationMax;
+ }
+
+ /**
+ * Query the maximum number of primitives supported in a PWLE composition.
+ *
+ * @return The max number of primitives supported, or zero if unlimited.
+ */
+ public int getPwleSizeMax() {
+ return mPwleSizeMax;
}
/**
@@ -408,52 +458,15 @@ public class VibratorInfo implements Parcelable {
}
private String[] getSupportedPrimitivesNames() {
- if (mSupportedPrimitives == null) {
- return new String[0];
- }
- String[] names = new String[mSupportedPrimitives.size()];
- for (int i = 0; i < mSupportedPrimitives.size(); i++) {
+ int supportedPrimitivesCount = mSupportedPrimitives.size();
+ String[] names = new String[supportedPrimitivesCount];
+ for (int i = 0; i < supportedPrimitivesCount; i++) {
names[i] = VibrationEffect.Composition.primitiveToString(mSupportedPrimitives.keyAt(i));
}
return names;
}
/**
- * Create a {@link SparseBooleanArray} from given {@code supportedKeys} where each key is mapped
- * to {@code true}.
- */
- @Nullable
- private static SparseBooleanArray toSparseBooleanArray(int[] supportedKeys) {
- if (supportedKeys == null) {
- return null;
- }
- SparseBooleanArray array = new SparseBooleanArray();
- for (int key : supportedKeys) {
- array.put(key, true);
- }
- return array;
- }
-
- /**
- * Create a {@link SparseIntArray} from given {@code supportedKeys} where each key is mapped
- * to the value indexed by it.
- *
- * <p>If {@code values} is null or does not contain a given key as a index, then zero is stored
- * to the sparse array so it can still be used to query the supported keys.
- */
- @Nullable
- private static SparseIntArray toSparseIntArray(int[] supportedKeys, int[] values) {
- if (supportedKeys == null) {
- return null;
- }
- SparseIntArray array = new SparseIntArray();
- for (int key : supportedKeys) {
- array.put(key, (values == null || key >= values.length) ? 0 : values[key]);
- }
- return array;
- }
-
- /**
* Describes how frequency should be mapped to absolute values for a specific {@link Vibrator}.
*
* <p>This mapping is defined by the following parameters:
@@ -675,11 +688,14 @@ public class VibratorInfo implements Parcelable {
/** @hide */
public static final class Builder {
private final int mId;
- private int mCapabilities = 0;
- private int[] mSupportedEffects = null;
- private int[] mSupportedBraking = null;
- private int[] mSupportedPrimitives = null;
- private int[] mPrimitiveDurations = new int[0];
+ private long mCapabilities;
+ private SparseBooleanArray mSupportedEffects;
+ private SparseBooleanArray mSupportedBraking;
+ private SparseIntArray mSupportedPrimitives = new SparseIntArray();
+ private int mPrimitiveDelayMax;
+ private int mCompositionSizeMax;
+ private int mPwlePrimitiveDurationMax;
+ private int mPwleSizeMax;
private float mQFactor = Float.NaN;
private FrequencyMapping mFrequencyMapping =
new FrequencyMapping(Float.NaN, Float.NaN, Float.NaN, Float.NaN, null);
@@ -691,7 +707,7 @@ public class VibratorInfo implements Parcelable {
/** Configure the vibrator capabilities with a combination of IVibrator.CAP_* values. */
@NonNull
- public Builder setCapabilities(int capabilities) {
+ public Builder setCapabilities(long capabilities) {
mCapabilities = capabilities;
return this;
}
@@ -699,34 +715,49 @@ public class VibratorInfo implements Parcelable {
/** Configure the effects supported with {@link android.hardware.vibrator.Effect} values. */
@NonNull
public Builder setSupportedEffects(int... supportedEffects) {
- mSupportedEffects = supportedEffects;
+ mSupportedEffects = toSparseBooleanArray(supportedEffects);
return this;
}
/** Configure braking supported with {@link android.hardware.vibrator.Braking} values. */
@NonNull
public Builder setSupportedBraking(int... supportedBraking) {
- mSupportedBraking = supportedBraking;
+ mSupportedBraking = toSparseBooleanArray(supportedBraking);
return this;
}
- /**
- * Configure the primitives supported with
- * {@link android.hardware.vibrator.CompositePrimitive} values.
- */
+ /** Configure maximum duration, in milliseconds, of a PWLE primitive. */
+ @NonNull
+ public Builder setPwlePrimitiveDurationMax(int pwlePrimitiveDurationMax) {
+ mPwlePrimitiveDurationMax = pwlePrimitiveDurationMax;
+ return this;
+ }
+
+ /** Configure maximum number of primitives supported in a single PWLE composed effect. */
@NonNull
- public Builder setSupportedPrimitives(int... supportedPrimitives) {
- mSupportedPrimitives = supportedPrimitives;
+ public Builder setPwleSizeMax(int pwleSizeMax) {
+ mPwleSizeMax = pwleSizeMax;
return this;
}
/** Configure the duration of a {@link android.hardware.vibrator.CompositePrimitive}. */
@NonNull
- public Builder setPrimitiveDuration(int primitiveId, int duration) {
- if (mPrimitiveDurations.length <= primitiveId) {
- mPrimitiveDurations = Arrays.copyOf(mPrimitiveDurations, primitiveId + 1);
- }
- mPrimitiveDurations[primitiveId] = duration;
+ public Builder setSupportedPrimitive(int primitiveId, int duration) {
+ mSupportedPrimitives.put(primitiveId, duration);
+ return this;
+ }
+
+ /** Configure maximum delay, in milliseconds, supported in a composed effect primitive. */
+ @NonNull
+ public Builder setPrimitiveDelayMax(int primitiveDelayMax) {
+ mPrimitiveDelayMax = primitiveDelayMax;
+ return this;
+ }
+
+ /** Configure maximum number of primitives supported in a single composed effect. */
+ @NonNull
+ public Builder setCompositionSizeMax(int compositionSizeMax) {
+ mCompositionSizeMax = compositionSizeMax;
return this;
}
@@ -748,7 +779,25 @@ public class VibratorInfo implements Parcelable {
@NonNull
public VibratorInfo build() {
return new VibratorInfo(mId, mCapabilities, mSupportedEffects, mSupportedBraking,
- mSupportedPrimitives, mPrimitiveDurations, mQFactor, mFrequencyMapping);
+ mSupportedPrimitives, mPrimitiveDelayMax, mCompositionSizeMax,
+ mPwlePrimitiveDurationMax, mPwleSizeMax, mQFactor, mFrequencyMapping);
+ }
+
+ /**
+ * Create a {@link SparseBooleanArray} from given {@code supportedKeys} where each key is
+ * mapped
+ * to {@code true}.
+ */
+ @Nullable
+ private static SparseBooleanArray toSparseBooleanArray(int[] supportedKeys) {
+ if (supportedKeys == null) {
+ return null;
+ }
+ SparseBooleanArray array = new SparseBooleanArray();
+ for (int key : supportedKeys) {
+ array.put(key, true);
+ }
+ return array;
}
}
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 0b11aeb1ed65..3b4f7e241852 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -124,7 +124,6 @@ public final class KeymasterDefs {
public static final int KM_TAG_DEVICE_UNIQUE_ATTESTATION =
Tag.DEVICE_UNIQUE_ATTESTATION; // KM_BOOL | 720;
- public static final int KM_TAG_ASSOCIATED_DATA = Tag.ASSOCIATED_DATA; // KM_BYTES | 1000;
public static final int KM_TAG_NONCE = Tag.NONCE; // KM_BYTES | 1001;
public static final int KM_TAG_MAC_LENGTH = Tag.MAC_LENGTH; // KM_UINT | 1003;
public static final int KM_TAG_RESET_SINCE_ID_ROTATION =
diff --git a/core/java/android/service/translation/TranslationService.java b/core/java/android/service/translation/TranslationService.java
index e1d4a5656b39..93c006aff435 100644
--- a/core/java/android/service/translation/TranslationService.java
+++ b/core/java/android/service/translation/TranslationService.java
@@ -361,6 +361,11 @@ public abstract class TranslationService extends Service {
new Consumer<Set<TranslationCapability>>() {
@Override
public void accept(Set<TranslationCapability> values) {
+ if (!isValidCapabilities(sourceFormat, targetFormat, values)) {
+ throw new IllegalStateException("Invalid capabilities and "
+ + "format compatibility");
+ }
+
final ArraySet<TranslationCapability> capabilities = new ArraySet<>(values);
final Bundle bundle = new Bundle();
bundle.putParcelableArray(TranslationManager.EXTRA_CAPABILITIES,
@@ -369,4 +374,23 @@ public abstract class TranslationService extends Service {
}
});
}
+
+ /**
+ * Helper method to validate capabilities and format compatibility.
+ */
+ private boolean isValidCapabilities(@TranslationSpec.DataFormat int sourceFormat,
+ @TranslationSpec.DataFormat int targetFormat, Set<TranslationCapability> capabilities) {
+ if (sourceFormat != TranslationSpec.DATA_FORMAT_TEXT
+ && targetFormat != TranslationSpec.DATA_FORMAT_TEXT) {
+ return true;
+ }
+
+ for (TranslationCapability capability : capabilities) {
+ if (capability.getState() == TranslationCapability.STATE_REMOVED_AND_AVAILABLE) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 67b97cee1b51..41374167cc56 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -263,6 +263,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
private static final int MSG_DETECTION_RESUME = 5;
private static final int MSG_HOTWORD_REJECTED = 6;
private static final int MSG_HOTWORD_STATUS_REPORTED = 7;
+ private static final int MSG_PROCESS_RESTARTED = 8;
private final String mText;
private final Locale mLocale;
@@ -1212,6 +1213,12 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
message.arg1 = status;
message.sendToTarget();
}
+
+ @Override
+ public void onProcessRestarted() {
+ Slog.i(TAG, "onProcessRestarted");
+ mHandler.sendEmptyMessage(MSG_PROCESS_RESTARTED);
+ }
}
class MyHandler extends Handler {
@@ -1246,6 +1253,9 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
case MSG_HOTWORD_STATUS_REPORTED:
mExternalCallback.onHotwordDetectionServiceInitialized(msg.arg1);
break;
+ case MSG_PROCESS_RESTARTED:
+ mExternalCallback.onHotwordDetectionServiceRestarted();
+ break;
default:
super.handleMessage(msg);
}
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index b66d93d6316e..93a7ec793536 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -291,9 +291,7 @@ public abstract class HotwordDetectionService extends Service {
@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory,
@DurationMillisLong long callbackTimeoutMillis,
- @Nullable IntConsumer statusCallback) {
- // TODO: Handle the unimplemented case by throwing?
- }
+ @Nullable IntConsumer statusCallback) {}
/**
* Called when the {@link VoiceInteractionService} requests that this service
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index 204e7df89706..fb540b1622e6 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -122,7 +122,7 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
this.mCallback = callback;
}
- /** TODO: onDetected */
+ /** Called when the detected result is valid. */
@Override
public void onDetected(
@Nullable HotwordDetectedResult hotwordDetectedResult,
@@ -150,33 +150,45 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
public void onKeyphraseDetected(
SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
HotwordDetectedResult result) {
-
+ if (DEBUG) {
+ Slog.i(TAG, "Ignored #onKeyphraseDetected event");
+ }
}
@Override
public void onGenericSoundTriggerDetected(
SoundTrigger.GenericRecognitionEvent recognitionEvent) throws RemoteException {
-
+ if (DEBUG) {
+ Slog.i(TAG, "Ignored #onGenericSoundTriggerDetected event");
+ }
}
@Override
public void onRejected(HotwordRejectedResult result) throws RemoteException {
-
+ if (DEBUG) {
+ Slog.i(TAG, "Ignored #onRejected event");
+ }
}
@Override
public void onError(int status) throws RemoteException {
-
+ if (DEBUG) {
+ Slog.i(TAG, "Ignored #onError (" + status + ") event");
+ }
}
@Override
public void onRecognitionPaused() throws RemoteException {
-
+ if (DEBUG) {
+ Slog.i(TAG, "Ignored #onRecognitionPaused event");
+ }
}
@Override
public void onRecognitionResumed() throws RemoteException {
-
+ if (DEBUG) {
+ Slog.i(TAG, "Ignored #onRecognitionResumed event");
+ }
}
@Override
@@ -187,6 +199,14 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
mCallback,
status));
}
+
+ @Override
+ public void onProcessRestarted() throws RemoteException {
+ Slog.v(TAG, "onProcessRestarted()");
+ mHandler.sendMessage(obtainMessage(
+ HotwordDetector.Callback::onHotwordDetectionServiceRestarted,
+ mCallback));
+ }
}
/** @hide */
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8080883c2b3e..145607ada4f4 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1265,7 +1265,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished();
}
- if (invokeCallback && runningAnimation.startDispatched) {
+ if (invokeCallback) {
dispatchAnimationEnd(runningAnimation.runner.getAnimation());
}
break;
diff --git a/core/java/android/view/ScrollCaptureTarget.java b/core/java/android/view/ScrollCaptureTarget.java
index 44017ed0d831..a8bb037af5f9 100644
--- a/core/java/android/view/ScrollCaptureTarget.java
+++ b/core/java/android/view/ScrollCaptureTarget.java
@@ -21,13 +21,10 @@ import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
-import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.CancellationSignal;
-import com.android.internal.util.FastMath;
-
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -43,8 +40,7 @@ public final class ScrollCaptureTarget {
private final int mHint;
private Rect mScrollBounds;
- private final float[] mTmpFloatArr = new float[2];
- private final Matrix mMatrixViewLocalToWindow = new Matrix();
+ private final int[] mTmpIntArr = new int[2];
public ScrollCaptureTarget(@NonNull View scrollTarget, @NonNull Rect localVisibleRect,
@NonNull Point positionInWindow, @NonNull ScrollCaptureCallback callback) {
@@ -117,28 +113,15 @@ public final class ScrollCaptureTarget {
}
}
- private static void zero(float[] pointArray) {
- pointArray[0] = 0;
- pointArray[1] = 0;
- }
-
- private static void roundIntoPoint(Point pointObj, float[] pointArray) {
- pointObj.x = FastMath.round(pointArray[0]);
- pointObj.y = FastMath.round(pointArray[1]);
- }
-
/**
- * Refresh the local visible bounds and it's offset within the window, based on the current
+ * Refresh the local visible bounds and its offset within the window, based on the current
* state of the {@code containing view}.
*/
@UiThread
public void updatePositionInWindow() {
- mMatrixViewLocalToWindow.reset();
- mContainingView.transformMatrixToGlobal(mMatrixViewLocalToWindow);
-
- zero(mTmpFloatArr);
- mMatrixViewLocalToWindow.mapPoints(mTmpFloatArr);
- roundIntoPoint(mPositionInWindow, mTmpFloatArr);
+ mContainingView.getLocationInWindow(mTmpIntArr);
+ mPositionInWindow.x = mTmpIntArr[0];
+ mPositionInWindow.y = mTmpIntArr[1];
}
public String toString() {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index f34cd8f9de50..4e66ceb76a60 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -233,6 +233,7 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeRemoveJankDataListener(long nativeListener);
private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener);
private static native int nativeGetGPUContextPriority();
+ private static native void nativeSetTransformHint(long nativeObject, int transformHint);
@Nullable
@GuardedBy("mLock")
@@ -348,6 +349,8 @@ public final class SurfaceControl implements Parcelable {
@GuardedBy("mLock")
private int mHeight;
+ private int mTransformHint;
+
private WeakReference<View> mLocalOwnerView;
static GlobalTransactionWrapper sGlobalTransaction;
@@ -605,6 +608,7 @@ public final class SurfaceControl implements Parcelable {
mName = other.mName;
mWidth = other.mWidth;
mHeight = other.mHeight;
+ mTransformHint = other.mTransformHint;
mLocalOwnerView = other.mLocalOwnerView;
assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
}
@@ -1467,6 +1471,7 @@ public final class SurfaceControl implements Parcelable {
mName = in.readString8();
mWidth = in.readInt();
mHeight = in.readInt();
+ mTransformHint = in.readInt();
long object = 0;
if (in.readInt() != 0) {
@@ -1485,6 +1490,7 @@ public final class SurfaceControl implements Parcelable {
dest.writeString8(mName);
dest.writeInt(mWidth);
dest.writeInt(mHeight);
+ dest.writeInt(mTransformHint);
if (mNativeObject == 0) {
dest.writeInt(0);
} else {
@@ -3602,4 +3608,27 @@ public final class SurfaceControl implements Parcelable {
mHeight = h;
nativeUpdateDefaultBufferSize(mNativeObject, w, h);
}
+
+ /**
+ * @hide
+ */
+ public int getTransformHint() {
+ return mTransformHint;
+ }
+
+ /**
+ * Update the transform hint of current SurfaceControl. Only affect if type is
+ * {@link #FX_SURFACE_BLAST}
+ *
+ * The transform hint is used to prevent allocating a buffer of different size when a
+ * layer is rotated. The producer can choose to consume the hint and allocate the buffer
+ * with the same size.
+ * @hide
+ */
+ public void setTransformHint(@Surface.Rotation int transformHint) {
+ if (mTransformHint != transformHint) {
+ mTransformHint = transformHint;
+ nativeSetTransformHint(mNativeObject, transformHint);
+ }
+ }
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 6b0bb9df5468..4f2cf6d9001e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -30,7 +30,6 @@ import android.graphics.BLASTBufferQueue;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.HardwareRenderer;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -214,6 +213,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
final Rect mSurfaceFrame = new Rect();
int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
+ int mTransformHint = 0;
private boolean mGlobalListenersAdded;
private boolean mAttachedToWindow;
@@ -944,7 +944,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
- boolean creating, boolean sizeChanged) {
+ boolean creating, boolean sizeChanged, boolean hintChanged) {
boolean realSizeChanged = false;
mSurfaceLock.lock();
@@ -1009,7 +1009,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
mTmpTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
- if (sizeChanged && !creating) {
+ if ((sizeChanged || hintChanged) && !creating) {
setBufferSize(mTmpTransaction);
}
@@ -1081,17 +1081,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|| mWindowSpaceTop != mLocation[1];
final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
|| getHeight() != mScreenRect.height();
-
+ final boolean hintChanged = viewRoot.getSurfaceTransformHint() != mTransformHint;
if (creating || formatChanged || sizeChanged || visibleChanged ||
(mUseAlpha && alphaChanged) || windowVisibleChanged ||
- positionChanged || layoutSizeChanged) {
+ positionChanged || layoutSizeChanged || hintChanged) {
getLocationInWindow(mLocation);
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged
+ " visible=" + visibleChanged + " alpha=" + alphaChanged
+ + " hint=" + hintChanged
+ " mUseAlpha=" + mUseAlpha
+ " visible=" + visibleChanged
+ " left=" + (mWindowSpaceLeft != mLocation[0])
@@ -1105,6 +1106,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mSurfaceHeight = myHeight;
mFormat = mRequestedFormat;
mLastWindowVisibility = mWindowVisibility;
+ mTransformHint = viewRoot.getSurfaceTransformHint();
mScreenRect.left = mWindowSpaceLeft;
mScreenRect.top = mWindowSpaceTop;
@@ -1130,9 +1132,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
- translator, creating, sizeChanged);
- final boolean redrawNeeded = sizeChanged || creating ||
- (mVisible && !mDrawFinished);
+ translator, creating, sizeChanged, hintChanged);
+ final boolean redrawNeeded = sizeChanged || creating || hintChanged
+ || (mVisible && !mDrawFinished);
try {
SurfaceHolder.Callback[] callbacks = null;
@@ -1158,7 +1160,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
c.surfaceCreated(mSurfaceHolder);
}
}
- if (creating || formatChanged || sizeChanged
+ if (creating || formatChanged || sizeChanged || hintChanged
|| visibleChanged || realSizeChanged) {
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "surfaceChanged -- format=" + mFormat
@@ -1234,6 +1236,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private void setBufferSize(Transaction transaction) {
if (mUseBlastAdapter) {
+ mBlastSurfaceControl.setTransformHint(mTransformHint);
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
} else {
transaction.setBufferSize(mSurfaceControl, mSurfaceWidth, mSurfaceHeight);
@@ -1330,6 +1333,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
if (mBlastBufferQueue != null) {
mBlastBufferQueue.destroy();
}
+ mTransformHint = viewRoot.getSurfaceTransformHint();
+ mBlastSurfaceControl.setTransformHint(mTransformHint);
mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight, mFormat);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cf8c746d6ecb..573ae998305e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -10382,4 +10382,8 @@ public final class ViewRootImpl implements ViewParent,
});
return true;
}
+
+ int getSurfaceTransformHint() {
+ return mSurfaceControl.getTransformHint();
+ }
}
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index d8cd6056de90..27821fd6608d 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -110,6 +110,10 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
@Override
public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) {
if (DEBUG) Log.d(TAG, "windowInsetsAnimation ended");
+ if (mViewRoot.mView == null) {
+ // The view has already detached from window.
+ return;
+ }
mViewRoot.mView.dispatchWindowInsetsAnimationEnd(animation);
}
diff --git a/core/java/android/view/WindowInsetsAnimation.java b/core/java/android/view/WindowInsetsAnimation.java
index ab5b5ba51a6e..6576eea40496 100644
--- a/core/java/android/view/WindowInsetsAnimation.java
+++ b/core/java/android/view/WindowInsetsAnimation.java
@@ -360,6 +360,13 @@ public final class WindowInsetsAnimation {
* finished, and then revert to the starting state of the animation in the first
* {@link #onProgress} callback by using post-layout view properties like {@link View#setX}
* and related methods.
+ *
+ * <p>Note that the animation might be cancelled before {@link #onStart} is dispatched. On
+ * {@link android.os.Build.VERSION_CODES#S S} and later, {@link #onEnd} is immediately
+ * dispatched without an {@link #onStart} in that case.
+ * On {@link android.os.Build.VERSION_CODES#R R}, no callbacks are dispatched after
+ * {@code #onPrepare} for such an animation.
+ *
* <p>
* Note: If the animation is application controlled by using
* {@link WindowInsetsController#controlWindowInsetsAnimation}, the end state of the
diff --git a/core/java/android/view/translation/TranslationCapability.java b/core/java/android/view/translation/TranslationCapability.java
index d104b2427c8e..65b749add1b2 100644
--- a/core/java/android/view/translation/TranslationCapability.java
+++ b/core/java/android/view/translation/TranslationCapability.java
@@ -61,6 +61,13 @@ public final class TranslationCapability implements Parcelable {
* was dropped.</p>
*/
public static final @ModelState int STATE_NOT_AVAILABLE = 4;
+ /**
+ * The translation between the source and target specs were removed from the system, but is
+ * still available to be downloaded again.
+ *
+ * @hide
+ */
+ public static final @ModelState int STATE_REMOVED_AND_AVAILABLE = 1000;
/**
* The state of translation readiness between {@code mSourceSpec} and {@code mTargetSpec}.
@@ -134,7 +141,8 @@ public final class TranslationCapability implements Parcelable {
STATE_AVAILABLE_TO_DOWNLOAD,
STATE_DOWNLOADING,
STATE_ON_DEVICE,
- STATE_NOT_AVAILABLE
+ STATE_NOT_AVAILABLE,
+ STATE_REMOVED_AND_AVAILABLE
})
@Retention(RetentionPolicy.SOURCE)
@DataClass.Generated.Member
@@ -152,6 +160,8 @@ public final class TranslationCapability implements Parcelable {
return "STATE_ON_DEVICE";
case STATE_NOT_AVAILABLE:
return "STATE_NOT_AVAILABLE";
+ case STATE_REMOVED_AND_AVAILABLE:
+ return "STATE_REMOVED_AND_AVAILABLE";
default: return Integer.toHexString(value);
}
}
@@ -255,13 +265,15 @@ public final class TranslationCapability implements Parcelable {
if (!(mState == STATE_AVAILABLE_TO_DOWNLOAD)
&& !(mState == STATE_DOWNLOADING)
&& !(mState == STATE_ON_DEVICE)
- && !(mState == STATE_NOT_AVAILABLE)) {
+ && !(mState == STATE_NOT_AVAILABLE)
+ && !(mState == STATE_REMOVED_AND_AVAILABLE)) {
throw new java.lang.IllegalArgumentException(
"state was " + mState + " but must be one of: "
+ "STATE_AVAILABLE_TO_DOWNLOAD(" + STATE_AVAILABLE_TO_DOWNLOAD + "), "
+ "STATE_DOWNLOADING(" + STATE_DOWNLOADING + "), "
+ "STATE_ON_DEVICE(" + STATE_ON_DEVICE + "), "
- + "STATE_NOT_AVAILABLE(" + STATE_NOT_AVAILABLE + ")");
+ + "STATE_NOT_AVAILABLE(" + STATE_NOT_AVAILABLE + "), "
+ + "STATE_REMOVED_AND_AVAILABLE(" + STATE_REMOVED_AND_AVAILABLE + ")");
}
this.mSourceSpec = sourceSpec;
@@ -293,10 +305,10 @@ public final class TranslationCapability implements Parcelable {
};
@DataClass.Generated(
- time = 1621545303074L,
+ time = 1624307114468L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/view/translation/TranslationCapability.java",
- inputSignatures = "public static final @android.view.translation.TranslationCapability.ModelState int STATE_AVAILABLE_TO_DOWNLOAD\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_DOWNLOADING\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_ON_DEVICE\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_NOT_AVAILABLE\nprivate final @android.view.translation.TranslationCapability.ModelState int mState\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mSourceSpec\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mTargetSpec\nprivate final boolean mUiTranslationEnabled\nprivate final @android.view.translation.TranslationContext.TranslationFlag int mSupportedTranslationFlags\nclass TranslationCapability extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstDefs=true, genToString=true, genConstructor=false)")
+ inputSignatures = "public static final @android.view.translation.TranslationCapability.ModelState int STATE_AVAILABLE_TO_DOWNLOAD\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_DOWNLOADING\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_ON_DEVICE\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_NOT_AVAILABLE\npublic static final @android.view.translation.TranslationCapability.ModelState int STATE_REMOVED_AND_AVAILABLE\nprivate final @android.view.translation.TranslationCapability.ModelState int mState\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mSourceSpec\nprivate final @android.annotation.NonNull android.view.translation.TranslationSpec mTargetSpec\nprivate final boolean mUiTranslationEnabled\nprivate final @android.view.translation.TranslationContext.TranslationFlag int mSupportedTranslationFlags\nclass TranslationCapability extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstDefs=true, genToString=true, genConstructor=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
index ec99c95a737c..d0214e6e0082 100644
--- a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
+++ b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
@@ -78,4 +78,7 @@ oneway interface IHotwordRecognitionStatusCallback {
* @param status The status about the result of requesting update state action.
*/
void onStatusReported(int status);
+
+ /** Called when the hotword detection process is restarted */
+ void onProcessRestarted();
}
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index b38f623e3a6d..3f3c9bdbe5f5 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -111,7 +111,7 @@ public class OverlayConfig {
// Rebase the system partitions and settings file on the specified root directory.
partitions = new ArrayList<>(PackagePartitions.getOrderedPartitions(
p -> new OverlayPartition(
- new File(rootDirectory, p.getFolder().getPath()),
+ new File(rootDirectory, p.getNonConicalFolder().getPath()),
p)));
}
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index af21f8183d3a..9ced6097804d 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -228,7 +228,7 @@ public interface ServiceConnector<I extends IInterface> {
private final int mBindingFlags;
private final @Nullable Function<IBinder, I> mBinderAsInterface;
private final @NonNull Handler mHandler;
- private final @NonNull Executor mExecutor;
+ protected final @NonNull Executor mExecutor;
private volatile I mService = null;
private boolean mBinding = false;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 945a6ab11856..dab3e9fa15fa 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -12141,6 +12141,15 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
}
+
+ void reset() {
+ idleTimeMs = 0;
+ rxTimeMs = 0;
+ txTimeMs = 0;
+ energy = 0;
+ uidRxBytes.clear();
+ uidTxBytes.clear();
+ }
}
private final BluetoothActivityInfoCache mLastBluetoothActivityInfo
@@ -12167,6 +12176,15 @@ public class BatteryStatsImpl extends BatteryStats {
mHasBluetoothReporting = true;
+ if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs
+ || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs
+ || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs
+ || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) {
+ // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash.
+ // Reset the preserved previous snapshot in order to restart accumulating deltas.
+ mLastBluetoothActivityInfo.reset();
+ }
+
final long rxTimeMs =
info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs;
final long txTimeMs =
diff --git a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
index 8aa2d57e8ea6..9e09006f608d 100644
--- a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
+++ b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
@@ -198,12 +198,9 @@ public class ScrollCaptureViewSupport<V extends View> implements ScrollCaptureCa
private static final float LIGHT_RADIUS_DP = 800;
private static final String TAG = "ViewRenderer";
- private HardwareRenderer mRenderer;
- private RenderNode mCaptureRenderNode;
- private final RectF mTempRectF = new RectF();
- private final Rect mSourceRect = new Rect();
+ private final HardwareRenderer mRenderer;
+ private final RenderNode mCaptureRenderNode;
private final Rect mTempRect = new Rect();
- private final Matrix mTempMatrix = new Matrix();
private final int[] mTempLocation = new int[2];
private long mLastRenderedSourceDrawingId = -1;
private Surface mSurface;
@@ -313,11 +310,9 @@ public class ScrollCaptureViewSupport<V extends View> implements ScrollCaptureCa
}
private void transformToRoot(View local, Rect localRect, Rect outRect) {
- mTempMatrix.reset();
- local.transformMatrixToGlobal(mTempMatrix);
- mTempRectF.set(localRect);
- mTempMatrix.mapRect(mTempRectF);
- mTempRectF.round(outRect);
+ local.getLocationInWindow(mTempLocation);
+ outRect.set(localRect);
+ outRect.offset(mTempLocation[0], mTempLocation[1]);
}
public void setColorMode(@ColorMode int colorMode) {
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index bd0de2984b7f..6976ace36c11 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -240,6 +240,7 @@ public class SystemConfig {
private final ArraySet<String> mRollbackWhitelistedPackages = new ArraySet<>();
private final ArraySet<String> mWhitelistedStagedInstallers = new ArraySet<>();
+ private final ArraySet<String> mAllowedPartnerApexes = new ArraySet<>();
/**
* Map of system pre-defined, uniquely named actors; keys are namespace,
@@ -410,6 +411,10 @@ public class SystemConfig {
return mWhitelistedStagedInstallers;
}
+ public Set<String> getAllowedPartnerApexes() {
+ return mAllowedPartnerApexes;
+ }
+
public ArraySet<String> getAppDataIsolationWhitelistedApps() {
return mAppDataIsolationWhitelistedApps;
}
@@ -1212,6 +1217,21 @@ public class SystemConfig {
}
XmlUtils.skipCurrentTag(parser);
} break;
+ case "allowed-partner-apex": {
+ // TODO(b/189274479): should this be allowOemPermissions instead?
+ if (allowAppConfigs) {
+ String pkgName = parser.getAttributeValue(null, "package");
+ if (pkgName == null) {
+ Slog.w(TAG, "<" + name + "> without package in " + permFile
+ + " at " + parser.getPositionDescription());
+ } else {
+ mAllowedPartnerApexes.add(pkgName);
+ }
+ } else {
+ logNotAllowedInPartition(name, permFile, parser);
+ }
+ XmlUtils.skipCurrentTag(parser);
+ } break;
default: {
Slog.w(TAG, "Tag " + name + " is unknown in "
+ permFile + " at " + parser.getPositionDescription());
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index d528428a0e83..e9e79dc30c20 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1775,6 +1775,16 @@ static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
return static_cast<jint>(SurfaceComposerClient::getGPUContextPriority());
}
+static void nativeSetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl,
+ jint transformHint) {
+ sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl*>(nativeSurfaceControl));
+ if (surface == nullptr) {
+ return;
+ }
+ surface->setTransformHint(
+ ui::Transform::toRotationFlags(static_cast<ui::Rotation>(transformHint)));
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1962,6 +1972,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeCreateJankDataListenerWrapper },
{"nativeGetGPUContextPriority", "()I",
(void*)nativeGetGPUContextPriority },
+ {"nativeSetTransformHint", "(JI)V",
+ (void*)nativeSetTransformHint },
// clang-format on
};
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 803ba649bd29..cd893185b4f6 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukke is geregistreer nie."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index e5ef55a2459b..b261c461cd5e 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 86a09ee9643b..b38bf9f93d73 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -613,6 +613,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 5b2149e92b83..846fb2c31d1f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 54dc9322417e..6b4736f71696 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
@@ -1624,7 +1626,7 @@
<string name="wireless_display_route_description" msgid="8297563323032966831">"Simsiz ekran"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"İştirakçılar"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"Cihaza qoş"</string>
- <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Ekranı cihaza yayımla"</string>
+ <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Ekran yayımı"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Cihazlar axtarılır..."</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Ayarlar"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"Əlaqəni kəsin"</string>
@@ -1695,15 +1697,15 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DEAKTİV"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> xidmətinin cihaza tam nəzarət etməsinə icazə verilsin?"</string>
<string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> aktiv olarsa, cihazınız data şifrələnməsini genişləndirmək üçün ekran kilidini istifadə etməyəcək."</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Tam nəzarət əlçatımlılıq ehtiyaclarınızı ödəyən bəzi tətbiqlər üçün uyğundur."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Tam nəzarət icazəsi xüsusi imkanlara dair yardım edən tətbiqlərə lazımdır, digər tətbiqlərə lazım deyil."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Baxış və nəzarət ekranı"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ekrandakı bütün kontenti oxuya və kontenti digər tətbiqlərin üzərində göstərə bilər."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Əməliyyatlara baxın və icra edin"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"O, tətbiq və ya avadanlıq sensoru ilə interaktivliyinizi izləyir və əvəzinizdən tətbiqlərlə qarşılıqlı əlaqəyə girir."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Tətbiq və sensorlarla əlaqələrinizi izləyib tətbiqlərə adınızdan əmrlər verə bilər."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"İcazə verin"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"İmtina edin"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Funksiyanı istifadə etmək üçün onun üzərinə toxunun:"</string>
- <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Əlçatımlılıq düyməsi ilə istifadə edəcəyiniz funksiyaları seçin"</string>
+ <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Xüsusi imkanlar düyməsinin köməyilə işə salınacaq funksiyaları seçin"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Səs səviyyəsi düyməsinin qısayolu ilə istifadə edəcəyiniz funksiyaları seçin"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> deaktiv edilib"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Qısayolları redaktə edin"</string>
@@ -1720,7 +1722,7 @@
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Xüsusi imkanlar düyməsinə toxunanda istədiyiniz funksiyanı seçin:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Əlçatımlılıq jesti (iki barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Əlçatımlılıq jesti (üç barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funksiyalar arasında keçid etmək üçün əlçatımlılıq düyməsinə toxunub saxlayın."</string>
+ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funksiyalar arasında keçid etmək üçün xüsusi imkanlar düyməsini basıb saxlayın."</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funksiyalar arasında keçid etmək üçün iki barmağınızla yuxarı sürüşdürüb saxlayın."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funksiyalar arasında keçid etmək üçün üç barmağınızla yuxarı doğru sürüşdürüb saxlayın."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Böyütmə"</string>
@@ -2137,7 +2139,7 @@
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Sürətli Ayarlar"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Yandırıb-söndürmə dialoqu"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilid Ekranı"</string>
- <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran şəkli"</string>
+ <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skrinşot"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Ekranda Əlçatımlılıq Qısayolu"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda Əlçatımlılıq Qısayolu Seçicisi"</string>
<string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Əlçatımlılıq Qısayolu"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ff2289f192bf..5fcd2df25a78 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -604,6 +604,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index b6ba47a47b1c..1af3ddd3b7fc 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9ab5dfec650a..b3722abd908b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Няма регистрирани отпечатъци."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 2a9ecf66d4e9..69ddbb4f1f46 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনও আঙ্গুলের ছাপ নথিভুক্ত করা হয়নি।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"আঙ্গুলের ছাপ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
@@ -1458,10 +1460,8 @@
<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="permlab_queryAllPackages" msgid="2928450604653281650">"অন্যান্য সব প্যাকেজের তথ্য সম্পর্কিত কোয়েরি দেখুন"</string>
+ <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"এটি কোনও অ্যাপকে সর্বদা ইনস্টল করা সব প্যাকেজ দেখতে অনুমতি দেয়।"</string>
<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-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 2d7003b6e4ab..74da24a6bfc4 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -604,6 +604,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije prijavljen nijedan otisak prsta."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 330713d9a6b9..03e7ef2e904b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No s\'ha registrat cap empremta digital."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c4eb66ea1a3b..bfd56343d674 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nejsou zaregistrovány žádné otisky prstů."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 270848758947..4231048bccea 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Der er ikke registreret nogen fingeraftryk."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 03b9904658d4..7a75eea2181c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index fce9d98005c8..523cde133638 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Δεν έχουν καταχωριστεί δακτυλικά αποτυπώματα."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 805f344ed20b..b2eaab053b46 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 86ddb1f7cb72..0a257f429b76 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index da1c49a93603..5eca8a68a12f 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index eeedf2109517..74d32d4a1075 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 5a2d3f340cd1..385608faaf28 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -601,6 +601,7 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎No fingerprints enrolled.‎‏‎‎‏‎"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎This device does not have a fingerprint sensor.‎‏‎‎‏‎"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
+ <string name="fingerprint_error_bad_calibration" msgid="374406495079531135">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎Sensor needs calibration‎‏‎‎‏‎"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎Finger ‎‏‎‎‏‏‎<xliff:g id="FINGERID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎Use fingerprint‎‏‎‎‏‎"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎Use fingerprint or screen lock‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index d3614f1b6df9..fafb766c0dba 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se registraron huellas digitales."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 72571596b524..3468da5db15a 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se ha registrado ninguna huella digital."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 1ae8730a90e4..0a60d66cd2e2 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ühtegi sõrmejälge pole registreeritud."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index de6e5e769e56..e36cc324aed9 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index cc2223cacbb6..add623a593f9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"اثر انگشتی ثبت نشده است."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1b28ca1e5f05..5b4caa7b71fe 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Sormenjälkiä ei ole otettu käyttöön."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index fa3737843761..29c9698479fa 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser l\'empreinte digitale ou le verrouillage de l\'écran"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 0ee3c889fdb2..23e599e1d948 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 5e10fdb8eb45..70f703a34648 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Non se rexistraron impresións dixitais."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 4157e1fd32eb..4d27b1086f61 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"કોઈ ફિંગરપ્રિન્ટની નોંધણી કરવામાં આવી નથી."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
@@ -1458,10 +1460,8 @@
<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="permlab_queryAllPackages" msgid="2928450604653281650">"બધા પૅકેજ જુઓ"</string>
+ <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"કોઈ ઍપને ઇન્સ્ટૉલ કરેલા બધા પૅકેજ જોવાની મંજૂરી આપે છે."</string>
<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 8fe4ebfee33e..74f4f4612d24 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 630ba2bece23..13a7c450f6d3 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -604,6 +604,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registriran nijedan otisak prsta."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f945d395a6e5..a478e6763a41 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nincsenek regisztrált ujjlenyomatok."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index d3057ca30809..e42eccb58cb6 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Գրանցված մատնահետք չկա:"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index abe36081900e..f50c4707f02a 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tidak ada sidik jari yang terdaftar."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 6be07b0056b0..bfc747668692 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Engin fingraför hafa verið skráð."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index d4f2fdb08395..708841dafac8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nessuna impronta digitale registrata."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7c9d97ecdd76..fabffbf34abf 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 39681875a345..e275df037597 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index e941b5e48806..bd85e614ce07 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 1324d2d4ce60..16da28fc28d9 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index df0b08299bb1..e72db139ae61 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"មិន​មាន​ការ​ចុះឈ្មោះស្នាម​ម្រាមដៃទេ។"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index a8e5b6403a4d..8858d0b8896d 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index cf9ade76183c..e9d0fc5a3326 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"등록된 지문이 없습니다."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 5479f119c2ba..c1961db3c757 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index ee2f058393df..65643c35bd8f 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ບໍ່ມີການລົງທະບຽນລາຍນິ້ວມື."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8ebb09ede62c..9849124541bd 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neužregistruota jokių kontrolinių kodų."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9b86c4d7fc7f..8407622b0614 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -604,6 +604,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nav reģistrēts neviens pirksta nospiedums."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index d0e11f1e8039..42a55c20a190 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Не се запишани отпечатоци."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 22fac7ed594f..f4a79e317e0c 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"വിരലടയാളങ്ങൾ എൻറോൾ ചെയ്തിട്ടില്ല."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ഫിംഗർ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 1060f64fdb1c..7d0a64345db5 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бүртгүүлсэн хурууны хээ алга."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index bf5f8e7a827e..3933bf358d8f 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोणत्याही फिंगरप्रिंटची नोंद झाली नाही"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिंट वापरा"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिंट किंवा स्क्रीन लॉक वापरा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index ccc0828daafb..2ad6baf06138 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tiada cap jari didaftarkan."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 7797e0875c2e..3543be0fb9e4 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"မည်သည့် လက်ဗွေကိုမျှ ထည့်သွင်းမထားပါ။"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 395dc1da2f03..9ed34e026e80 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 130adcdcf6c9..25f59c27e077 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 9449ac1cfb91..307c125c41ca 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukken geregistreerd."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor staat tijdelijk uit."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index b609827b9918..1e6eb37d0132 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2efcc76bae52..fbccb257569e 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ਕੋਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਰਜ ਨਹੀਂ ਕੀਤੇ ਗਏ।"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਜਾਂ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 49890fc64d27..0671787fc470 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nie zarejestrowano odcisków palców."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f4c0cdbcd2aa..8c6b146c408e 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f1c847647ae6..0fa0e50de0cb 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registada."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f4c0cdbcd2aa..8c6b146c408e 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c50f2e3a99c0..7bbf3e1dd913 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -604,6 +604,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index dde5ebc88d59..ebe46e8124e5 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Нет отсканированных отпечатков пальцев"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 13df5e2db962..eea259472033 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ඇඟිලි සලකුණු ඇතුළත් කර නොමැත."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4f8329a5e985..234e3a86f54f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index fb6fc9ae4b16..19c443444d89 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ni registriranih prstnih odtisov."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 646cc854a631..7934473206b5 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 98ddb39e1680..a0ae389e428b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -604,6 +604,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f155f3cd0c36..34d5e2c08ff7 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Inga fingeravtryck har registrerats."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 8ca0ac0f1aa1..cc8d644ebc0c 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hakuna alama za vidole zilizojumuishwa."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 4a50960dd1e9..0d2815164b81 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index d910224af035..936b758a1db5 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"వేలిముద్రలు నమోదు చేయబడలేదు."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
@@ -1458,10 +1460,8 @@
<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="permlab_queryAllPackages" msgid="2928450604653281650">"అన్ని ప్యాకేజీలను క్వెరీ చేయండి"</string>
+ <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ఇన్‌స్టాల్ చేసిన అన్ని ప్యాకేజీలను చూడటానికి యాప్‌ను అనుమతించండి."</string>
<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-th/strings.xml b/core/res/res/values-th/strings.xml
index 3f9ae3af84ea..9b2966f8586b 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index edc7427cfdc5..a34ac289dab9 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Walang naka-enroll na fingerprint."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e5f9fe99de82..a08dcb23a6fc 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Parmak izi kaydedilmedi."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 964c07719f4e..8be7da682be7 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -607,6 +607,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Відбитки пальців не зареєстровано."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або дані для розблокування екрана"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 7f5046b77277..e0344e05a756 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index d8769b24eca4..25a6a1aed415 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index b276ff15552b..a5cfbaf9a3d9 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Chưa đăng ký vân tay."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b745661b42c7..23832eb16ab6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index fd0bd9f1be77..0b59e5255baa 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 310663f005d6..8f81d83a46e5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未登錄任何指紋。"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ae01829085f3..c5c781840ce5 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -601,6 +601,8 @@
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Azikho izigxivizo zeminwe ezibhalisiwe."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
+ <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) -->
+ <skip />
<string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3c47366a59db..f4aff9467cee 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3350,6 +3350,10 @@
<!-- The default vibration strength, must be between 1 and 255 inclusive. -->
<integer name="config_defaultVibrationAmplitude">255</integer>
+ <!-- The max vibration strength allowed in audio haptic channels, must be positive or zero if
+ limit is unknown. -->
+ <item name="config_hapticChannelMaxVibrationAmplitude" format="float" type="dimen">0</item>
+
<!-- If the device should still vibrate even in low power mode, for certain priority vibrations
(e.g. accessibility, alarms). This is mainly for Wear devices that don't have speakers. -->
<bool name="config_allowPriorityVibrationsInLowPowerMode">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bdeff89352ea..302bd94c1973 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1603,6 +1603,8 @@
<string name="fingerprint_acquired_too_bright">Too bright</string>
<!-- Message shown during fingerprint acquisition when a fingerprint must be adjusted.[CHAR LIMIT=50] -->
<string name="fingerprint_acquired_try_adjusting">Try adjusting</string>
+ <!-- Message shown during fingerprint acquisition when a fingeprint area has already been captured during enrollment [CHAR LIMIT=100] -->
+ <string name="fingerprint_acquired_immobile">Change the position of your finger slightly each time</string>
<!-- Array containing custom messages shown during fingerprint acquisision from vendor. Vendor is expected to add and translate these strings -->
<string-array name="fingerprint_acquired_vendor">
</string-array>
@@ -1636,6 +1638,8 @@
<string name="fingerprint_error_hw_not_present">This device does not have a fingerprint sensor.</string>
<!-- Generic error message shown when fingerprint is not available due to a security vulnerability. [CHAR LIMIT=50] -->
<string name="fingerprint_error_security_update_required">Sensor temporarily disabled.</string>
+ <!-- Generic error message shown when fingerprint needs calibration [CHAR LIMIT=50] -->
+ <string name="fingerprint_error_bad_calibration">Sensor needs calibration</string>
<!-- Template to be used to name enrolled fingerprints by default. -->
<string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 97a2a38bdab8..5f849b4e1eb0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2013,6 +2013,7 @@
<java-symbol type="integer" name="config_notificationServiceArchiveSize" />
<java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
<java-symbol type="integer" name="config_defaultVibrationAmplitude" />
+ <java-symbol type="dimen" name="config_hapticChannelMaxVibrationAmplitude" />
<java-symbol type="integer" name="config_vibrationWaveformRampStepDuration" />
<java-symbol type="integer" name="config_vibrationWaveformRampDownDuration" />
<java-symbol type="integer" name="config_radioScanningTimeout" />
@@ -2537,6 +2538,8 @@
<java-symbol type="string" name="fingerprint_error_no_fingerprints" />
<java-symbol type="string" name="fingerprint_error_hw_not_present" />
<java-symbol type="string" name="fingerprint_error_security_update_required" />
+ <java-symbol type="string" name="fingerprint_error_bad_calibration" />
+ <java-symbol type="string" name="fingerprint_acquired_immobile" />
<!-- Fingerprint config -->
<java-symbol type="integer" name="config_fingerprintMaxTemplatesPerUser"/>
diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
new file mode 100644
index 000000000000..8c05978ad03c
--- /dev/null
+++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Test for verifying the behavior of {@link PropertyInvalidatedCache}. This test does
+ * not use any actual binder calls - it is entirely self-contained.
+ * <p>
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:PropertyInvalidatedCacheTests
+ */
+@SmallTest
+public class PropertyInvalidatedCacheTests {
+
+ static final String CACHE_PROPERTY = "cache_key.cache_test_a";
+
+ // This class is a proxy for binder calls. It contains a counter that increments
+ // every time the class is queried.
+ private static class ServerProxy {
+ // The number of times this class was queried.
+ private int mCount = 0;
+
+ // A single query. The key behavior is that the query count is incremented.
+ boolean query(int x) {
+ mCount++;
+ return value(x);
+ }
+
+ // Return the expected value of an input, without incrementing the query count.
+ boolean value(int x) {
+ return x % 3 == 0;
+ }
+
+ // Verify the count.
+ void verify(int x) {
+ assertEquals(x, mCount);
+ }
+ }
+
+ @Test
+ public void testDisableCache1() {
+
+ // A stand-in for the binder. The test verifies that calls are passed through to
+ // this class properly.
+ ServerProxy tester = new ServerProxy();
+
+ // Three caches, all using the same system property but one uses a different name.
+ PropertyInvalidatedCache<Integer, Boolean> cache1 =
+ new PropertyInvalidatedCache<>(4, CACHE_PROPERTY) {
+ @Override
+ protected Boolean recompute(Integer x) {
+ return tester.query(x);
+ }
+ };
+ PropertyInvalidatedCache<Integer, Boolean> cache2 =
+ new PropertyInvalidatedCache<>(4, CACHE_PROPERTY) {
+ @Override
+ protected Boolean recompute(Integer x) {
+ return tester.query(x);
+ }
+ };
+ PropertyInvalidatedCache<Integer, Boolean> cache3 =
+ new PropertyInvalidatedCache<>(4, CACHE_PROPERTY, "cache3") {
+ @Override
+ protected Boolean recompute(Integer x) {
+ return tester.query(x);
+ }
+ };
+
+ // Caches are enabled upon creation.
+ assertEquals(false, cache1.getDisabledState());
+ assertEquals(false, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Disable the cache1 instance. Only cache1 is disabled
+ cache1.disableInstance();
+ assertEquals(true, cache1.getDisabledState());
+ assertEquals(false, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Disable cache1. This will disable cache1 and cache2 because they share the
+ // same name. cache3 has a different name and will not be disabled.
+ cache1.disableLocal();
+ assertEquals(true, cache1.getDisabledState());
+ assertEquals(true, cache2.getDisabledState());
+ assertEquals(false, cache3.getDisabledState());
+
+ // Create a new cache1. Verify that the new instance is disabled.
+ cache1 = new PropertyInvalidatedCache<>(4, CACHE_PROPERTY) {
+ @Override
+ protected Boolean recompute(Integer x) {
+ return tester.query(x);
+ }
+ };
+ assertEquals(true, cache1.getDisabledState());
+ }
+}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java
index de0670b08ffd..228a061ae3c8 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchResultTest.java
@@ -18,7 +18,7 @@ package android.app.appsearch;
import static com.google.common.truth.Truth.assertThat;
-import static org.testng.Assert.expectThrows;
+import static org.junit.Assert.assertThrows;
import org.junit.Test;
@@ -26,7 +26,7 @@ public class AppSearchResultTest {
@Test
public void testMapNullPointerException() {
NullPointerException e =
- expectThrows(
+ assertThrows(
NullPointerException.class,
() -> {
Object o = null;
diff --git a/core/tests/coretests/src/android/os/VibratorInfoTest.java b/core/tests/coretests/src/android/os/VibratorInfoTest.java
index 8c7d10c7a5ef..6e07fa264c1c 100644
--- a/core/tests/coretests/src/android/os/VibratorInfoTest.java
+++ b/core/tests/coretests/src/android/os/VibratorInfoTest.java
@@ -87,14 +87,14 @@ public class VibratorInfoTest {
public void testIsPrimitiveSupported() {
VibratorInfo info = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
- .setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK)
+ .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
.build();
assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_TICK));
// Returns false when there is no compose capability.
info = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
- .setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK)
+ .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
.build();
assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
}
@@ -103,8 +103,7 @@ public class VibratorInfoTest {
public void testGetPrimitiveDuration() {
VibratorInfo info = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
- .setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK)
- .setPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+ .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
.build();
assertEquals(20, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_TICK));
@@ -113,6 +112,26 @@ public class VibratorInfoTest {
}
@Test
+ public void testCompositionLimits() {
+ VibratorInfo info = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
+ .setPrimitiveDelayMax(100)
+ .setCompositionSizeMax(10)
+ .setPwlePrimitiveDurationMax(50)
+ .setPwleSizeMax(20)
+ .build();
+ assertEquals(100, info.getPrimitiveDelayMax());
+ assertEquals(10, info.getCompositionSizeMax());
+ assertEquals(50, info.getPwlePrimitiveDurationMax());
+ assertEquals(20, info.getPwleSizeMax());
+
+ VibratorInfo emptyInfo = new VibratorInfo.Builder(TEST_VIBRATOR_ID).build();
+ assertEquals(0, emptyInfo.getPrimitiveDelayMax());
+ assertEquals(0, emptyInfo.getCompositionSizeMax());
+ assertEquals(0, emptyInfo.getPwlePrimitiveDurationMax());
+ assertEquals(0, emptyInfo.getPwleSizeMax());
+ }
+
+ @Test
public void testGetDefaultBraking_returnsFirstSupportedBraking() {
assertEquals(Braking.NONE, new VibratorInfo.Builder(
TEST_VIBRATOR_ID).build().getDefaultBraking());
@@ -263,8 +282,12 @@ public class VibratorInfoTest {
VibratorInfo.Builder completeBuilder = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
.setSupportedEffects(VibrationEffect.EFFECT_CLICK)
- .setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK)
- .setPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+ .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+ .setPrimitiveDelayMax(100)
+ .setCompositionSizeMax(10)
+ .setSupportedBraking(Braking.CLAB)
+ .setPwlePrimitiveDurationMax(50)
+ .setPwleSizeMax(20)
.setQFactor(2f)
.setFrequencyMapping(TEST_FREQUENCY_MAPPING);
VibratorInfo complete = completeBuilder.build();
@@ -279,8 +302,7 @@ public class VibratorInfoTest {
assertNotEquals(complete, completeWithComposeControl);
VibratorInfo completeWithNoEffects = completeBuilder
- .setSupportedEffects()
- .setSupportedPrimitives()
+ .setSupportedEffects(new int[0])
.build();
assertNotEquals(complete, completeWithNoEffects);
@@ -289,13 +311,8 @@ public class VibratorInfoTest {
.build();
assertNotEquals(complete, completeWithUnknownEffects);
- VibratorInfo completeWithUnknownPrimitives = completeBuilder
- .setSupportedPrimitives(null)
- .build();
- assertNotEquals(complete, completeWithUnknownPrimitives);
-
VibratorInfo completeWithDifferentPrimitiveDuration = completeBuilder
- .setPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+ .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
.build();
assertNotEquals(complete, completeWithDifferentPrimitiveDuration);
@@ -321,12 +338,17 @@ public class VibratorInfoTest {
.build();
assertNotEquals(complete, completeWithDifferentQFactor);
- VibratorInfo empty = new VibratorInfo.Builder(TEST_VIBRATOR_ID).build();
- VibratorInfo emptyWithKnownSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
- .setSupportedEffects()
- .setSupportedPrimitives()
+ VibratorInfo unknownEffectSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID).build();
+ VibratorInfo knownEmptyEffectSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
+ .setSupportedEffects(new int[0])
+ .build();
+ assertNotEquals(unknownEffectSupport, knownEmptyEffectSupport);
+
+ VibratorInfo unknownBrakingSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID).build();
+ VibratorInfo knownEmptyBrakingSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
+ .setSupportedBraking(new int[0])
.build();
- assertNotEquals(empty, emptyWithKnownSupport);
+ assertNotEquals(unknownBrakingSupport, knownEmptyBrakingSupport);
}
@Test
@@ -334,8 +356,7 @@ public class VibratorInfoTest {
VibratorInfo original = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
.setSupportedEffects(VibrationEffect.EFFECT_CLICK)
- .setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK)
- .setPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+ .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
.setQFactor(Float.NaN)
.setFrequencyMapping(TEST_FREQUENCY_MAPPING)
.build();
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 3e620c2bbec6..fedbf7a9868e 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -24,6 +24,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
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;
@@ -47,7 +49,9 @@ import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -64,13 +68,15 @@ public class BatteryUsageStatsTest {
}
@Test
- public void testParcelability() {
+ public void testParcelability_smallNumberOfUids() {
final BatteryUsageStats outBatteryUsageStats = buildBatteryUsageStats1(true).build();
final Parcel outParcel = Parcel.obtain();
outParcel.writeParcelable(outBatteryUsageStats, 0);
final byte[] bytes = outParcel.marshall();
outParcel.recycle();
+ assertThat(bytes.length).isLessThan(2000);
+
final Parcel inParcel = Parcel.obtain();
inParcel.unmarshall(bytes, 0, bytes.length);
inParcel.setDataPosition(0);
@@ -80,6 +86,46 @@ public class BatteryUsageStatsTest {
assertBatteryUsageStats1(inBatteryUsageStats, true);
}
+ @Test
+ public void testParcelability_largeNumberOfUids() {
+ final BatteryUsageStats.Builder builder =
+ new BatteryUsageStats.Builder(new String[0]);
+
+ // Without the use of a blob, this BatteryUsageStats object would generate a Parcel
+ // larger than 64 Kb
+ final int uidCount = 200;
+ for (int i = 0; i < uidCount; i++) {
+ BatteryStatsImpl.Uid mockUid = mock(BatteryStatsImpl.Uid.class);
+ when(mockUid.getUid()).thenReturn(i);
+ builder.getOrCreateUidBatteryConsumerBuilder(mockUid)
+ .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, i * 100);
+ }
+
+ BatteryUsageStats outBatteryUsageStats = builder.build();
+
+ final Parcel parcel = Parcel.obtain();
+ parcel.writeParcelable(outBatteryUsageStats, 0);
+
+ assertThat(parcel.dataSize()).isLessThan(2000);
+
+ // This parcel cannot be marshaled because it contains a file descriptor.
+ // Assuming that parcel marshaling works fine, let's just rewind the parcel.
+ parcel.setDataPosition(0);
+
+ final BatteryUsageStats inBatteryUsageStats =
+ parcel.readParcelable(getClass().getClassLoader());
+ parcel.recycle();
+
+ assertThat(inBatteryUsageStats.getUidBatteryConsumers()).hasSize(uidCount);
+ final Map<Integer, UidBatteryConsumer> consumersByUid =
+ inBatteryUsageStats.getUidBatteryConsumers().stream().collect(
+ Collectors.toMap(UidBatteryConsumer::getUid, c -> c));
+ for (int i = 0; i < uidCount; i++) {
+ final UidBatteryConsumer uidBatteryConsumer = consumersByUid.get(i);
+ assertThat(uidBatteryConsumer).isNotNull();
+ assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(i * 100);
+ }
+ }
@Test
public void testDefaultSessionDuration() {
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 a525c2c0219c..3253bb06c835 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
@@ -87,4 +87,9 @@ public interface OneHanded {
* Notifies when user switch complete
*/
void onUserSwitch(int userId);
+
+ /**
+ * Notifies when keyguard visibility changed
+ */
+ void onKeyguardVisibilityChanged(boolean showing);
}
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 b43daa0da2c0..b5c54023c492 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
@@ -81,6 +81,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private volatile boolean mIsSwipeToNotificationEnabled;
private boolean mTaskChangeToExit;
private boolean mLockedDisabled;
+ private boolean mKeyguardShowing;
private int mUserId;
private float mOffSetFraction;
@@ -357,7 +358,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
@VisibleForTesting
void startOneHanded() {
- if (isLockedDisabled()) {
+ if (isLockedDisabled() || mKeyguardShowing) {
Slog.d(TAG, "Temporary lock disabled");
return;
}
@@ -481,7 +482,9 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
@VisibleForTesting
void notifyExpandNotification() {
- mMainExecutor.execute(() -> mEventCallback.notifyExpandNotification());
+ if (mEventCallback != null) {
+ mMainExecutor.execute(() -> mEventCallback.notifyExpandNotification());
+ }
}
@VisibleForTesting
@@ -692,6 +695,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mTutorialHandler.onConfigurationChanged();
}
+ private void onKeyguardVisibilityChanged(boolean showing) {
+ mKeyguardShowing = showing;
+ }
+
private void onUserSwitch(int newUserId) {
unregisterSettingObservers();
mUserId = newUserId;
@@ -838,6 +845,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
OneHandedController.this.onUserSwitch(userId);
});
}
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ mMainExecutor.execute(() -> {
+ OneHandedController.this.onKeyguardVisibilityChanged(showing);
+ });
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
index 1a365fee3b13..9986154b051d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java
@@ -235,7 +235,8 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
}
void onAnimationProgress(float linearProgress) {
- if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()) {
+ if (mFirstWindowSurface == null || !mFirstWindowSurface.isValid()
+ || !mSplashScreenView.isAttachedToWindow()) {
return;
}
@@ -267,15 +268,20 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
return;
}
final SurfaceControl.Transaction tx = mTransactionPool.acquire();
- tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
-
- SyncRtSurfaceTransactionApplier.SurfaceParams
- params = new SyncRtSurfaceTransactionApplier.SurfaceParams
- .Builder(mFirstWindowSurface)
- .withWindowCrop(null)
- .withMergeTransaction(tx)
- .build();
- mApplier.scheduleApply(params);
+ if (mSplashScreenView.isAttachedToWindow()) {
+ tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
+
+ SyncRtSurfaceTransactionApplier.SurfaceParams
+ params = new SyncRtSurfaceTransactionApplier.SurfaceParams
+ .Builder(mFirstWindowSurface)
+ .withWindowCrop(null)
+ .withMergeTransaction(tx)
+ .build();
+ mApplier.scheduleApply(params);
+ } else {
+ tx.setWindowCrop(mFirstWindowSurface, null);
+ tx.apply();
+ }
mTransactionPool.release(tx);
Choreographer.getSfInstance().postCallback(CALLBACK_COMMIT,
@@ -287,13 +293,14 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener {
if (DEBUG_EXIT_ANIMATION) {
Slog.v(TAG, "vanish animation finished");
}
- mSplashScreenView.post(() -> {
+
+ if (mSplashScreenView.isAttachedToWindow()) {
mSplashScreenView.setVisibility(GONE);
if (mFinishCallback != null) {
mFinishCallback.run();
mFinishCallback = null;
}
- });
+ }
if (mShiftUpAnimation != null) {
mShiftUpAnimation.finish();
}
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 47789b7490ee..950900337918 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
@@ -435,4 +435,17 @@ public class OneHandedControllerTest extends OneHandedTestCase {
verify(mSpiedOneHandedController).notifyShortcutState(anyInt());
}
+
+ @Test
+ public void testNotifyExpandNotification_withNullCheckProtection() {
+ when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
+ when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
+ when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
+ when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
+ mSpiedOneHandedController.setOneHandedEnabled(true);
+ mSpiedOneHandedController.notifyExpandNotification();
+
+ // Verify no NPE crash and mMockShellMainExecutor never be execute.
+ verify(mMockShellMainExecutor, never()).execute(any());
+ }
}
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 4cd3616566c2..ecdd4b616e0f 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -214,6 +214,25 @@ public final class GnssMeasurement implements Parcelable {
*
* <p> When this bit is unset, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
* carrier phase measurement plus an accumulated integer number of carrier half cycles.
+ *
+ * <p> For signals that have databits, the carrier phase tracking loops typically use a costas
+ * loop discriminator. This type of tracking loop introduces a half-cycle ambiguity that is
+ * resolved by searching through the received data for known patterns of databits (e.g. GPS uses
+ * the TLM word) which then determines the polarity of the incoming data and resolves the
+ * half-cycle ambiguity.
+ *
+ * <p>Before the half-cycle ambiguity has been resolved it is possible that the ADR_STATE_VALID
+ * flag is set:
+ *
+ * <ul>
+ * <li> In cases where ADR_STATE_HALF_CYCLE_REPORTED is not set, the
+ * ADR_STATE_HALF_CYCLE_RESOLVED flag will not be available. Here, a half wave length will be
+ * added to the returned accumulated delta range uncertainty to indicate the half cycle
+ * ambiguity.
+ * <li> In cases where ADR_STATE_HALF_CYCLE_REPORTED is set, half cycle ambiguity will be
+ * indicated via both the ADR_STATE_HALF_CYCLE_RESOLVED flag and as well a half wave length
+ * added to the returned accumulated delta range uncertainty.
+ * </ul>
*/
public static final int ADR_STATE_HALF_CYCLE_RESOLVED = (1<<3);
@@ -1039,9 +1058,6 @@ public final class GnssMeasurement implements Parcelable {
* with integer ambiguity resolution, to determine highly precise relative location between
* receivers.
*
- * <p>This includes ensuring that all half-cycle ambiguities are resolved before this value is
- * reported as {@link #ADR_STATE_VALID}.
- *
* <p>The alignment of the phase measurement will not be adjusted by the receiver so the
* in-phase and quadrature phase components will have a quarter cycle offset as they do when
* transmitted from the satellites. If the measurement is from a combination of the in-phase
diff --git a/obex/javax/obex/ObexHelper.java b/obex/javax/obex/ObexHelper.java
index 478297f2a3c9..843793ad98f8 100644
--- a/obex/javax/obex/ObexHelper.java
+++ b/obex/javax/obex/ObexHelper.java
@@ -34,6 +34,8 @@
package javax.obex;
+import android.util.Log;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -43,7 +45,6 @@ import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
-import android.util.Log;
/**
* This class defines a set of helper methods for the implementation of Obex.
@@ -1083,11 +1084,12 @@ public final class ObexHelper {
}
private static int validateMaxPacketSize(int size) {
- if(VDBG && (size > MAX_PACKET_SIZE_INT)) Log.w(TAG,
- "The packet size supported for the connection (" + size + ") is larger"
- + " than the configured OBEX packet size: " + MAX_PACKET_SIZE_INT);
- if(size != -1) {
- if(size < LOWER_LIMIT_MAX_PACKET_SIZE) {
+ if (VDBG && (size > MAX_PACKET_SIZE_INT)) {
+ Log.w(TAG, "The packet size supported for the connection (" + size + ") is larger"
+ + " than the configured OBEX packet size: " + MAX_PACKET_SIZE_INT);
+ }
+ if (size != -1 && size < MAX_PACKET_SIZE_INT) {
+ if (size < LOWER_LIMIT_MAX_PACKET_SIZE) {
throw new IllegalArgumentException(size + " is less that the lower limit: "
+ LOWER_LIMIT_MAX_PACKET_SIZE);
}
diff --git a/obex/javax/obex/ObexTransport.java b/obex/javax/obex/ObexTransport.java
index a5a75f55f553..4cef0b33df4f 100644
--- a/obex/javax/obex/ObexTransport.java
+++ b/obex/javax/obex/ObexTransport.java
@@ -81,6 +81,8 @@ public interface ObexTransport {
* size. Therefore this value shall not change.
* For RFCOMM or other transport types where the OBEX packets size
* is unrelated to the transport packet size, return -1;
+ * Exception can be made (like PBAP transport) with a smaller value
+ * to avoid bad effect on other profiles using the RFCOMM;
* @return the maximum allowed OBEX packet that can be send over
* the transport. Or -1 in case of don't care.
*/
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 42c1997b41a3..bfc00bb8b94d 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -52,6 +52,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.Arrays;
+import java.util.NoSuchElementException;
public final class RemotePrintDocument {
private static final String LOG_TAG = "RemotePrintDocument";
@@ -441,7 +442,12 @@ public final class RemotePrintDocument {
// Keep going - best effort...
}
- mPrintDocumentAdapter.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ try {
+ mPrintDocumentAdapter.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (NoSuchElementException e) {
+ Log.w(LOG_TAG, "Error unlinking print document adapter death recipient.");
+ // Keep going - best effort...
+ }
}
private void scheduleCommand(AsyncCommand command) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 59f272ff70f6..d25d5dcaac87 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -61,7 +61,6 @@ import android.print.PrinterId;
import android.print.PrinterInfo;
import android.printservice.PrintService;
import android.printservice.PrintServiceInfo;
-import android.provider.DocumentsContract;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index e6ca2e0d10c8..4ae120ae286d 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -23,8 +23,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.resources.TextAppearanceConfig;
@@ -35,6 +38,7 @@ import com.google.android.material.resources.TextAppearanceConfig;
public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
private CollapsingToolbarLayout mCollapsingToolbarLayout;
+ private AppBarLayout mAppBarLayout;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -43,6 +47,8 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
TextAppearanceConfig.setShouldLoadFontSynchronously(true);
super.setContentView(R.layout.collapsing_toolbar_base_layout);
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
+ mAppBarLayout = findViewById(R.id.app_bar);
+ disableCollapsingToolbarLayoutScrollingBehavior();
final Toolbar toolbar = findViewById(R.id.action_bar);
setActionBar(toolbar);
@@ -107,4 +113,18 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
public CollapsingToolbarLayout getCollapsingToolbarLayout() {
return mCollapsingToolbarLayout;
}
+
+ private void disableCollapsingToolbarLayoutScrollingBehavior() {
+ final CoordinatorLayout.LayoutParams params =
+ (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
+ final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
+ behavior.setDragCallback(
+ new AppBarLayout.Behavior.DragCallback() {
+ @Override
+ public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
+ return false;
+ }
+ });
+ params.setBehavior(behavior);
+ }
}
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
index 304c3439a60d..d993e4465343 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
@@ -22,6 +22,7 @@ import android.view.View;
import android.widget.AdapterView;
import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.widget.settingsspinner.SettingsSpinner;
@@ -31,12 +32,12 @@ import com.android.settingslib.widget.settingsspinner.SettingsSpinnerAdapter;
* This preference uses SettingsSpinner & SettingsSpinnerAdapter which provide default layouts for
* both view and drop down view of the Spinner.
*/
-public class SettingsSpinnerPreference extends Preference {
+public class SettingsSpinnerPreference extends Preference implements OnPreferenceClickListener {
private SettingsSpinnerAdapter mAdapter;
private AdapterView.OnItemSelectedListener mListener;
- private int mPosition; //Default 0 for internal shard storage.
- private boolean mIsClickable = true;
+ private int mPosition;
+ private boolean mShouldPerformClick;
/**
* Perform inflation from XML and apply a class-specific base style.
@@ -51,7 +52,7 @@ public class SettingsSpinnerPreference extends Preference {
public SettingsSpinnerPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setLayoutResource(R.layout.settings_spinner_preference);
- setSelectable(false);
+ setOnPreferenceClickListener(this);
}
/**
@@ -64,7 +65,7 @@ public class SettingsSpinnerPreference extends Preference {
public SettingsSpinnerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.settings_spinner_preference);
- setSelectable(false);
+ setOnPreferenceClickListener(this);
}
/**
@@ -76,6 +77,13 @@ public class SettingsSpinnerPreference extends Preference {
this(context, null);
}
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ mShouldPerformClick = true;
+ notifyChanged();
+ return true;
+ }
+
/** Sets adapter of the spinner. */
public <T extends SettingsSpinnerAdapter> void setAdapter(T adapter) {
mAdapter = adapter;
@@ -101,24 +109,19 @@ public class SettingsSpinnerPreference extends Preference {
notifyChanged();
}
- /** Set clickable of the spinner. */
- public void setClickable(boolean isClickable) {
- if (mIsClickable == isClickable) {
- return;
- }
- mIsClickable = isClickable;
- notifyChanged();
- }
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final SettingsSpinner spinner = (SettingsSpinner) holder.findViewById(R.id.spinner);
- spinner.setEnabled(mIsClickable);
- spinner.setClickable(mIsClickable);
spinner.setAdapter(mAdapter);
spinner.setSelection(mPosition);
spinner.setOnItemSelectedListener(mOnSelectedListener);
+ if (mShouldPerformClick) {
+ mShouldPerformClick = false;
+ // To show dropdown view.
+ spinner.performClick();
+ }
}
private final AdapterView.OnItemSelectedListener mOnSelectedListener =
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 89bb9e8bfe01..fa3f34c96ad2 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Bynaam"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Stel gassessie terug"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gas"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index bc1bd1633e4c..7b4c832fd1d0 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"እንግዳን ዳግም አስጀምር"</string>
<string name="guest_nickname" msgid="6332276931583337261">"እንግዳ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index f04aaac87b6d..611f2c44f565 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"উপনাম"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ কৰক"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"অতিথিৰ ছেশ্বন ৰিছেট কৰক"</string>
<string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b7cf11ae3754..c50a22d18605 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Ləqəb"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Qonaq əlavə edin"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Qonaq sessiyasını sıfırlayın"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Qonaq"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
@@ -576,7 +575,7 @@
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiv"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin."</string>
- <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Simli qulaqlıq"</string>
+ <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Naqilli qulaqlıq"</string>
<string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aktiv"</string>
<string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Deaktiv"</string>
<string name="carrier_network_change_mode" msgid="4257621815706644026">"Operator şəbəkəsinin dəyişilməsi"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 97c281ad2d67..e26d0650c8cc 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -567,8 +567,7 @@
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesiju gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 09e584318173..7899fa687ddc 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Нулиране на сесията като гост"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гост"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 88abe33d1f18..9eb20f90735f 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -567,8 +567,7 @@
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi sesiju gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index f499ab6cc7c0..d3590bf9e8d2 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Àlies"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Restableix el convidat"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidat"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 4d07eff0e858..5c664b987101 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Resetovat hosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Host"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 98f53011d2ca..59bfab8ddea8 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Επαναφορά περιόδου επισκέπτη"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Επισκέπτης"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 6ff48541e4e8..26c7b2c7a760 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Apodo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer invitado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invitado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index ef7b7db2bb9b..194aeaff4b15 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Lähtesta külastajaseanss"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Külaline"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 93506105d964..33e2314dd887 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -528,7 +528,7 @@
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
<string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
<string name="storage_category" msgid="2287342585424631813">"Biltegiratzea"</string>
- <string name="shared_data_title" msgid="1017034836800864953">"Partekatutako datuak"</string>
+ <string name="shared_data_title" msgid="1017034836800864953">"Datu partekatuak"</string>
<string name="shared_data_summary" msgid="5516326713822885652">"Ikusi eta aldatu partekatutako datuak"</string>
<string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Ez dago erabiltzaile honen datu partekaturik."</string>
<string name="shared_data_query_failure_text" msgid="3489828881998773687">"Errore bat gertatu da datu partekatuak eskuratzean. Saiatu berriro."</string>
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Goitizena"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatua"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Berrezarri gonbidatuentzako saioa"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gonbidatua"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 964162b34357..a11a00a5f65d 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Nollaa vieras"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Vieras"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 73f98ec23ccf..dba912ea3920 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Alcume"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer sesión de convidado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 5620d946b999..bc74092efa8d 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान हटाएं"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट करें"</string>
<string name="guest_nickname" msgid="6332276931583337261">"मेहमान"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 0ff35f890407..d18d34cb0037 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -567,8 +567,7 @@
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Uklanjanje gosta"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi gostujuću sesiju"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 9bd4d1263abd..3ad3590ca728 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Becenév"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Vendég munkamenet visszaállítása"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Vendég"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 662a67361b33..da92e7d4517f 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Endurstilla gestastillingu"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gestur"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 2c2d11fecda4..6f7565e3fb02 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Reimposta sessione Ospite"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Ospite"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index ddae3c72babb..70dd9e74929b 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Қонақ қосу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Қонақ сеансын әдепкі күйге қайтару"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Қонақ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index d970e9590c36..26595f5cc067 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"ឈ្មោះ​ហៅក្រៅ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូល​ភ្ញៀវ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"កំណត់​ភ្ញៀវឡើង​វិញ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ភ្ញៀវ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើស​រូបភាព"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 8bad32006594..b36ef8d2a2da 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"ಅಡ್ಡ ಹೆಸರು"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"ಅತಿಥಿಯನ್ನು ಮರುಹೊಂದಿಸಿ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ಅತಿಥಿ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3383602753f1..ad0ad1fb28bf 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Iš naujo nustatyti svečią"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Svečias"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index d655afc7ae35..586de6fcfdf7 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -567,8 +567,7 @@
<string name="user_nickname" msgid="262624187455825083">"Segvārds"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Atiestatīt viesa sesiju"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Viesis"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index bd7f074f01a0..0d0f345af7c3 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Прекар"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додајте гостин"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетирајте го гостинот"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гостин"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 1e80ccd0f3ab..655be1a74c31 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"വിളിപ്പേര്"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"അതിഥിയെ റീസെറ്റ് ചെയ്യുക"</string>
<string name="guest_nickname" msgid="6332276931583337261">"അതിഥി"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 40b65efe275e..07ed369b8d36 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Хоч"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Зочин нэмэх"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Зочныг шинэчлэх"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Зочин"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 6a46edee6ce5..fe8e8375a65a 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"अतिथी सेशन रीसेट करा"</string>
<string name="guest_nickname" msgid="6332276931583337261">"अतिथी"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 7156a8ef6548..b383ad84cadb 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည့် ထည့်ရန်"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်ရန်"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ဧည့်သည်"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index bb93a29feaa5..84c231faed46 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Legg til en gjest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Tilbakestill gjest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gjest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index a33bbf3e2dd9..1837eabf2370 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Gastsessie resetten"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gast"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 5f410a86691b..bd77d881560f 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesję gościa"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gość"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 3c8d928a7213..e39b58bb8344 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index fc98aa732606..a5c0d1d58d40 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Alcunha"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Repor convidado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 3c8d928a7213..e39b58bb8344 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4db2f315a452..e1b0390fbace 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -567,8 +567,7 @@
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adăugați un invitat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ștergeți invitatul"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Resetați sesiunea pentru invitați"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invitat"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 0bcdc230c089..1e5fce5f3bc9 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавить гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Сбросить гостевой сеанс"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гость"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index ef12ad36c5e1..09c0bf993f34 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Obnoviť reláciu hosťa"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Hosť"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index cbdfefcd424a..b698c19ff8b8 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodajanje gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranitev gosta"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Ponastavi gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 3859be937d47..b3c23b667a42 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -567,8 +567,7 @@
<string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетуј сесију госта"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гост"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 7dcca0d2b611..124c063bea95 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Återställ gästsession"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gäst"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b7aff721c405..7f67b88aa837 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -452,7 +452,7 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"อุปกรณ์อาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะเต็ม"</string>
+ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g>จึงจะเต็ม"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - อีก <xliff:g id="TIME">%2$s</xliff:g> จึงจะเต็ม"</string>
<string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - จำกัดการชาร์จชั่วคราว"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string>
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"ชื่อเล่น"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"เพิ่มผู้ใช้ชั่วคราว"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้ใช้ชั่วคราวออก"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"รีเซ็ตผู้เข้าร่วม"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ผู้ใช้ชั่วคราว"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6d1f6abbdf96..cc7db29f3d32 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Magdagdag ng bisita"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"I-reset ang bisita"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Bisita"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 82e481bd0613..2cb10763fcc9 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -568,8 +568,7 @@
<string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Скинути сеанс у режимі \"Гість\""</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гість"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 7f4e30aa33c4..3e11124597d9 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Nik"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Mehmon seansini tiklash"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Mehmon"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 2fe791a5a47c..0fa97e2011ce 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -566,8 +566,7 @@
<string name="user_nickname" msgid="262624187455825083">"Isiteketiso"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engeza isivakashi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string>
- <!-- no translation found for guest_reset_guest (6110013010356013758) -->
- <skip />
+ <string name="guest_reset_guest" msgid="6110013010356013758">"Setha kabusha isivakashi"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Isihambeli"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java
index b0c5314a2ec0..53a382a9ebf6 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java
@@ -89,24 +89,4 @@ public class SettingsSpinnerPreferenceTest {
assertThat(mSpinnerPreference.getSelectedItem())
.isEqualTo(mSpinner.getAdapter().getItem(1));
}
-
- @Test
- public void onBindViewHolder_setClickableTrue_isClickableTrue() {
- mSpinnerPreference.setClickable(true);
-
- mSpinnerPreference.onBindViewHolder(mViewHolder);
-
- assertThat(mSpinner.isClickable()).isTrue();
- assertThat(mSpinner.isEnabled()).isTrue();
- }
-
- @Test
- public void onBindViewHolder_setClickableFalse_isClickableFalse() {
- mSpinnerPreference.setClickable(false);
-
- mSpinnerPreference.onBindViewHolder(mViewHolder);
-
- assertThat(mSpinner.isClickable()).isFalse();
- assertThat(mSpinner.isEnabled()).isFalse();
- }
}
diff --git a/packages/SystemUI/docs/qs-tiles.md b/packages/SystemUI/docs/qs-tiles.md
index 89c28a074c76..efcb2de0f6c3 100644
--- a/packages/SystemUI/docs/qs-tiles.md
+++ b/packages/SystemUI/docs/qs-tiles.md
@@ -306,6 +306,7 @@ This section describes necessary and recommended steps when implementing a Quick
* Add a case to the `switch` with a unique String spec for the chosen tile.
5. In [SystemUI/res/values/config.xml](/packages/SystemUI/res/values/config.xml), modify `quick_settings_tiles_stock` and add the spec defined in the previous step. If necessary, add it also to `quick_settings_tiles_default`. The first one contains a list of all the tiles that SystemUI knows how to create (to show to the user in the customization screen). The second one contains only the default tiles that the user will experience on a fresh boot or after they reset their tiles.
6. In [SystemUI/res/values/tiles_states_strings.xml](/packages/SystemUI/res/values/tiles_states_strings.xml), add a new array for your tile. The name has to be `tile_states_<spec>`. Use a good description to help the translators.
+7. In [`SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt), add a new element to the map in `SubtitleArrayMapping` corresponding to the resource created in the previous step.
#### Abstract methods in QSTileImpl
diff --git a/packages/SystemUI/res/drawable/rounded_bg_full.xml b/packages/SystemUI/res/drawable/rounded_bg_full.xml
index e0d3f63e8f40..967c57b0c370 100644
--- a/packages/SystemUI/res/drawable/rounded_bg_full.xml
+++ b/packages/SystemUI/res/drawable/rounded_bg_full.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<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/colorSurface" />
<corners
android:bottomLeftRadius="?android:attr/dialogCornerRadius"
android:topLeftRadius="?android:attr/dialogCornerRadius"
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index 42f14f30da00..6bc01389e3c3 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -64,10 +64,12 @@
android:layout_gravity="center"
android:padding="8dp"
android:gravity="center_vertical|start"
- android:textSize="15sp"
android:ellipsize="end"
- android:maxLines="1"
- style="@style/TextAppearance.NotificationImportanceChannel" />
+ android:maxLines="2"
+ android:textColor="?android:attr/textColorPrimary"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textSize="16sp"
+ />
<Switch
android:id="@+id/toggle"
@@ -80,18 +82,13 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
- android:background="?android:attr/colorAccent"
+ android:background="@*android:color/background_device_default_light"
/>
<!-- ChannelRows get added dynamically -->
</com.android.systemui.statusbar.notification.row.ChannelEditorListView>
- <!-- divider view -->
- <View
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="?android:attr/colorAccent"
- />
+
<RelativeLayout
android:id="@+id/bottom_actions"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/notif_half_shelf_row.xml b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
index 87de28650662..245d1579d5a3 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf_row.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
@@ -21,61 +21,76 @@
android:layout_height="wrap_content"
android:padding="8dp"
android:clickable="true"
- android:orientation="horizontal"
- android:foreground="?android:attr/selectableItemBackground" >
-
- <!-- This is where an icon would go *if we wanted one* **wink** -->
- <Space
- android:id="@+id/icon"
- android:layout_height="48dp"
- android:layout_width="48dp"
- android:layout_gravity="center_vertical"
- android:padding="8dp"
- />
+ android:orientation="vertical"
+ android:foreground="?android:attr/selectableItemBackground"
+ >
- <RelativeLayout
- android:id="@+id/description_container"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_gravity="center_vertical"
- android:gravity="left|center_vertical"
- android:orientation="vertical"
- >
- <TextView
- android:id="@+id/channel_name"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:paddingBottom="0dp"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:gravity="center_vertical|start"
- android:textSize="14sp"
- android:ellipsize="end"
- android:maxLines="1"
- style="@style/TextAppearance.NotificationImportanceChannel"
+ android:orientation="horizontal">
+
+ <!-- This is where an icon would go *if we wanted one* **wink** -->
+ <Space
+ android:id="@+id/icon"
+ android:layout_height="48dp"
+ android:layout_width="48dp"
+ android:layout_gravity="center_vertical"
+ android:padding="8dp"
/>
- <TextView
- android:id="@+id/channel_description"
+ <RelativeLayout
+ android:id="@+id/description_container"
android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:gravity="left|center_vertical"
+ android:orientation="vertical"
+ >
+ <TextView
+ android:id="@+id/channel_name"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:paddingBottom="0dp"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp"
+ android:gravity="center_vertical|start"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp"
+ />
+
+ <TextView
+ android:id="@+id/channel_description"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp"
+ android:gravity="center_vertical|start"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:layout_below="@id/channel_name"
+ android:fontFamily="@*android:string/config_bodyFontFamily"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textSize="14sp"
+ />
+ </RelativeLayout>
+
+ <Switch
+ android:id="@+id/toggle"
+ android:layout_height="48dp"
android:layout_width="wrap_content"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:gravity="center_vertical|start"
- android:textSize="14sp"
- android:ellipsize="end"
- android:maxLines="1"
- android:layout_below="@id/channel_name"
- style="@style/TextAppearance.NotificationImportanceApp"
+ android:layout_gravity="center_vertical"
+ android:padding="8dp"
/>
- </RelativeLayout>
-
- <Switch
- android:id="@+id/toggle"
- android:layout_height="48dp"
- android:layout_width="wrap_content"
- android:layout_gravity="center_vertical"
- android:padding="8dp"
+ </LinearLayout>
+ <!-- divider view -->
+ <View
+ android:layout_width="match_parent"
+ android:layout_height=".5dp"
+ android:background="@*android:color/background_device_default_light"
/>
</com.android.systemui.statusbar.notification.row.ChannelRow>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index c3b96a40023d..9502454d1c8c 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1035,7 +1035,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekranı böyüdün"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran hissəsinin böyüdülməsi"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Dəyişdirici"</string>
- <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Əlçatımlılıq düyməsi əlçatımlılıq jestini əvəz etdi\n\n"<annotation id="link">"Ayarlara baxın"</annotation></string>
+ <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Jest xüsusi imkanlar düyməsinə dəyişdirildi\n\n"<annotation id="link">"Ayarlara baxın"</annotation></string>
<string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"Əlçatımlılıq jestindən düymə\n\n"<annotation id="link">"Ayarlarına"</annotation>" keçə bilərsiniz"</string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Düyməni müvəqqəti gizlətmək üçün kənara çəkin"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Yuxarıya sola köçürün"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 2e98ad94383a..5afd979d34f5 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -484,12 +484,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Дадаць карыстальніка"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Новы карыстальнік"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Выдаліць госця?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Скінуць гасцявы сеанс?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Выдаліць"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Скінуць"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"З вяртаннем, госць!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 9f71f43605ae..0eedd1ca13f1 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1038,8 +1038,7 @@
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্রিনের কিছুটা অংশ বড় করুন"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"বদল করুন"</string>
<string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"অ্যাক্সেসিবিলিটি জেসচার পরিবর্তন করে অ্যাক্সেসেবিলিটি বোতাম করা হয়েছে\n\n"<annotation id="link">"সেটিংস দেখুন"</annotation></string>
- <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
- <skip />
+ <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"আপনি অ্যাক্সেসিবিলিটি জেসচারের বদলে \n\n"<annotation id="link">"সেটিংস"</annotation>" বোতামে সুইচ করতে পারেন"</string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"এটি অস্থায়ীভাবে লুকাতে বোতামটি কোণে সরান"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"উপরে বাঁদিকে সরান"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"উপরে ডানদিকে সরান"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 17dbbe95a010..615d34634789 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -482,12 +482,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Poništiti gostujuću sesiju?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Poništi"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Zdravo! Lijepo je opet vidjeti goste."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 274ca3a32a2c..17cb3b9f3c32 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1038,8 +1038,7 @@
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Teil des Bildschirms vergrößern"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schalter"</string>
<string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"Die Schaltfläche „Bedienungshilfen“ ersetzt die Touch-Geste für Bedienungshilfen\n\n"<annotation id="link">"Einstellungen aufrufen"</annotation></string>
- <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
- <skip />
+ <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"Du kannst von der barrierefreien Geste zu einer Schaltfläche wechseln\n\n"<annotation id="link">"Einstellungen"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Durch Ziehen an den Rand wird die Schaltfläche zeitweise ausgeblendet"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"Nach oben links verschieben"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Nach rechts oben verschieben"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 662282106d1d..497845707e46 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Lisa kasutaja"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Uus kasutaja"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Kas eemaldada külaline?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Kas lähtestada külastajaseanss?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eemalda"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Lähtesta"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Tere tulemast tagasi, külaline!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 6f7aee23f190..abbbae7985d4 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -482,12 +482,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Dodavanje korisnika"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Poništiti gostujuću sesiju?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Poništi"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli natrag, gostu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 800c9dc36a07..15106bb4c157 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Felhasználó hozzáadása"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Új felhasználó"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Eltávolítja a vendég munkamenetet?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Visszaállítja a vendég munkamenetet?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eltávolítás"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Visszaállítás"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Örülünk, hogy visszatért, vendég!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index deeeb209e1e3..2e2141ee075c 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Ավելացնել օգտատեր"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Նոր օգտատեր"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Հեռացնե՞լ հյուրին"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Վերակայե՞լ հյուրի աշխատաշրջանը"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Հեռացնել"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Վերակայել"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index a6cb798a188e..53a3165776fd 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Tambahkan pengguna"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baru"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Hapus tamu?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset sesi tamu?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hapus"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 066cd9344e91..454b5bba4a49 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Aggiungi utente"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Nuovo utente"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Rimuovere l\'ospite?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reimpostare sessione Ospite?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Rimuovi"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reimposta"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto alla sessione Ospite."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b2f0fd259702..32c386d9993e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -725,7 +725,7 @@
<string name="notification_channel_unsilenced" msgid="94878840742161152">"ההודעות אלה יישלחו כהתראות"</string>
<string name="inline_blocking_helper" msgid="2891486013649543452">"ההתראות האלה בדרך כלל נדחות על ידך. \nלהמשיך להציג אותן?"</string>
<string name="inline_done_button" msgid="6043094985588909584">"סיום"</string>
- <string name="inline_ok_button" msgid="603075490581280343">"החלה"</string>
+ <string name="inline_ok_button" msgid="603075490581280343">"אישור"</string>
<string name="inline_keep_showing" msgid="8736001253507073497">"שנמשיך להציג לך את ההתראות האלה?"</string>
<string name="inline_stop_button" msgid="2453460935438696090">"לא, אל תמשיכו"</string>
<string name="inline_deliver_silently_button" msgid="2714314213321223286">"הצגה ללא צליל"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b1736534ffd1..dacdf2146540 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"ユーザーを追加"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"新しいユーザー"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ゲストを削除しますか?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ゲストをリセットしますか?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"削除"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"リセット"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"おかえりなさい、ゲストさん"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 09d5f9f6e3af..8366b2f48927 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Пайдаланушы қосу"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Жаңа пайдаланушы"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Қонақты жою керек пе?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Қонақ сеансы бастапқы күйге қайтарылсын ба?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып тастау"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Бастапқы күйге қайтару"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
@@ -668,7 +666,7 @@
<string name="enable_demo_mode" msgid="3180345364745966431">"Демо режимін қосу"</string>
<string name="show_demo_mode" msgid="3677956462273059726">"Демо режимін көрсету"</string>
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
- <string name="status_bar_alarm" msgid="87160847643623352">"Дабыл"</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_app_button_label" msgid="7123784239111190992">"Барлығын көрсету"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 065a49951dfb..3baa4e1411f1 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"បញ្ចូល​អ្នកប្រើ"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"អ្នកប្រើ​ថ្មី"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ដកភ្ញៀវចេញឬ?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"កំណត់​ភ្ញៀវឡើង​វិញឬ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យ​ទាំងអស់​ក្នុង​វគ្គ​នេះ​នឹង​ត្រូវ​លុប។"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ដកចេញ"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"កំណត់​ឡើងវិញ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"សូម​ស្វាគមន៍​ការ​ត្រឡប់​មកវិញ, ភ្ញៀវ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​វគ្គ​របស់​អ្នក​ទេ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 80415d531d39..ab80f7f3acdc 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"사용자 추가"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"신규 사용자"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"게스트를 삭제하시겠습니까?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"게스트를 초기화하시겠습니까?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"초기화"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"게스트 세션 진행"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 2474fe1f25b5..037a765870d4 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Колдонуучу кошуу"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Жаңы колдонуучу"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Конокту алып саласызбы?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Конок сеансын баштапкы абалга келтиресизби?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана маалыматтар өчүрүлөт."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Өчүрүү"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Баштапкы абалга келтирүү"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 106f7f20a5ba..4cdc8a5fcb4e 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"ເພີ່ມຜູ້ໃຊ້"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"ຜູ່ໃຊ້ໃໝ່"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ລຶບ​ແຂກ​ບໍ?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ຣີເຊັດແຂກບໍ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯ​ແລະ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ໃນ​ເຊດ​ຊັນ​ນີ້​ຈະ​ຖືກ​ລຶບ​ອອກ."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ລຶບ​"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ຣີເຊັດ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ຍິນ​ດີ​ຕ້ອນ​ຮັບ​ກັບ​ມາ, ຜູ້ຢ້ຽມຢາມ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານ​ຕ້ອງ​ການ​ສືບ​ຕໍ່​ເຊດ​ຊັນ​ຂອງ​ທ່ານບໍ່?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 535da7a98f87..90f775bcd310 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Додај корисник"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Нов корисник"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се отстрани гостинот?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Да се ресетира гостинот?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Отстрани"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Ресетирај"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дојде пак, гостине!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 8dae31d1c7f2..976c2dd420c8 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Хэрэглэгч нэмэх"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Шинэ хэрэглэгч"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Зочныг хасах уу?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Зочныг шинэчлэх үү?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Хасах"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Шинэчлэх"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Эргэн тавтай морилно уу!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 3aae0640802f..84b559475019 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1038,8 +1038,7 @@
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच करा"</string>
<string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"अ‍ॅक्सेसिबिलिटी जेश्चर हे आता अ‍ॅक्सेसिबिलिटी बटण आहे \n\n"<annotation id="link">"सेटिंग्ज पाहा"</annotation></string>
- <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
- <skip />
+ <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"तुम्ही अ‍ॅक्सेसिबिलिटी जेश्चरवरून बटणवर स्विच करू शकता \n\n"<annotation id="link">"सेटिंग्ज"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"बटण तात्पुरते लपवण्यासाठी ते कोपर्‍यामध्ये हलवा"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"वर डावीकडे हलवा"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"वर उजवीकडे हलवा"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 9a8fc20fd6c4..efe716e9d04a 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"အသုံးပြုသူ ထည့်ရန်"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"အသုံးပြုသူ အသစ်"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ဧည့်သည်ကို ဖယ်မလား။"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်မလား။"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ဖယ်ထုတ်ပါ"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ပြင်ဆင်သတ်မှတ်ရန်"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ဧည့်သည်ကို ပြန်လည် ကြိုဆိုပါသည်။"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 0006f7f824a3..52e615519148 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -1038,8 +1038,7 @@
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रिनको केही भाग म्याग्निफाइ गर्नुहोस्"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"बदल्नुहोस्"</string>
<string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"एक्सेसिबिलिटी इसाराका स्थानमा एक्सेसिबिलिटी बटन प्रयोग हुन थालेको छ\n\n"<annotation id="link">"सेटिङ हेर्नुहोस्"</annotation></string>
- <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) -->
- <skip />
+ <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"तपाईं एक्सेसिबिलिटी जेस्चरको साटो बटन प्रयोग गर्न सक्नुहुन्छ\n\n"<annotation id="link">"सेटिङ"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"यो बटन केही बेर नदेखिने पार्न किनारातिर सार्नुहोस्"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"सिरानको बायाँतिर सार्नुहोस्"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"सिरानको दायाँतिर सार्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 8e6293aa2e04..b98694e2fae7 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -21,8 +21,8 @@
It's fine to override this color since at that point the shade was dark. -->
<color name="notification_legacy_background_color">@color/GM2_grey_900</color>
- <!-- The color of the dividing line between grouped notifications while . -->
- <color name="notification_divider_color">#212121</color>
+ <!-- The color of the dividing line between grouped notifications. -->
+ <color name="notification_divider_color">@*android:color/background_device_default_dark</color>
<!-- The color of the gear shown behind a notification -->
<color name="notification_gear_color">@color/GM2_grey_500</color>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 944753ad570b..8bd41deb9499 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Gebruiker toevoegen"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Nieuwe gebruiker"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast verwijderen?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Gastsessie resetten?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwijderen"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetten"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gast!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 1dcb1434bc29..003ce4c4b5ce 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ଅତିଥିଙ୍କୁ ରିସେଟ୍ କରିବେ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ରିସେଟ୍ କରନ୍ତୁ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ପୁଣି ସ୍ୱାଗତ, ଅତିଥି!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ad41e5535e6d..e4dbca5eb8e3 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Redefinir sessão de visitante?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Redefinir"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 738e91644681..a9cb3dc88fa1 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Adicionar utilizador"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Novo utilizador"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover o convidado?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Pretende repor a sessão de convidado?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Repor"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, convidado!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ad41e5535e6d..e4dbca5eb8e3 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Redefinir sessão de visitante?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Redefinir"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 3a8b51c49117..6c82ad58a25f 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"පරිශීලකයෙක් එක් කරන්න"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"නව පරිශීලකයා"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"අමුත්තාන් ඉවත් කරන්නද?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ආගන්තුකයා යළි සකසන්නද?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ඉවත් කරන්න"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"යළි සකසන්න"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"නැවත සාදරයෙන් පිළිගනිමු, අමුත්තා!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්‍යද?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 3ceef49a21e7..390a7bc268e3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Lägg till användare"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Ny användare"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vill du ta bort gästen?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Vill du återställa gästsessionen?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ta bort"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Återställ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka som gäst!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 0a4e05923f89..99bf399b3c1b 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Ongeza mtumiaji"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Mtumiaji mpya"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ungependa kumwondoa mgeni?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Ungependa kubadilisha kipindi cha mgeni?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ondoa"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Badilisha"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena mgeni!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 9f8e6364e55d..da80b85b38bf 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -36,10 +36,6 @@
<!-- On tablets this is just the close_handle_height -->
<dimen name="peek_height">@dimen/close_handle_height</dimen>
- <!-- The margin between the clock and the notifications on Keyguard. See
- keyguard_clock_height_fraction_* for the difference between min and max.-->
- <dimen name="keyguard_clock_notifications_margin">44dp</dimen>
-
<!-- Height of the status bar header bar when on Keyguard -->
<dimen name="status_bar_header_height_keyguard">60dp</dimen>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index d6eec3fd4fcf..b21d22faf958 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"เพิ่มผู้ใช้"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"ผู้ใช้ใหม่"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ต้องการนำผู้ใช้ชั่วคราวออกไหม"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"รีเซ็ตผู้เข้าร่วมไหม"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"นำออก"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"รีเซ็ต"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับผู้เข้าร่วมกลับมาอีกครั้ง"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 0a7bdacc69c8..5b48488f18fe 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Magdagdag ng user"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Bagong user"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alisin ang bisita?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"I-reset ang session ng bisita?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alisin"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"I-reset"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome ulit, bisita!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 80e29fb5df6d..8a3d467fbe58 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"Kullanıcı ekle"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"Yeni kullanıcı"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Misafir oturumu kaldırılsın mı?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Misafir oturumu sıfırlansın mı?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kaldır"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Sıfırla"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Misafir kullanıcı, tekrar hoşgeldiniz"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 25cc331d993b..9592b2d6aa5c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"添加用户"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"新用户"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"要移除访客吗?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重置访客会话吗?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"重置"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"访客,欢迎回来!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 5c58081f5035..7be08d3fda5a 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -480,12 +480,10 @@
<string name="user_add_user" msgid="4336657383006913022">"加入使用者"</string>
<string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
<string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
- <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) -->
- <skip />
+ <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重設訪客嗎?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
- <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) -->
- <skip />
+ <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"重設"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客您好,歡迎回來!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 2cf30581326b..e7edb0e6a57d 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -93,7 +93,7 @@
<color name="notification_material_background_dark_color">#ff333333</color>
<!-- The color of the dividing line between grouped notifications. -->
- <color name="notification_divider_color">#FF616161</color>
+ <color name="notification_divider_color">@*android:color/background_device_default_light</color>
<!-- The color of the ripples on the untinted notifications -->
<color name="notification_ripple_untinted_color">#28000000</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 9678affa96a7..2a1bee5344ec 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -445,6 +445,9 @@
<!-- Adjust the theme on fully custom and decorated custom view notifications -->
<bool name="config_adjustThemeOnNotificationCustomViews">false</bool>
+ <!-- Notifications are sized to match the width of two (of 4) qs tiles in landscape. -->
+ <bool name="config_skinnyNotifsInLandscape">true</bool>
+
<!-- If true, enable the advance anti-falsing classifier on the lockscreen. On some devices it
does not work well, particularly with noisy touchscreens. Note that disabling it may
increase the rate of unintentional unlocks. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9b860c75f476..7525a9b1c19c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -685,7 +685,7 @@
<dimen name="notification_shadow_radius">0dp</dimen>
<!-- The alpha of the dividing line between child notifications of a notification group. -->
- <item name="notification_divider_alpha" format="float" type="dimen">0.5</item>
+ <item name="notification_divider_alpha" format="float" type="dimen">1</item>
<!-- The height of the divider between the individual notifications in a notification
group. -->
@@ -735,8 +735,8 @@
<!-- Minimum distance the user has to drag down to go to the full shade. -->
<dimen name="keyguard_drag_down_min_distance">100dp</dimen>
- <!-- The margin between the clock and the notifications on Keyguard.-->
- <dimen name="keyguard_clock_notifications_margin">30dp</dimen>
+ <!-- The margin between the status view and the notifications on Keyguard.-->
+ <dimen name="keyguard_status_view_bottom_margin">20dp</dimen>
<!-- Minimum margin between clock and status bar -->
<dimen name="keyguard_clock_top_margin">36dp</dimen>
<!-- The margin between top of clock and bottom of lock icon. -->
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index ef6212d4f354..a28d1747f2fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -205,6 +205,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
}
}
+ int getNotificationIconAreaHeight() {
+ return mNotificationIconAreaController.getHeight();
+ }
+
@Override
protected void onViewDetached() {
if (CUSTOM_CLOCKS_ENABLED) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 123c0e63d7d1..2096c310744d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -187,10 +187,11 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
/**
- * Get the height of the keyguard status view.
+ * Get the height of the keyguard status view without the notification icon area, as that's
+ * only visible on AOD.
*/
- public int getHeight() {
- return mView.getHeight();
+ public int getLockscreenHeight() {
+ return mView.getHeight() - mKeyguardClockSwitchController.getNotificationIconAreaHeight();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 7b34e52c16e8..455f3c0d6ac2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -71,7 +71,6 @@ public class DozeTriggers implements DozeMachine.Part {
* Assuming that the screen should start on.
*/
private static boolean sWakeDisplaySensorState = true;
- private Runnable mQuickPickupDozeCancellable;
private static final int PROXIMITY_TIMEOUT_DELAY_MS = 500;
@@ -279,14 +278,14 @@ public class DozeTriggers implements DozeMachine.Part {
boolean isWakeDisplayEvent = isQuickPickup || ((isWakeOnPresence || isWakeOnReach)
&& rawValues != null && rawValues.length > 0 && rawValues[0] != 0);
- if (isWakeOnPresence || isQuickPickup) {
- onWakeScreen(isQuickPickup || isWakeDisplayEvent,
+ if (isWakeOnPresence) {
+ onWakeScreen(isWakeDisplayEvent,
mMachine.isExecutingTransition() ? null : mMachine.getState(),
pulseReason);
} else if (isLongPress) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
null /* onPulseSuppressedListener */);
- } else if (isWakeOnReach) {
+ } else if (isWakeOnReach || isQuickPickup) {
if (isWakeDisplayEvent) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
null /* onPulseSuppressedListener */);
@@ -388,11 +387,7 @@ public class DozeTriggers implements DozeMachine.Part {
*/
private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state, int reason) {
mDozeLog.traceWakeDisplay(wake, reason);
- final boolean isWakeOnPresence = reason == DozeLog.REASON_SENSOR_WAKE_UP;
- final boolean isQuickPickup = reason == DozeLog.REASON_SENSOR_QUICK_PICKUP;
- if (isWakeOnPresence) {
- sWakeDisplaySensorState = wake;
- }
+ sWakeDisplaySensorState = wake;
if (wake) {
proximityCheckThenCall((result) -> {
@@ -405,27 +400,13 @@ public class DozeTriggers implements DozeMachine.Part {
// Log sensor triggered
Optional.ofNullable(DozingUpdateUiEvent.fromReason(reason))
.ifPresent(mUiEventLogger::log);
-
- if (isQuickPickup) {
- // schedule runnable to go back to DOZE
- onQuickPickup();
- }
- } else if (state == DozeMachine.State.DOZE_AOD && isQuickPickup) {
- // elongate time in DOZE_AOD, schedule new runnable to go back to DOZE
- onQuickPickup();
}
- }, isQuickPickup /* alreadyPerformedProxCheck */, reason);
+ }, false /* alreadyPerformedProxCheck */, reason);
} else {
boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
- boolean pulse = (state == DozeMachine.State.DOZE_REQUEST_PULSE)
- || (state == DozeMachine.State.DOZE_PULSING)
- || (state == DozeMachine.State.DOZE_PULSING_BRIGHT);
- boolean docked = (state == DozeMachine.State.DOZE_AOD_DOCKED);
+
if (!pausing && !paused) {
- if (isQuickPickup && (pulse || docked)) {
- return;
- }
mMachine.requestState(DozeMachine.State.DOZE);
// log wake timeout
mUiEventLogger.log(DozingUpdateUiEvent.DOZING_UPDATE_WAKE_TIMEOUT);
@@ -433,15 +414,6 @@ public class DozeTriggers implements DozeMachine.Part {
}
}
- private void onQuickPickup() {
- cancelQuickPickupDelayableDoze();
- mQuickPickupDozeCancellable = mMainExecutor.executeDelayed(() -> {
- onWakeScreen(false,
- mMachine.isExecutingTransition() ? null : mMachine.getState(),
- DozeLog.REASON_SENSOR_QUICK_PICKUP);
- }, mDozeParameters.getQuickPickupAodDuration());
- }
-
@Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {
@@ -481,7 +453,6 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeSensors.requestTemporaryDisable();
break;
case FINISH:
- cancelQuickPickupDelayableDoze();
mBroadcastReceiver.unregister(mBroadcastDispatcher);
mDozeHost.removeCallback(mHostCallback);
mDockManager.removeListener(mDockEventListener);
@@ -510,16 +481,6 @@ public class DozeTriggers implements DozeMachine.Part {
}
}
- /**
- * Cancels last scheduled Runnable that transitions to STATE_DOZE (blank screen) after
- * going into STATE_AOD (AOD screen) from the quick pickup gesture.
- */
- private void cancelQuickPickupDelayableDoze() {
- if (mQuickPickupDozeCancellable != null) {
- mQuickPickupDozeCancellable.run();
- mQuickPickupDozeCancellable = null;
- }
- }
private void checkTriggersAtInit() {
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 1004e257c750..3957a60c5b45 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -32,6 +32,7 @@ import javax.inject.Provider
private const val TAG = "MediaCarouselController"
private val settingsIntent = Intent().setAction(ACTION_MEDIA_CONTROLS_SETTINGS)
+private const val DEBUG = false
/**
* Class that is responsible for keeping the view carousel up to date.
@@ -156,6 +157,12 @@ class MediaCarouselController @Inject constructor(
}
}
+ /**
+ * Update MediaCarouselScrollHandler.visibleToUser to reflect media card container visibility.
+ * It will be called when the container is out of view.
+ */
+ lateinit var updateUserVisibility: () -> Unit
+
init {
mediaFrame = inflateMediaCarousel()
mediaCarousel = mediaFrame.requireViewById(R.id.media_carousel_scroller)
@@ -177,6 +184,12 @@ class MediaCarouselController @Inject constructor(
keysNeedRemoval.forEach { removePlayer(it) }
keysNeedRemoval.clear()
+ // Update user visibility so that no extra impression will be logged when
+ // activeMediaIndex resets to 0
+ if (this::updateUserVisibility.isInitialized) {
+ updateUserVisibility()
+ }
+
// Let's reset our scroll position
mediaCarouselScrollHandler.scrollToStart()
}
@@ -187,16 +200,24 @@ class MediaCarouselController @Inject constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
if (addOrUpdatePlayer(key, oldKey, data)) {
MediaPlayerData.getMediaPlayer(key, null)?.let {
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
it.mInstanceId,
/* isRecommendationCard */ false,
- it.surfaceForSmartspaceLogging)
+ it.surfaceForSmartspaceLogging,
+ rank = MediaPlayerData.getMediaPlayerIndex(key))
}
}
+ if (mediaCarouselScrollHandler.visibleToUser &&
+ isSsReactivated && !mediaCarouselScrollHandler.qsExpanded) {
+ // It could happen that reactived media player isn't visible to user because
+ // of it is a resumption card.
+ logSmartspaceImpression(mediaCarouselScrollHandler.qsExpanded)
+ }
val canRemove = data.isPlaying?.let { !it } ?: data.isClearable && !data.active
if (canRemove && !Utils.useMediaResumption(context)) {
// This view isn't playing, let's remove this! This happens e.g when
@@ -217,17 +238,24 @@ class MediaCarouselController @Inject constructor(
data: SmartspaceMediaData,
shouldPrioritize: Boolean
) {
- Log.d(TAG, "My Smartspace media update is here")
+ if (DEBUG) Log.d(TAG, "Loading Smartspace media update")
if (data.isActive) {
addSmartspaceMediaRecommendations(key, data, shouldPrioritize)
MediaPlayerData.getMediaPlayer(key, null)?.let {
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
it.mInstanceId,
/* isRecommendationCard */ true,
- it.surfaceForSmartspaceLogging)
- }
- if (mediaCarouselScrollHandler.visibleToUser) {
- logSmartspaceImpression()
+ it.surfaceForSmartspaceLogging,
+ rank = MediaPlayerData.getMediaPlayerIndex(key))
+
+ if (mediaCarouselScrollHandler.visibleToUser &&
+ mediaCarouselScrollHandler.visibleMediaIndex ==
+ MediaPlayerData.getMediaPlayerIndex(key)) {
+ logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
+ it.mInstanceId,
+ /* isRecommendationCard */ true,
+ it.surfaceForSmartspaceLogging)
+ }
}
} else {
onSmartspaceMediaDataRemoved(data.targetId, immediately = true)
@@ -239,7 +267,7 @@ class MediaCarouselController @Inject constructor(
}
override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
- Log.d(TAG, "My Smartspace media removal request is received")
+ if (DEBUG) Log.d(TAG, "My Smartspace media removal request is received")
if (immediately || visualStabilityManager.isReorderingAllowed) {
onMediaDataRemoved(key)
} else {
@@ -357,7 +385,7 @@ class MediaCarouselController @Inject constructor(
data: SmartspaceMediaData,
shouldPrioritize: Boolean
) {
- Log.d(TAG, "Updating smartspace target in carousel")
+ if (DEBUG) Log.d(TAG, "Updating smartspace target in carousel")
if (MediaPlayerData.getMediaPlayer(key, null) != null) {
Log.w(TAG, "Skip adding smartspace target in carousel")
return
@@ -644,17 +672,17 @@ class MediaCarouselController @Inject constructor(
}
/**
- * Log the user impression for media card.
+ * Log the user impression for media card at visibleMediaIndex.
*/
- fun logSmartspaceImpression() {
+ fun logSmartspaceImpression(qsExpanded: Boolean) {
val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
if (MediaPlayerData.players().size > visibleMediaIndex) {
val mediaControlPanel = MediaPlayerData.players().elementAt(visibleMediaIndex)
- val isMediaActive =
- MediaPlayerData.playerKeys().elementAt(visibleMediaIndex).data?.active
+ val hasActiveMediaOrRecommendationCard =
+ MediaPlayerData.hasActiveMediaOrRecommendationCard()
val isRecommendationCard = mediaControlPanel.recommendationViewHolder != null
- if (!isRecommendationCard && !isMediaActive) {
- // Media control card time out or swiped away
+ if (!hasActiveMediaOrRecommendationCard && !qsExpanded) {
+ // Skip logging if on LS or QQS, and there is no active media card
return
}
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
@@ -672,6 +700,13 @@ class MediaCarouselController @Inject constructor(
surface: Int,
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
) {
+ // Only log media resume card when Smartspace data is available
+ if (!isRecommendationCard &&
+ !mediaManager.smartspaceMediaData.isActive &&
+ MediaPlayerData.smartspaceMediaData == null) {
+ return
+ }
+
/* ktlint-disable max-line-length */
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
eventId,
@@ -770,6 +805,16 @@ internal object MediaPlayerData {
return mediaData.get(key)?.let { mediaPlayers.get(it) }
}
+ fun getMediaPlayerIndex(key: String): Int {
+ val sortKey = mediaData.get(key)
+ mediaPlayers.entries.forEachIndexed { index, e ->
+ if (e.key == sortKey) {
+ return index
+ }
+ }
+ return -1
+ }
+
fun removeMediaPlayer(key: String) = mediaData.remove(key)?.let {
if (it.isSsMediaRec) {
smartspaceMediaData = null
@@ -808,4 +853,15 @@ internal object MediaPlayerData {
mediaData.clear()
mediaPlayers.clear()
}
+
+ /* Returns true if there is active media player card or recommendation card */
+ fun hasActiveMediaOrRecommendationCard(): Boolean {
+ if (smartspaceMediaData != null && smartspaceMediaData?.isActive!!) {
+ return true
+ }
+ if (firstActiveMediaIndex() != -1) {
+ return true
+ }
+ return false
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
index eb3549789c19..b0d4cb1c9818 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
@@ -62,7 +62,7 @@ class MediaCarouselScrollHandler(
private val closeGuts: (immediate: Boolean) -> Unit,
private val falsingCollector: FalsingCollector,
private val falsingManager: FalsingManager,
- private val logSmartspaceImpression: () -> Unit
+ private val logSmartspaceImpression: (Boolean) -> Unit
) {
/**
* Is the view in RTL
@@ -195,18 +195,22 @@ class MediaCarouselScrollHandler(
if (playerWidthPlusPadding == 0) {
return
}
+
val relativeScrollX = scrollView.relativeScrollX
onMediaScrollingChanged(relativeScrollX / playerWidthPlusPadding,
relativeScrollX % playerWidthPlusPadding)
}
}
+ /**
+ * Whether the media card is visible to user if any
+ */
var visibleToUser: Boolean = false
- set(value) {
- if (field != value) {
- field = value
- }
- }
+
+ /**
+ * Whether the quick setting is expanded or not
+ */
+ var qsExpanded: Boolean = false
init {
gestureDetector = GestureDetectorCompat(scrollView.context, gestureListener)
@@ -471,7 +475,7 @@ class MediaCarouselScrollHandler(
val oldIndex = visibleMediaIndex
visibleMediaIndex = newIndex
if (oldIndex != visibleMediaIndex && visibleToUser) {
- logSmartspaceImpression()
+ logSmartspaceImpression(qsExpanded)
}
closeGuts(false)
updatePlayerVisibilities()
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 19190cd4a17d..19a67e95a496 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -266,7 +266,7 @@ public class MediaControlPanel {
}
mKey = key;
MediaSession.Token token = data.getToken();
- mInstanceId = data.getPackageName().hashCode();
+ mInstanceId = SmallHash.hash(data.getPackageName());
mBackgroundColor = data.getBackgroundColor();
if (mToken == null || !mToken.equals(token)) {
@@ -504,7 +504,7 @@ public class MediaControlPanel {
return;
}
- mInstanceId = data.getTargetId().hashCode();
+ mInstanceId = SmallHash.hash(data.getTargetId());
mBackgroundColor = data.getBackgroundColor();
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
recommendationCard.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
index ee1d3ea87da8..296bfda89432 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
@@ -31,7 +31,8 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
entries[key] = data to entries.remove(oldKey)?.second
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index a611b600f47f..c8deb014f781 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -83,7 +83,8 @@ class MediaDataFilter @Inject constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
if (oldKey != null && oldKey != key) {
allEntries.remove(oldKey)
@@ -101,7 +102,7 @@ class MediaDataFilter @Inject constructor(
// Notify listeners
listeners.forEach {
- it.onMediaDataLoaded(key, oldKey, data)
+ it.onMediaDataLoaded(key, oldKey, data, isSsReactivated = isSsReactivated)
}
}
@@ -118,6 +119,8 @@ class MediaDataFilter @Inject constructor(
// Override the pass-in value here, as the order of Smartspace card is only determined here.
var shouldPrioritizeMutable = false
smartspaceMediaData = data
+ // Override the pass-in value here, as the Smartspace reactivation could only happen here.
+ var isSsReactivated = false
// Before forwarding the smartspace target, first check if we have recently inactive media
val sorted = userEntries.toSortedMap(compareBy {
@@ -137,9 +140,13 @@ class MediaDataFilter @Inject constructor(
// Notify listeners to consider this media active
Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
reactivatedKey = lastActiveKey
+ if (MediaPlayerData.firstActiveMediaIndex() == -1) {
+ isSsReactivated = true
+ }
val mediaData = sorted.get(lastActiveKey)!!.copy(active = true)
listeners.forEach {
- it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData)
+ it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData,
+ isSsReactivated = isSsReactivated)
}
} else {
// Mark to prioritize Smartspace card if no recent media.
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 28d336ea18d5..df1b07f3e0b2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -148,7 +148,7 @@ class MediaDataManager(
private val internalListeners: MutableSet<Listener> = mutableSetOf()
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
// There should ONLY be at most one Smartspace media recommendation.
- private var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
+ var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
private var smartspaceSession: SmartspaceSession? = null
private var allowMediaRecommendations = Utils.allowMediaRecommendations(context)
@@ -453,7 +453,8 @@ class MediaDataManager(
if (smartspaceMediaData.targetId != key) {
return
}
- Log.d(TAG, "Dismissing Smartspace media target")
+
+ if (DEBUG) Log.d(TAG, "Dismissing Smartspace media target")
if (smartspaceMediaData.isActive) {
smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
targetId = smartspaceMediaData.targetId)
@@ -709,17 +710,19 @@ class MediaDataManager(
override fun onSmartspaceTargetsUpdated(targets: List<Parcelable>) {
if (!allowMediaRecommendations) {
+ if (DEBUG) Log.d(TAG, "Smartspace recommendation is disabled in Settings.")
return
}
val mediaTargets = targets.filterIsInstance<SmartspaceTarget>()
when (mediaTargets.size) {
0 -> {
- Log.d(TAG, "Empty Smartspace media target")
if (!smartspaceMediaData.isActive) {
return
}
- Log.d(TAG, "Set Smartspace media to be inactive for the data update")
+ if (DEBUG) {
+ Log.d(TAG, "Set Smartspace media to be inactive for the data update")
+ }
smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
targetId = smartspaceMediaData.targetId)
notifySmartspaceMediaDataRemoved(smartspaceMediaData.targetId, immediately = false)
@@ -728,13 +731,12 @@ class MediaDataManager(
val newMediaTarget = mediaTargets.get(0)
if (smartspaceMediaData.targetId == newMediaTarget.smartspaceTargetId) {
// The same Smartspace updates can be received. Skip the duplicate updates.
- Log.d(TAG, "Same Smartspace media update exists. Skip loading data.")
- } else {
- Log.d(TAG, "Forwarding Smartspace media update.")
- smartspaceMediaData = toSmartspaceMediaData(newMediaTarget, isActive = true)
- notifySmartspaceMediaDataLoaded(
- smartspaceMediaData.targetId, smartspaceMediaData)
+ return
}
+ if (DEBUG) Log.d(TAG, "Forwarding Smartspace media update.")
+ smartspaceMediaData = toSmartspaceMediaData(newMediaTarget, isActive = true)
+ notifySmartspaceMediaDataLoaded(
+ smartspaceMediaData.targetId, smartspaceMediaData)
}
else -> {
// There should NOT be more than 1 Smartspace media update. When it happens, it
@@ -824,12 +826,16 @@ class MediaDataManager(
* @param immediately indicates should apply the UI changes immediately, otherwise wait
* until the next refresh-round before UI becomes visible. True by default to take in place
* immediately.
+ *
+ * @param isSsReactivated indicates transition from a state with no active media players to
+ * a state with active media players upon receiving Smartspace media data.
*/
fun onMediaDataLoaded(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean = true
+ immediately: Boolean = true,
+ isSsReactivated: Boolean = false
) {}
/**
@@ -879,7 +885,7 @@ class MediaDataManager(
private fun packageName(target: SmartspaceTarget): String? {
val recommendationList = target.iconGrid
if (recommendationList == null || recommendationList.isEmpty()) {
- Log.d(TAG, "Empty or media recommendation list.")
+ Log.w(TAG, "Empty or null media recommendation list.")
return null
}
for (recommendation in recommendationList) {
@@ -889,7 +895,7 @@ class MediaDataManager(
packageName -> return packageName }
}
}
- Log.d(TAG, "No valid package name is provided.")
+ Log.w(TAG, "No valid package name is provided.")
return null
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index 52ecbea05924..292b0e291244 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -67,7 +67,8 @@ class MediaDeviceManager @Inject constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
if (oldKey != null && oldKey != key) {
val oldEntry = entries.remove(oldKey)
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index edbf18789e28..186f961ff1b6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -220,14 +220,11 @@ class MediaHierarchyManager @Inject constructor(
set(value) {
if (field != value) {
field = value
+ mediaCarouselController.mediaCarouselScrollHandler.qsExpanded = value
}
// qs is expanded on LS shade and HS shade
if (value && (isLockScreenShadeVisibleToUser() || isHomeScreenShadeVisibleToUser())) {
- mediaCarouselController.logSmartspaceImpression()
- }
- // Release shade and back to lock screen
- if (isLockScreenVisibleToUser()) {
- mediaCarouselController.logSmartspaceImpression()
+ mediaCarouselController.logSmartspaceImpression(value)
}
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
}
@@ -409,7 +406,7 @@ class MediaHierarchyManager @Inject constructor(
updateTargetState()
// Enters shade from lock screen
if (newState == StatusBarState.SHADE_LOCKED && isLockScreenShadeVisibleToUser()) {
- mediaCarouselController.logSmartspaceImpression()
+ mediaCarouselController.logSmartspaceImpression(qsExpanded)
}
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
}
@@ -423,7 +420,7 @@ class MediaHierarchyManager @Inject constructor(
dozeAnimationRunning = false
// Enters lock screen from screen off
if (isLockScreenVisibleToUser()) {
- mediaCarouselController.logSmartspaceImpression()
+ mediaCarouselController.logSmartspaceImpression(qsExpanded)
}
} else {
updateDesiredLocation()
@@ -436,11 +433,7 @@ class MediaHierarchyManager @Inject constructor(
override fun onExpandedChanged(isExpanded: Boolean) {
// Enters shade from home screen
if (isHomeScreenShadeVisibleToUser()) {
- mediaCarouselController.logSmartspaceImpression()
- }
- // Back to lock screen from bouncer
- if (isLockScreenVisibleToUser()) {
- mediaCarouselController.logSmartspaceImpression()
+ mediaCarouselController.logSmartspaceImpression(qsExpanded)
}
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
}
@@ -465,6 +458,10 @@ class MediaHierarchyManager @Inject constructor(
goingToSleep = false
}
})
+
+ mediaCarouselController.updateUserVisibility = {
+ mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
+ }
}
private fun updateConfiguration() {
@@ -663,15 +660,11 @@ class MediaHierarchyManager @Inject constructor(
return true
}
- if (statusbarState == StatusBarState.KEYGUARD) {
- if (currentLocation == LOCATION_LOCKSCREEN &&
- previousLocation == LOCATION_QS ||
- (currentLocation == LOCATION_QS &&
- previousLocation == LOCATION_LOCKSCREEN)) {
- // We're always fading from lockscreen to keyguard in situations where the player
- // is already fully hidden
- return false
- }
+ if (statusbarState == StatusBarState.KEYGUARD && (currentLocation == LOCATION_LOCKSCREEN ||
+ previousLocation == LOCATION_LOCKSCREEN)) {
+ // We're always fading from lockscreen to keyguard in situations where the player
+ // is already fully hidden
+ return false
}
return mediaFrame.isShownNotFaded || animator.isRunning || animationPending
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
index 43e21424c45e..ff085c36ef9c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
@@ -60,7 +60,8 @@ class MediaHost constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
if (immediately) {
updateViewVisibility()
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index 0da84fbac600..ab568c8c5a85 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -159,7 +159,8 @@ class MediaResumeListener @Inject constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
if (useMediaResumption) {
// If this had been started from a resume state, disconnect now that it's live
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
index a4f33e354b68..8bddde839817 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
@@ -95,7 +95,8 @@ class MediaSessionBasedFilter @Inject constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
backgroundExecutor.execute {
data.token?.let {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
index bbea140ecfaf..9a3919326cbd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
@@ -54,7 +54,8 @@ class MediaTimeoutListener @Inject constructor(
key: String,
oldKey: String?,
data: MediaData,
- immediately: Boolean
+ immediately: Boolean,
+ isSsReactivated: Boolean
) {
var reusedListener: PlaybackStateListener? = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/SmallHash.java b/packages/SystemUI/src/com/android/systemui/media/SmallHash.java
new file mode 100644
index 000000000000..de7aac609955
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/SmallHash.java
@@ -0,0 +1,44 @@
+/*
+ * 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.media;
+
+import java.util.Objects;
+
+/**
+ * A simple hash function for use in privacy-sensitive logging.
+ */
+public final class SmallHash {
+ // Hashes will be in the range [0, MAX_HASH).
+ public static final int MAX_HASH = (1 << 13);
+
+ /** Return Small hash of the string, if non-null, or 0 otherwise. */
+ public static int hash(String in) {
+ return hash(Objects.hashCode(in));
+ }
+
+ /**
+ * Maps in to the range [0, MAX_HASH), keeping similar values distinct.
+ *
+ * @param in An arbitrary integer.
+ * @return in mod MAX_HASH, signs chosen to stay in the range [0, MAX_HASH).
+ */
+ public static int hash(int in) {
+ return Math.abs(Math.floorMod(in, MAX_HASH));
+ }
+
+ private SmallHash() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index e24acf27c973..659475d19277 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -228,24 +228,5 @@ public class QuickQSPanel extends QSPanel {
}
}
}
-
- @Override
- public void setExpansion(float expansion) {
- if (expansion > 0f && expansion < 1f) {
- return;
- }
- boolean selected = expansion == 0f;
- // Expansion == 0f is when QQS is fully showing (as opposed to 1f, which is QS). At this
- // point we want them to be selected so the tiles will marquee (but not at other points
- // of expansion.
- // We set it as not important while we change this, so setting each tile as selected
- // will not cause them to announce themselves until the user has actually selected the
- // item.
- setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- for (int i = 0; i < getChildCount(); i++) {
- getChildAt(i).setSelected(selected);
- }
- setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 8aed0a88fa35..d31e67c55777 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -190,6 +190,9 @@ open class QSTileViewImpl @JvmOverloads constructor(
if (collapsed) {
labelContainer.ignoreLastView = true
secondaryLabel.alpha = 0f
+ // Do not marque in QQS
+ label.ellipsize = TextUtils.TruncateAt.END
+ secondaryLabel.ellipsize = TextUtils.TruncateAt.END
}
setLabelColor(getLabelColorForState(QSTile.State.DEFAULT_STATE))
setSecondaryLabelColor(getSecondaryLabelColorForState(QSTile.State.DEFAULT_STATE))
@@ -492,11 +495,7 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
return if (state.state == Tile.STATE_UNAVAILABLE || state is BooleanState) {
- val resName = "$TILE_STATE_RES_PREFIX${state.spec}"
- var arrayResId = resources.getIdentifier(resName, "array", context.packageName)
- if (arrayResId == 0) {
- arrayResId = R.array.tile_states_default
- }
+ var arrayResId = SubtitleArrayMapping.getSubtitleId(state.spec)
val array = resources.getStringArray(arrayResId)
array[state.state]
} else {
@@ -557,6 +556,41 @@ open class QSTileViewImpl @JvmOverloads constructor(
private fun getChevronColorForState(state: Int): Int = getSecondaryLabelColorForState(state)
}
+@VisibleForTesting
+internal object SubtitleArrayMapping {
+ private val subtitleIdsMap = mapOf<String?, Int>(
+ "internet" to R.array.tile_states_internet,
+ "wifi" to R.array.tile_states_wifi,
+ "cell" to R.array.tile_states_cell,
+ "battery" to R.array.tile_states_battery,
+ "dnd" to R.array.tile_states_dnd,
+ "flashlight" to R.array.tile_states_flashlight,
+ "rotation" to R.array.tile_states_rotation,
+ "bt" to R.array.tile_states_bt,
+ "airplane" to R.array.tile_states_airplane,
+ "location" to R.array.tile_states_location,
+ "hotspot" to R.array.tile_states_hotspot,
+ "inversion" to R.array.tile_states_inversion,
+ "saver" to R.array.tile_states_saver,
+ "dark" to R.array.tile_states_dark,
+ "work" to R.array.tile_states_work,
+ "cast" to R.array.tile_states_cast,
+ "night" to R.array.tile_states_night,
+ "screenrecord" to R.array.tile_states_screenrecord,
+ "reverse" to R.array.tile_states_reverse,
+ "reduce_brightness" to R.array.tile_states_reduce_brightness,
+ "cameratoggle" to R.array.tile_states_cameratoggle,
+ "mictoggle" to R.array.tile_states_mictoggle,
+ "controls" to R.array.tile_states_controls,
+ "wallet" to R.array.tile_states_wallet,
+ "alarm" to R.array.tile_states_alarm
+ )
+
+ fun getSubtitleId(spec: String?): Int {
+ return subtitleIdsMap.getOrDefault(spec, R.array.tile_states_default)
+ }
+}
+
private fun colorValuesHolder(name: String, vararg values: Int): PropertyValuesHolder {
return PropertyValuesHolder.ofInt(name, *values).apply {
setEvaluator(ArgbEvaluator.getInstance())
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index a69b8d60681c..25cbdc5c2187 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -245,7 +245,8 @@ public class NotificationMediaManager implements Dumpable {
mMediaDataManager.addListener(new MediaDataManager.Listener() {
@Override
public void onMediaDataLoaded(@NonNull String key,
- @Nullable String oldKey, @NonNull MediaData data, boolean immediately) {
+ @Nullable String oldKey, @NonNull MediaData data, boolean immediately,
+ boolean isSsReactivated) {
}
@Override
@@ -318,7 +319,8 @@ public class NotificationMediaManager implements Dumpable {
mMediaDataManager.addListener(new MediaDataManager.Listener() {
@Override
public void onMediaDataLoaded(@NonNull String key,
- @Nullable String oldKey, @NonNull MediaData data, boolean immediately) {
+ @Nullable String oldKey, @NonNull MediaData data, boolean immediately,
+ boolean isSsReactivated) {
}
@Override
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 c24c2be3faa3..4f3406c405ad 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
@@ -203,6 +203,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mBackgroundNormal.setCustomBackground(R.drawable.notification_material_bg);
}
+ protected boolean hideBackground() {
+ return false;
+ }
+
+ protected void updateBackground() {
+ mBackgroundNormal.setVisibility(hideBackground() ? INVISIBLE : VISIBLE);
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
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 ba28dc59def4..fe75739d33c4 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
@@ -133,7 +133,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private boolean mUpdateBackgroundOnUpdate;
private boolean mNotificationTranslationFinished = false;
- private ArrayList<MenuItem> mSnoozedMenuItems;
+ private boolean mIsSnoozed;
/**
* Listener for when {@link ExpandableNotificationRow} is laid out.
@@ -1105,8 +1105,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
false /* resetMenu */);
mNotificationGutsManager.openGuts(this, 0, 0, item);
- mSnoozedMenuItems = mMenuRow.getMenuItems(mMenuRow.getMenuView().getContext());
- mMenuRow.resetMenu();
+ mIsSnoozed = true;
};
}
@@ -1821,10 +1820,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
void onGutsClosed() {
updateContentAccessibilityImportanceForGuts(true /* isEnabled */);
- if (mSnoozedMenuItems != null && mSnoozedMenuItems.size() > 0) {
- mMenuRow.setMenuItems(mSnoozedMenuItems);
- mSnoozedMenuItems = null;
- }
+ mIsSnoozed = false;
}
/**
@@ -2890,6 +2886,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mShowNoBackground = false;
}
updateOutline();
+ updateBackground();
+ }
+
+ @Override
+ protected boolean hideBackground() {
+ return mShowNoBackground || super.hideBackground();
}
public int getPositionOfChild(ExpandableNotificationRow childRow) {
@@ -2975,7 +2977,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfoInternal(info);
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
- if (canViewBeDismissed()) {
+ if (canViewBeDismissed() && !mIsSnoozed) {
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
}
boolean expandable = shouldShowPublic();
@@ -2991,7 +2993,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
isExpanded = isExpanded();
}
}
- if (expandable) {
+ if (expandable && !mIsSnoozed) {
if (isExpanded) {
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index f2e39e78df36..c2716b949b71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -725,7 +725,7 @@ public class NotificationChildrenContainer extends ViewGroup {
tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
- alpha = NotificationUtils.interpolate(0, 0.5f,
+ alpha = NotificationUtils.interpolate(0, mDividerAlpha,
Math.min(viewState.alpha, expandFraction));
}
tmpState.hidden = !dividersVisible;
@@ -802,9 +802,9 @@ public class NotificationChildrenContainer extends ViewGroup {
View divider = mDividers.get(i);
tmpState.initFrom(divider);
tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
- float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
+ float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
- alpha = NotificationUtils.interpolate(0, 0.5f,
+ alpha = NotificationUtils.interpolate(0, mDividerAlpha,
Math.min(viewState.alpha, expandFraction));
}
tmpState.hidden = !dividersVisible;
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 f0201cb3482d..9ba04bf2f49f 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
@@ -111,6 +111,7 @@ import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.ScrollAdapter;
import com.android.systemui.util.Assert;
+import com.android.systemui.util.leak.RotationUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -421,6 +422,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
animateScroll();
};
private int mCornerRadius;
+ private int mMinimumPaddings;
+ private int mQsTilePadding;
+ private boolean mSkinnyNotifsInLandscape;
private int mSidePaddings;
private final Rect mBackgroundAnimationRect = new Rect();
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
@@ -896,7 +900,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
R.dimen.min_top_overscroll_to_qs);
mStatusBarHeight = res.getDimensionPixelSize(R.dimen.status_bar_height);
mBottomMargin = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom);
- mSidePaddings = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
+ mMinimumPaddings = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
+ mQsTilePadding = res.getDimensionPixelOffset(R.dimen.qs_tile_margin_horizontal);
+ mSkinnyNotifsInLandscape = res.getBoolean(R.bool.config_skinnyNotifsInLandscape);
+ mSidePaddings = mMinimumPaddings; // Updated in onMeasure by updateSidePadding()
mMinInteractionHeight = res.getDimensionPixelSize(
R.dimen.notification_min_interaction_height);
mCornerRadius = res.getDimensionPixelSize(R.dimen.notification_corner_radius);
@@ -906,6 +913,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
com.android.internal.R.dimen.quick_qs_offset_height);
}
+ void updateSidePadding(int viewWidth) {
+ if (viewWidth == 0 || !mSkinnyNotifsInLandscape) {
+ mSidePaddings = mMinimumPaddings;
+ return;
+ }
+ // Portrait is easy, just use the dimen for paddings
+ if (RotationUtils.getRotation(mContext) == RotationUtils.ROTATION_NONE) {
+ mSidePaddings = mMinimumPaddings;
+ return;
+ }
+ final int innerWidth = viewWidth - mMinimumPaddings * 2;
+ final int qsTileWidth = (innerWidth - mQsTilePadding * 3) / 4;
+ mSidePaddings = mMinimumPaddings + qsTileWidth + mQsTilePadding;
+ }
+
void updateCornerRadius() {
int newRadius = getResources().getDimensionPixelSize(R.dimen.notification_corner_radius);
if (mCornerRadius != newRadius) {
@@ -966,6 +988,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
+ updateSidePadding(width);
int childWidthSpec = MeasureSpec.makeMeasureSpec(width - mSidePaddings * 2,
MeasureSpec.getMode(widthMeasureSpec));
// Don't constrain the height of the children so we know how big they'd like to be
@@ -2117,7 +2140,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void updateContentHeight() {
- final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mSidePaddings;
+ final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
int height = (int) scrimTopPadding;
float previousPaddingRequest = mPaddingBetweenElements;
int numShownItems = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 3e4177d32a34..fa5011e8802f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -40,9 +40,9 @@ public class KeyguardClockPositionAlgorithm {
private static float CLOCK_HEIGHT_WEIGHT = 0.7f;
/**
- * Margin between the bottom of the clock and the notification shade.
+ * Margin between the bottom of the status view and the notification shade.
*/
- private int mClockNotificationsMargin;
+ private int mStatusViewBottomMargin;
/**
* Height of the parent view - display size in px.
@@ -153,8 +153,8 @@ public class KeyguardClockPositionAlgorithm {
* Refreshes the dimension values.
*/
public void loadDimens(Resources res) {
- mClockNotificationsMargin = res.getDimensionPixelSize(
- R.dimen.keyguard_clock_notifications_margin);
+ mStatusViewBottomMargin = res.getDimensionPixelSize(
+ R.dimen.keyguard_status_view_bottom_margin);
mContainerTopPadding =
res.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) / 2;
@@ -181,7 +181,7 @@ public class KeyguardClockPositionAlgorithm {
mNotificationStackHeight = notificationStackHeight;
mPanelExpansion = panelExpansion;
mHeight = parentHeight;
- mKeyguardStatusHeight = keyguardStatusHeight;
+ mKeyguardStatusHeight = keyguardStatusHeight + mStatusViewBottomMargin;
mUserSwitchHeight = userSwitchHeight;
mUserSwitchPreferredY = userSwitchPreferredY;
mHasCustomClock = hasCustomClock;
@@ -221,40 +221,15 @@ public class KeyguardClockPositionAlgorithm {
public float getMinStackScrollerPadding() {
return mBypassEnabled ? mUnlockedStackScrollerPadding
- : mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin;
- }
-
- private int getMaxClockY() {
- return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin;
+ : mMinTopMargin + mKeyguardStatusHeight;
}
private int getExpandedPreferredClockY() {
return mMinTopMargin + mUserSwitchHeight;
}
- /**
- * Vertically align the clock and the shade in the available space considering only
- * a percentage of the clock height defined by {@code CLOCK_HEIGHT_WEIGHT}.
- * @return Clock Y in pixels.
- */
- public int getExpandedClockPosition() {
- final int availableHeight = mMaxShadeBottom - mMinTopMargin;
- final int containerCenter = mMinTopMargin + availableHeight / 2;
-
- float y = containerCenter
- - (mKeyguardStatusHeight + mUserSwitchHeight) * CLOCK_HEIGHT_WEIGHT
- - mClockNotificationsMargin - mNotificationStackHeight / 2;
- if (y < mMinTopMargin) {
- y = mMinTopMargin;
- }
-
- // Don't allow the clock base to be under half of the screen
- final float maxClockY = getMaxClockY();
- if (y > maxClockY) {
- y = maxClockY;
- }
-
- return (int) y;
+ public int getLockscreenStatusViewHeight() {
+ return mKeyguardStatusHeight;
}
private int getClockY(float panelExpansion, float darkAmount) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 6b864c9c35df..41af80e02b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -602,6 +602,10 @@ public class NotificationIconAreaController implements
updateAodIconColors();
}
+ public int getHeight() {
+ return mAodIcons == null ? 0 : mAodIcons.getHeight();
+ }
+
public void appearAodIcons() {
if (mAodIcons == null) {
return;
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 aaddfca4b685..f461d944d2c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1260,7 +1260,7 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScrollLayoutController.getIntrinsicContentHeight(),
expandedFraction,
totalHeight,
- mKeyguardStatusViewController.getHeight(),
+ mKeyguardStatusViewController.getLockscreenHeight(),
userIconHeight,
userSwitcherPreferredY, hasCustomClock(),
hasVisibleNotifications, darkamount, mOverStretchAmount,
@@ -2669,14 +2669,6 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
protected int getMaxPanelHeight() {
- if (mKeyguardBypassController.getBypassEnabled() && mBarState == KEYGUARD) {
- return getMaxPanelHeightBypass();
- } else {
- return getMaxPanelHeightNonBypass();
- }
- }
-
- private int getMaxPanelHeightNonBypass() {
int min = mStatusBarMinHeight;
if (!(mBarState == KEYGUARD)
&& mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) {
@@ -2701,16 +2693,6 @@ public class NotificationPanelViewController extends PanelViewController {
return maxHeight;
}
- private int getMaxPanelHeightBypass() {
- int position =
- mClockPositionAlgorithm.getExpandedClockPosition()
- + mKeyguardStatusViewController.getHeight();
- if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() != 0) {
- position += mShelfHeight / 2.0f + mDarkIconSize / 2.0f;
- }
- return position;
- }
-
public boolean isInSettings() {
return mQsExpanded;
}
@@ -2782,11 +2764,8 @@ public class NotificationPanelViewController extends PanelViewController {
maxHeight += mNotificationStackScrollLayoutController.getTopPaddingOverflow();
if (mBarState == KEYGUARD) {
- int
- minKeyguardPanelBottom =
- mClockPositionAlgorithm.getExpandedClockPosition()
- + mKeyguardStatusViewController.getHeight()
- + mNotificationStackScrollLayoutController.getIntrinsicContentHeight();
+ int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight()
+ + mNotificationStackScrollLayoutController.getIntrinsicContentHeight();
return Math.max(maxHeight, minKeyguardPanelBottom);
} else {
return maxHeight;
@@ -3336,7 +3315,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) {
// The expandedHeight is always the full panel Height when bypassing
- expandedHeight = getMaxPanelHeightNonBypass();
+ expandedHeight = getMaxPanelHeight();
}
mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight);
updateKeyguardBottomAreaAlpha();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 7a1e5cf1770b..cfcea9684c3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -551,11 +551,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
*/
public void setNotificationsBounds(float left, float top, float right, float bottom) {
if (mClipsQsScrim) {
- // notification scrim's rounded corners are anti-aliased, but clipping of the QS scrim
- // can't be and it's causing jagged corners. That's why notification scrim needs
- // to overlap QS scrim by one pixel - both vertically (top - 1) and
- // horizontally (left - 1 and right + 1), see: b/186644628
- mNotificationsScrim.setDrawableBounds(left - 1, top - 1, right + 1, bottom);
+ // notification scrim's rounded corners are anti-aliased, but clipping of the QS/behind
+ // scrim can't be and it's causing jagged corners. That's why notification scrim needs
+ // to overlap QS scrim by one pixel horizontally (left - 1 and right + 1)
+ // see: b/186644628
+ mNotificationsScrim.setDrawableBounds(left - 1, top, right + 1, bottom);
mScrimBehind.setBottomEdgePosition((int) top);
} else {
mNotificationsScrim.setDrawableBounds(left, top, right, bottom);
@@ -1242,6 +1242,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
pw.println(mDefaultScrimAlpha);
pw.print(" mExpansionFraction=");
pw.println(mPanelExpansion);
+
+ pw.print(" mState.getMaxLightRevealScrimAlpha=");
+ pw.println(mState.getMaxLightRevealScrimAlpha());
}
public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index e52e1fa5f39f..06811932ac0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -197,7 +197,7 @@ public enum ScrimState {
}
@Override
- public float getBehindAlpha() {
+ public float getMaxLightRevealScrimAlpha() {
return mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f;
}
@@ -220,18 +220,11 @@ public enum ScrimState {
mBlankScreen = mDisplayRequiresBlanking;
mAnimationDuration = mWakeLockScreenSensorActive
? ScrimController.ANIMATION_DURATION_LONG : ScrimController.ANIMATION_DURATION;
-
- // Wake sensor will show the wallpaper, let's fade from black. Otherwise it will
- // feel like the screen is flashing if the wallpaper is light.
- if (mWakeLockScreenSensorActive && previousState == AOD) {
- updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
- }
}
-
@Override
- public float getBehindAlpha() {
+ public float getMaxLightRevealScrimAlpha() {
return mWakeLockScreenSensorActive ? ScrimController.WAKE_SENSOR_SCRIM_ALPHA
- : AOD.getBehindAlpha();
+ : AOD.getMaxLightRevealScrimAlpha();
}
},
@@ -351,6 +344,10 @@ public enum ScrimState {
return mBehindAlpha;
}
+ public float getMaxLightRevealScrimAlpha() {
+ return 1f;
+ }
+
public float getNotifAlpha() {
return mNotifAlpha;
}
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 5d2fe523c803..3f07785520cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1473,9 +1473,7 @@ public class StatusBar extends SystemUI implements DemoMode,
* @param why the reason for the wake up
*/
public void wakeUpIfDozing(long time, View where, String why) {
- if (mDozing && !(mKeyguardViewMediator.isAnimatingScreenOff()
- || mUnlockedScreenOffAnimationController
- .isScreenOffLightRevealAnimationPlaying())) {
+ if (mDozing && !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
mPowerManager.wakeUp(
time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
@@ -4444,6 +4442,8 @@ public class StatusBar extends SystemUI implements DemoMode,
} else {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
}
+ updateLightRevealScrimVisibility();
+
Trace.endSection();
}
@@ -4894,6 +4894,7 @@ public class StatusBar extends SystemUI implements DemoMode,
return;
}
+ mLightRevealScrim.setAlpha(mScrimController.getState().getMaxLightRevealScrimAlpha());
if (mFeatureFlags.useNewLockscreenAnimations()
&& (mDozeParameters.getAlwaysOn() || mDozeParameters.isQuickPickupEnabled())) {
mLightRevealScrim.setVisibility(View.VISIBLE);
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 52bf2d577776..9a04d39c4e9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -172,7 +172,8 @@ class UnlockedScreenOffAnimationController @Inject constructor(
// 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) {
+ if (!this::statusBar.isInitialized ||
+ statusBar.notificationPanelViewController.isFullyExpanded) {
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index ce080752b5cc..2ac5c1eeae8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -387,15 +387,8 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
int qsTypeIcon = 0;
IconState qsIcon = null;
CharSequence description = null;
- // Mobile icon will only be shown in the statusbar in 2 scenarios
- // 1. Mobile is the default network, and it is validated
- // 2. Mobile is the default network, it is not validated and there is no other
- // non-Carrier WiFi networks available.
- boolean maybeShowIcons = (mCurrentState.inetCondition == 1)
- || (mCurrentState.inetCondition == 0
- && !mNetworkController.isNonCarrierWifiNetworkAvailable());
// Only send data sim callbacks to QS.
- if (mCurrentState.dataSim && mCurrentState.isDefault && maybeShowIcons) {
+ if (mCurrentState.dataSim && mCurrentState.isDefault) {
qsTypeIcon =
(showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.qsDataType : 0;
qsIcon = new IconState(mCurrentState.enabled
@@ -408,7 +401,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
boolean activityOut = mCurrentState.dataConnected
&& !mCurrentState.carrierNetworkChangeMode
&& mCurrentState.activityOut;
- showDataIcon &= mCurrentState.dataSim && mCurrentState.isDefault && maybeShowIcons;
+ showDataIcon &= mCurrentState.dataSim && mCurrentState.isDefault;
boolean showTriangle = showDataIcon && !mCurrentState.airplaneMode;
int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.dataType : 0;
showDataIcon |= mCurrentState.roaming;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 753def0b0f1c..2406db3ee58f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -109,17 +109,10 @@ public class WifiSignalController extends
contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
}
if (mProviderModel) {
- // WiFi icon will only be shown in the statusbar in 2 scenarios
- // 1. WiFi is the default network, and it is validated
- // 2. WiFi is the default network, it is not validated and there is no other
- // non-Carrier WiFi networks available.
- boolean maybeShowIcons = (mCurrentState.inetCondition == 1)
- || (mCurrentState.inetCondition == 0
- && !mNetworkController.isNonCarrierWifiNetworkAvailable());
IconState statusIcon = new IconState(
- wifiVisible && maybeShowIcons, getCurrentIconId(), contentDescription);
+ wifiVisible, getCurrentIconId(), contentDescription);
IconState qsIcon = null;
- if ((mCurrentState.isDefault && maybeShowIcons) || (!mNetworkController.isRadioOn()
+ if (mCurrentState.isDefault || (!mNetworkController.isRadioOn()
&& !mNetworkController.isEthernetDefault())) {
qsIcon = new IconState(mCurrentState.connected,
mWifiTracker.isCaptivePortal ? R.drawable.ic_qs_wifi_disconnected
@@ -158,15 +151,8 @@ public class WifiSignalController extends
if (mCurrentState.inetCondition == 0) {
dataContentDescription = mContext.getString(R.string.data_connection_no_internet);
}
- // Mobile icon will only be shown in the statusbar in 2 scenarios
- // 1. Mobile is the default network, and it is validated
- // 2. Mobile is the default network, it is not validated and there is no other
- // non-Carrier WiFi networks available.
- boolean maybeShowIcons = (mCurrentState.inetCondition == 1)
- || (mCurrentState.inetCondition == 0
- && !mNetworkController.isNonCarrierWifiNetworkAvailable());
boolean sbVisible = mCurrentState.enabled && mCurrentState.connected
- && maybeShowIcons && mCurrentState.isDefault;
+ && mCurrentState.isDefault;
IconState statusIcon =
new IconState(sbVisible, getCurrentIconIdForCarrierWifi(), contentDescription);
int typeIcon = sbVisible ? icons.dataType : 0;
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 3af82f91af1c..bc956dc85702 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -45,6 +45,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.shared.tracing.ProtoTraceable;
@@ -114,6 +115,7 @@ public final class WMShell extends SystemUI
private final NavigationModeController mNavigationModeController;
private final ScreenLifecycle mScreenLifecycle;
private final SysUiState mSysUiState;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private final ProtoTracer mProtoTracer;
private final Executor mSysUiMainExecutor;
@@ -121,6 +123,7 @@ public final class WMShell extends SystemUI
private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
+ private WakefulnessLifecycle.Observer mWakefulnessObserver;
@Inject
public WMShell(Context context,
@@ -136,6 +139,7 @@ public final class WMShell extends SystemUI
ScreenLifecycle screenLifecycle,
SysUiState sysUiState,
ProtoTracer protoTracer,
+ WakefulnessLifecycle wakefulnessLifecycle,
@Main Executor sysUiMainExecutor) {
super(context);
mCommandQueue = commandQueue;
@@ -148,6 +152,7 @@ public final class WMShell extends SystemUI
mSplitScreenOptional = splitScreenOptional;
mOneHandedOptional = oneHandedOptional;
mHideDisplayCutoutOptional = hideDisplayCutoutOptional;
+ mWakefulnessLifecycle = wakefulnessLifecycle;
mProtoTracer = protoTracer;
mShellCommandHandler = shellCommandHandler;
mSysUiMainExecutor = sysUiMainExecutor;
@@ -266,21 +271,8 @@ public final class WMShell extends SystemUI
mOneHandedKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
- public void onKeyguardBouncerChanged(boolean bouncer) {
- if (bouncer) {
- oneHanded.stopOneHanded();
- }
- }
-
- @Override
public void onKeyguardVisibilityChanged(boolean showing) {
- if (showing) {
- // When keyguard shown, temperory lock OHM disabled to avoid mis-trigger.
- oneHanded.setLockedDisabled(true /* locked */, false /* enabled */);
- } else {
- // Reset locked.
- oneHanded.setLockedDisabled(false /* locked */, false /* enabled */);
- }
+ oneHanded.onKeyguardVisibilityChanged(showing);
oneHanded.stopOneHanded();
}
@@ -291,6 +283,24 @@ public final class WMShell extends SystemUI
};
mKeyguardUpdateMonitor.registerCallback(mOneHandedKeyguardCallback);
+ mWakefulnessObserver =
+ new WakefulnessLifecycle.Observer() {
+ @Override
+ public void onFinishedWakingUp() {
+ // Reset locked for the case keyguard not shown.
+ oneHanded.setLockedDisabled(false /* locked */, false /* enabled */);
+ }
+
+ @Override
+ public void onStartedGoingToSleep() {
+ oneHanded.stopOneHanded();
+ // When user press power button going to sleep, temperory lock OHM disabled
+ // to avoid mis-trigger.
+ oneHanded.setLockedDisabled(true /* locked */, false /* enabled */);
+ }
+ };
+ mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
+
mScreenLifecycle.addObserver(new ScreenLifecycle.Observer() {
@Override
public void onScreenTurningOff() {
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 a11b9cf357a8..10997fab081f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -209,33 +209,14 @@ public class DozeTriggersTest extends SysuiTestCase {
// WHEN quick pick up is triggered
mTriggers.onSensor(DozeLog.REASON_SENSOR_QUICK_PICKUP, 100, 100, null);
- // THEN device goes into aod (shows clock with black background)
- verify(mMachine).requestState(DOZE_AOD);
+ // THEN request pulse
+ verify(mMachine).requestPulse(anyInt());
// THEN a log is taken that quick pick up was triggered
verify(mUiEventLogger).log(DozingUpdateUiEvent.DOZING_UPDATE_QUICK_PICKUP);
}
@Test
- public void testQuickPickupTimeOutAfterExecutables() {
- // 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(DOZE_AOD);
- verify(mMachine, never()).requestState(DozeMachine.State.DOZE);
-
- // WHEN next executable is run
- mExecutor.advanceClockToLast();
- mExecutor.runAllReady();
-
- // THEN device goes back into DOZE
- verify(mMachine).requestState(DozeMachine.State.DOZE);
-
- // THEN a log is taken that wake up timeout expired
- verify(mUiEventLogger).log(DozingUpdateUiEvent.DOZING_UPDATE_WAKE_TIMEOUT);
- }
-
- @Test
public void testOnSensor_Fingerprint() {
// GIVEN dozing state
when(mMachine.getState()).thenReturn(DOZE_AOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index e20b426907be..66b64708ad24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -82,9 +82,11 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
@Test
public void eventNotEmittedWithoutDevice() {
// WHEN data source emits an event without device data
- mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
// THEN an event isn't emitted
- verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean());
+ verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
+ anyBoolean());
}
@Test
@@ -92,7 +94,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
// WHEN device source emits an event without media data
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// THEN an event isn't emitted
- verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean());
+ verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
+ anyBoolean());
}
@Test
@@ -100,80 +103,95 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
// GIVEN that a device event has already been received
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// WHEN media event is received
- mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
- verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean());
+ verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
+ anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@Test
public void emitEventAfterMediaFirst() {
// GIVEN that media event has already been received
- mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
// WHEN device event is received
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
- verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean());
+ verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
+ anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@Test
public void migrateKeyMediaFirst() {
// GIVEN that media and device info has already been received
- mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
reset(mListener);
// WHEN a key migration event is received
- mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
- verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean());
+ verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
+ anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@Test
public void migrateKeyDeviceFirst() {
// GIVEN that media and device info has already been received
- mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
reset(mListener);
// WHEN a key migration event is received
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
// THEN the listener receives a combined event
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
- verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean());
+ verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
+ anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@Test
public void migrateKeyMediaAfter() {
// GIVEN that media and device info has already been received
- mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
reset(mListener);
// WHEN a second key migration event is received for media
- mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
// THEN the key has already been migrated
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
- verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean());
+ verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
+ anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@Test
public void migrateKeyDeviceAfter() {
// GIVEN that media and device info has already been received
- mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
- mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
reset(mListener);
// WHEN a second key migration event is received for the device
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
// THEN the key has already be migrated
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
- verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean());
+ verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
+ anyBoolean());
assertThat(captor.getValue().getDevice()).isNotNull();
}
@@ -187,7 +205,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
@Test
public void mediaDataRemovedAfterMediaEvent() {
- mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
mManager.onMediaDataRemoved(KEY);
verify(mListener).onMediaDataRemoved(eq(KEY));
}
@@ -202,13 +221,15 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
@Test
public void mediaDataKeyUpdated() {
// GIVEN that device and media events have already been received
- mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
// WHEN the key is changed
- mManager.onMediaDataLoaded("NEW_KEY", KEY, mMediaData, true /* immediately */);
+ mManager.onMediaDataLoaded("NEW_KEY", KEY, mMediaData, true /* immediately */,
+ false /* isSsReactivated */);
// THEN the listener gets a load event with the correct keys
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
verify(mListener).onMediaDataLoaded(
- eq("NEW_KEY"), any(), captor.capture(), anyBoolean());
+ eq("NEW_KEY"), any(), captor.capture(), anyBoolean(), anyBoolean());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
index 17f2a07eb249..d8791867cb45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
@@ -120,7 +120,8 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
// THEN we should tell the listener
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true),
+ eq(false))
}
@Test
@@ -129,7 +130,7 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest)
// THEN we should NOT tell the listener
- verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean())
+ verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyBoolean())
}
@Test
@@ -175,10 +176,12 @@ class MediaDataFilterTest : SysuiTestCase() {
setUser(USER_GUEST)
// THEN we should add back the guest user media
- verify(listener).onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true),
+ eq(false))
// but not the main user's
- verify(listener, never()).onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean())
+ verify(listener, never()).onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean(),
+ anyBoolean())
}
@Test
@@ -245,7 +248,7 @@ class MediaDataFilterTest : SysuiTestCase() {
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
- verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean())
+ verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyBoolean())
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@@ -282,12 +285,15 @@ class MediaDataFilterTest : SysuiTestCase() {
// WHEN we have media that was recently played, but not currently active
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
+ eq(false))
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
- // THEN we should tell listeners to treat the media as active instead
+ // THEN we should tell listeners to treat the media as not active instead
+ verify(listener, never()).onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(),
+ anyBoolean())
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
@@ -299,14 +305,16 @@ class MediaDataFilterTest : SysuiTestCase() {
// WHEN we have media that was recently played, but not currently active
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
+ eq(false))
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
// THEN we should tell listeners to treat the media as active instead
val dataCurrentAndActive = dataCurrent.copy(active = true)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
+ eq(true))
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
// Smartspace update shouldn't be propagated for the empty rec list.
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
@@ -317,14 +325,16 @@ class MediaDataFilterTest : SysuiTestCase() {
// WHEN we have media that was recently played, but not currently active
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
+ eq(false))
// AND we get a smartspace signal
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
// THEN we should tell listeners to treat the media as active instead
val dataCurrentAndActive = dataCurrent.copy(active = true)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
+ eq(true))
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
// Smartspace update should also be propagated but not prioritized.
verify(listener)
@@ -344,11 +354,17 @@ class MediaDataFilterTest : SysuiTestCase() {
fun testOnSmartspaceMediaDataRemoved_usedMediaAndSmartspace_clearsBoth() {
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
+ eq(false))
+
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
+ val dataCurrentAndActive = dataCurrent.copy(active = true)
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
+ eq(true))
+
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrent), eq(true))
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
}
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 3128db423a24..5b4e12463370 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -185,7 +185,8 @@ class MediaDataManagerTest : SysuiTestCase() {
fun testOnMetaDataLoaded_callsListener() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), anyObject(), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), anyObject(), eq(true),
+ eq(false))
}
@Test
@@ -196,7 +197,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value!!.active).isTrue()
}
@@ -215,7 +217,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
val data = mediaDataCaptor.value
assertThat(data.resumption).isFalse()
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
@@ -223,7 +226,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationRemoved(KEY)
// THEN the media data indicates that it is for resumption
verify(listener)
- .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true))
+ .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
}
@@ -236,7 +240,8 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(2)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(2)
verify(listener)
- .onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ .onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
val data = mediaDataCaptor.value
assertThat(data.resumption).isFalse()
val resumableData = data.copy(resumeAction = Runnable {})
@@ -247,7 +252,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationRemoved(KEY)
// THEN the data is for resumption and the key is migrated to the package name
verify(listener)
- .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true))
+ .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
verify(listener, never()).onMediaDataRemoved(eq(KEY))
// WHEN the second is removed
@@ -255,7 +261,8 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the data is for resumption and the second key is removed
verify(listener)
.onMediaDataLoaded(
- eq(PACKAGE_NAME), eq(PACKAGE_NAME), capture(mediaDataCaptor), eq(true))
+ eq(PACKAGE_NAME), eq(PACKAGE_NAME), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
verify(listener).onMediaDataRemoved(eq(KEY_2))
}
@@ -269,7 +276,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
val data = mediaDataCaptor.value
val dataRemoteWithResume = data.copy(resumeAction = Runnable {}, isLocalSession = false)
mediaDataManager.onMediaDataLoaded(KEY, null, dataRemoteWithResume)
@@ -295,7 +303,8 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
// THEN the media data indicates that it is for resumption
verify(listener)
- .onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor), eq(true))
+ .onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
val data = mediaDataCaptor.value
assertThat(data.resumption).isTrue()
assertThat(data.song).isEqualTo(SESSION_TITLE)
@@ -335,7 +344,8 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener)
- .onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ .onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
}
@Test
@@ -414,7 +424,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value!!.lastActive).isAtLeast(currentTime)
}
@@ -431,7 +442,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.setTimedOut(KEY, true, true)
// THEN the last active time is not changed
- verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
}
@@ -442,7 +454,8 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
val data = mediaDataCaptor.value
assertThat(data.resumption).isFalse()
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
@@ -454,7 +467,8 @@ class MediaDataManagerTest : SysuiTestCase() {
// THEN the last active time is not changed
verify(listener)
- .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true))
+ .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value.resumption).isTrue()
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
}
@@ -480,7 +494,8 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
// THEN only the first MAX_COMPACT_ACTIONS are actually set
- verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
+ eq(false))
assertThat(mediaDataCaptor.value.actionsToShowInCompact.size).isEqualTo(
MediaDataManager.MAX_COMPACT_ACTIONS)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
index c6d7e92175eb..b9caab277c4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
@@ -185,7 +185,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
filter.onMediaDataLoaded(KEY, null, mediaData1)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
}
@Test
@@ -207,7 +208,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
}
@Test
@@ -236,7 +238,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
}
@Test
@@ -251,14 +254,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
// WHEN a loaded event is received that matches the local session
filter.onMediaDataLoaded(KEY, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is filtered
verify(mediaListener, never()).onMediaDataLoaded(
- eq(KEY), eq(null), eq(mediaData2), anyBoolean())
+ eq(KEY), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
}
@Test
@@ -274,7 +278,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the event is not filtered because there isn't a notification for the remote
// session.
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
}
@Test
@@ -291,14 +296,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
+ eq(false))
// WHEN a loaded event is received that matches the local session
filter.onMediaDataLoaded(key2, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is filtered
verify(mediaListener, never())
- .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean())
+ .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
// AND there should be a removed event for key2
verify(mediaListener).onMediaDataRemoved(eq(key2))
}
@@ -317,13 +323,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
+ eq(false))
// WHEN a loaded event is received that matches the remote session
filter.onMediaDataLoaded(key2, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), eq(true),
+ eq(false))
}
@Test
@@ -339,13 +347,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
// WHEN a loaded event is received that matches the local session
filter.onMediaDataLoaded(KEY, null, mediaData2)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2), eq(true),
+ eq(false))
}
@Test
@@ -363,7 +373,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the event is not filtered
- verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
+ eq(false))
}
@Test
@@ -385,7 +396,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the key migration event is fired
- verify(mediaListener).onMediaDataLoaded(eq(key2), eq(key1), eq(mediaData2), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(key2), eq(key1), eq(mediaData2), eq(true),
+ eq(false))
}
@Test
@@ -415,12 +427,13 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
fgExecutor.runAllReady()
// THEN the key migration event is filtered
verify(mediaListener, never())
- .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean())
+ .onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
// WHEN a loaded event is received that matches the remote session
filter.onMediaDataLoaded(key2, null, mediaData1)
bgExecutor.runAllReady()
fgExecutor.runAllReady()
// THEN the key migration event is fired
- verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData1), eq(true))
+ verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData1), eq(true),
+ eq(false))
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
index 19ffa4991eaf..b8d018f5f850 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.qs.tileimpl
import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
+import androidx.test.filters.MediumTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -27,7 +27,7 @@ import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidTestingRunner::class)
-@SmallTest
+@MediumTest
class TilesStatesTextTest : SysuiTestCase() {
@Test
@@ -51,4 +51,29 @@ class TilesStatesTextTest : SysuiTestCase() {
assertThat(array.size).isEqualTo(3)
}
+
+ @Test
+ fun testStockTilesSubtitlesMap() {
+ val tiles = mContext.getString(R.string.quick_settings_tiles_stock).split(",")
+ tiles.forEach { spec ->
+ val resName = "${QSTileViewImpl.TILE_STATE_RES_PREFIX}$spec"
+ val resId = mContext.resources.getIdentifier(resName, "array", mContext.packageName)
+
+ assertNotEquals("Missing resource for $resName", 0, resId)
+
+ assertThat(SubtitleArrayMapping.getSubtitleId(spec)).isEqualTo(resId)
+ }
+ }
+
+ @Test
+ fun testStockTilesSubtitlesReturnsDefault_unknown() {
+ assertThat(SubtitleArrayMapping.getSubtitleId("unknown"))
+ .isEqualTo(R.array.tile_states_default)
+ }
+
+ @Test
+ fun testStockTilesSubtitlesReturnsDefault_null() {
+ assertThat(SubtitleArrayMapping.getSubtitleId(null))
+ .isEqualTo(R.array.tile_states_default)
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index e55361e750b1..678b193073c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -312,6 +312,8 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimBehind, true,
mScrimForBubble, false
));
+
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
}
@Test
@@ -321,8 +323,9 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
- mScrimBehind, OPAQUE,
+ mScrimBehind, TRANSPARENT,
mNotificationsScrim, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
assertScrimTinted(Map.of(
mScrimInFront, true,
@@ -340,6 +343,7 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
mScrimBehind, TRANSPARENT));
+ assertEquals(0f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// Pulsing notification should conserve AOD wallpaper.
mScrimController.transitionTo(ScrimState.PULSING);
@@ -348,6 +352,7 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
mScrimBehind, TRANSPARENT));
+ assertEquals(0f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
}
@Test
@@ -359,7 +364,8 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
assertScrimTinted(Map.of(
mScrimInFront, true,
@@ -378,7 +384,8 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
assertScrimTinted(Map.of(
mScrimInFront, true,
@@ -403,13 +410,15 @@ public class ScrimControllerTest extends SysuiTestCase {
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, SEMI_TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// ... and that if we set it while we're in AOD, it does take immediate effect.
mScrimController.setAodFrontScrimAlpha(1f);
assertScrimAlpha(Map.of(
mScrimInFront, OPAQUE,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// ... and make sure we recall the previous front scrim alpha even if we transition away
// for a bit.
@@ -418,7 +427,8 @@ public class ScrimControllerTest extends SysuiTestCase {
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, OPAQUE,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// ... and alpha updates should be completely ignored if always_on is off.
// Passing it forward would mess up the wake-up transition.
@@ -448,23 +458,28 @@ public class ScrimControllerTest extends SysuiTestCase {
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, OPAQUE,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// ... but will take effect after docked
when(mDockManager.isDocked()).thenReturn(true);
mScrimController.transitionTo(ScrimState.KEYGUARD);
mScrimController.setAodFrontScrimAlpha(0.5f);
mScrimController.transitionTo(ScrimState.AOD);
+ finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, SEMI_TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// ... and that if we set it while we're in AOD, it does take immediate effect after docked.
mScrimController.setAodFrontScrimAlpha(1f);
+ finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, OPAQUE,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// Reset value since enums are static.
mScrimController.setAodFrontScrimAlpha(0f);
@@ -480,7 +495,8 @@ public class ScrimControllerTest extends SysuiTestCase {
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
mScrimController.transitionTo(ScrimState.PULSING);
finishAnimationsImmediately();
@@ -489,7 +505,8 @@ public class ScrimControllerTest extends SysuiTestCase {
// Pulse callback should have been invoked
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
assertScrimTinted(Map.of(
mScrimInFront, true,
@@ -503,13 +520,16 @@ public class ScrimControllerTest extends SysuiTestCase {
// Front scrim should be semi-transparent
assertScrimAlpha(Map.of(
mScrimInFront, SEMI_TRANSPARENT,
- mScrimBehind, OPAQUE));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(1f, mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
mScrimController.setWakeLockScreenSensorActive(true);
finishAnimationsImmediately();
assertScrimAlpha(Map.of(
mScrimInFront, SEMI_TRANSPARENT,
- mScrimBehind, SEMI_TRANSPARENT));
+ mScrimBehind, TRANSPARENT));
+ assertEquals(ScrimController.WAKE_SENSOR_SCRIM_ALPHA,
+ mScrimController.getState().getMaxLightRevealScrimAlpha(), 0f);
// Reset value since enums are static.
mScrimController.setAodFrontScrimAlpha(0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 521b958ab891..bd9d1a7fd657 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -238,9 +238,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
mNetworkController.setNoNetworksAvailable(false);
setWifiStateForVcn(true, testSsid);
setWifiLevelForVcn(0);
- // Connected, but still not validated - does not show
- //verifyLastWifiIcon(false, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
- verifyLastMobileDataIndicatorsForVcn(false, 0, 0, false);
+ verifyLastMobileDataIndicatorsForVcn(true, 0, TelephonyIcons.ICON_CWF, false);
mNetworkController.setNoNetworksAvailable(true);
for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
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 ff15d0151ea4..5691660b4882 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -27,6 +27,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.CommandQueue;
@@ -70,6 +71,7 @@ public class WMShellTest extends SysuiTestCase {
@Mock LegacySplitScreen mLegacySplitScreen;
@Mock OneHanded mOneHanded;
@Mock HideDisplayCutout mHideDisplayCutout;
+ @Mock WakefulnessLifecycle mWakefulnessLifecycle;
@Mock ProtoTracer mProtoTracer;
@Mock ShellCommandHandler mShellCommandHandler;
@Mock ShellExecutor mSysUiMainExecutor;
@@ -82,7 +84,8 @@ public class WMShellTest extends SysuiTestCase {
Optional.of(mOneHanded), Optional.of(mHideDisplayCutout),
Optional.of(mShellCommandHandler), mCommandQueue, mConfigurationController,
mKeyguardUpdateMonitor, mNavigationModeController,
- mScreenLifecycle, mSysUiState, mProtoTracer, mSysUiMainExecutor);
+ mScreenLifecycle, mSysUiState, mProtoTracer, mWakefulnessLifecycle,
+ mSysUiMainExecutor);
}
@Test
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 241a0dbac758..f63198866b08 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -872,18 +872,32 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
"userId=" + userId);
}
+ final int resolvedUserId;
+ final List<AccessibilityServiceInfo> serviceInfos;
synchronized (mLock) {
// We treat calls from a profile as if made by its parent as profiles
// share the accessibility state of the parent. The call below
// performs the current profile parent resolution.
- final int resolvedUserId = mSecurityPolicy
+ resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
+ serviceInfos = new ArrayList<>(
+ getUserStateLocked(resolvedUserId).mInstalledServices);
+ }
- if (Binder.getCallingPid() == OWN_PROCESS_ID) {
- return new ArrayList<>(getUserStateLocked(resolvedUserId).mInstalledServices);
+ if (Binder.getCallingPid() == OWN_PROCESS_ID) {
+ return serviceInfos;
+ }
+ final PackageManagerInternal pm = LocalServices.getService(
+ PackageManagerInternal.class);
+ final int callingUid = Binder.getCallingUid();
+ for (int i = serviceInfos.size() - 1; i >= 0; i--) {
+ final AccessibilityServiceInfo serviceInfo = serviceInfos.get(i);
+ if (pm.filterAppAccess(serviceInfo.getComponentName().getPackageName(), callingUid,
+ resolvedUserId)) {
+ serviceInfos.remove(i);
}
- return getUserStateLocked(resolvedUserId).mInstalledServices;
}
+ return serviceInfos;
}
@Override
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 05131d44b01e..906edb30ff12 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -753,9 +753,19 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
return notMatch;
}));
+ restartBleScan();
}
void onAssociationPreRemove(Association association) {
+ if (association.isNotifyOnDeviceNearby()) {
+ ServiceConnector<ICompanionDeviceService> serviceConnector =
+ mDeviceListenerServiceConnectors.forUser(association.getUserId())
+ .get(association.getPackageName());
+ if (serviceConnector != null) {
+ serviceConnector.unbind();
+ }
+ }
+
String deviceProfile = association.getDeviceProfile();
if (deviceProfile != null) {
Association otherAssociationWithDeviceProfile = find(
@@ -787,16 +797,6 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
}
}
-
- if (association.isNotifyOnDeviceNearby()) {
- ServiceConnector<ICompanionDeviceService> serviceConnector =
- mDeviceListenerServiceConnectors.forUser(association.getUserId())
- .get(association.getPackageName());
- if (serviceConnector != null) {
- serviceConnector.unbind();
- restartBleScan();
- }
- }
}
private void updateSpecialAccessPermissionForAssociatedPackage(Association association) {
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index 49469cc8a597..1e32129dcee1 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -16,6 +16,7 @@
package com.android.server.appop;
+import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE;
import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG;
import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME;
@@ -58,7 +59,9 @@ import com.android.internal.util.XmlUtils;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.time.Duration;
@@ -138,6 +141,7 @@ final class DiscreteRegistry {
private static final String TAG_HISTORY = "h";
private static final String ATTR_VERSION = "v";
+ private static final String ATTR_LARGEST_CHAIN_ID = "lc";
private static final int CURRENT_VERSION = 1;
private static final String TAG_UID = "u";
@@ -182,6 +186,16 @@ final class DiscreteRegistry {
DiscreteRegistry(Object inMemoryLock) {
mInMemoryLock = inMemoryLock;
+ synchronized (mOnDiskLock) {
+ mDiscreteAccessDir = new File(
+ new File(Environment.getDataSystemDirectory(), "appops"),
+ "discrete");
+ createDiscreteAccessDirLocked();
+ int largestChainId = readLargestChainIdFromDiskLocked();
+ synchronized (mInMemoryLock) {
+ mDiscreteOps = new DiscreteOps(largestChainId);
+ }
+ }
}
void systemReady() {
@@ -190,15 +204,6 @@ final class DiscreteRegistry {
setDiscreteHistoryParameters(p);
});
setDiscreteHistoryParameters(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_PRIVACY));
- synchronized (mOnDiskLock) {
- synchronized (mInMemoryLock) {
- mDiscreteAccessDir = new File(
- new File(Environment.getDataSystemDirectory(), "appops"),
- "discrete");
- createDiscreteAccessDirLocked();
- mDiscreteOps = new DiscreteOps();
- }
- }
}
private void setDiscreteHistoryParameters(DeviceConfig.Properties p) {
@@ -251,7 +256,7 @@ final class DiscreteRegistry {
DiscreteOps discreteOps;
synchronized (mInMemoryLock) {
discreteOps = mDiscreteOps;
- mDiscreteOps = new DiscreteOps();
+ mDiscreteOps = new DiscreteOps(discreteOps.mChainIdOffset);
mCachedOps = null;
}
deleteOldDiscreteHistoryFilesLocked();
@@ -275,6 +280,50 @@ final class DiscreteRegistry {
return;
}
+ private int readLargestChainIdFromDiskLocked() {
+ final File[] files = mDiscreteAccessDir.listFiles();
+ if (files != null && files.length > 0) {
+ File latestFile = null;
+ long latestFileTimestamp = 0;
+ for (File f : files) {
+ final String fileName = f.getName();
+ if (!fileName.endsWith(DISCRETE_HISTORY_FILE_SUFFIX)) {
+ continue;
+ }
+ long timestamp = Long.valueOf(fileName.substring(0,
+ fileName.length() - DISCRETE_HISTORY_FILE_SUFFIX.length()));
+ if (latestFileTimestamp < timestamp) {
+ latestFile = f;
+ latestFileTimestamp = timestamp;
+ }
+ }
+ if (latestFile == null) {
+ return 0;
+ }
+ FileInputStream stream;
+ try {
+ stream = new FileInputStream(latestFile);
+ } catch (FileNotFoundException e) {
+ return 0;
+ }
+ try {
+ TypedXmlPullParser parser = Xml.resolvePullParser(stream);
+ XmlUtils.beginDocument(parser, TAG_HISTORY);
+
+ final int largestChainId = parser.getAttributeInt(null, ATTR_LARGEST_CHAIN_ID, 0);
+ return largestChainId;
+ } catch (Throwable t) {
+ return 0;
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) { }
+ }
+ } else {
+ return 0;
+ }
+ }
+
private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) {
synchronized (mOnDiskLock) {
long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff,
@@ -301,7 +350,7 @@ final class DiscreteRegistry {
void clearHistory() {
synchronized (mOnDiskLock) {
synchronized (mInMemoryLock) {
- mDiscreteOps = new DiscreteOps();
+ mDiscreteOps = new DiscreteOps(0);
}
clearOnDiskHistoryLocked();
}
@@ -341,6 +390,10 @@ final class DiscreteRegistry {
: new String[]{AppOpsManager.opToPublicName(dumpOp)};
discreteOps.filter(0, Instant.now().toEpochMilli(), filter, uidFilter, packageNameFilter,
opNamesFilter, attributionTagFilter, OP_FLAGS_ALL);
+ pw.print(prefix);
+ pw.print("Largest chain id: ");
+ pw.print(mDiscreteOps.mLargestChainId);
+ pw.println();
discreteOps.dump(pw, sdf, date, prefix, nDiscreteOps);
}
@@ -351,14 +404,14 @@ final class DiscreteRegistry {
}
private DiscreteOps getAllDiscreteOps() {
- DiscreteOps discreteOps = new DiscreteOps();
+ DiscreteOps discreteOps = new DiscreteOps(0);
synchronized (mOnDiskLock) {
synchronized (mInMemoryLock) {
discreteOps.merge(mDiscreteOps);
}
if (mCachedOps == null) {
- mCachedOps = new DiscreteOps();
+ mCachedOps = new DiscreteOps(0);
readDiscreteOpsFromDisk(mCachedOps);
}
discreteOps.merge(mCachedOps);
@@ -368,9 +421,13 @@ final class DiscreteRegistry {
private final class DiscreteOps {
ArrayMap<Integer, DiscreteUidOps> mUids;
+ int mChainIdOffset;
+ int mLargestChainId;
- DiscreteOps() {
+ DiscreteOps(int chainIdOffset) {
mUids = new ArrayMap<>();
+ mChainIdOffset = chainIdOffset;
+ mLargestChainId = chainIdOffset;
}
boolean isEmpty() {
@@ -378,6 +435,7 @@ final class DiscreteRegistry {
}
void merge(DiscreteOps other) {
+ mLargestChainId = max(mLargestChainId, other.mLargestChainId);
int nUids = other.mUids.size();
for (int i = 0; i < nUids; i++) {
int uid = other.mUids.keyAt(i);
@@ -390,6 +448,17 @@ final class DiscreteRegistry {
@Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
@AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
+ if (attributionChainId != ATTRIBUTION_CHAIN_ID_NONE) {
+ attributionChainId += mChainIdOffset;
+ if (attributionChainId < 0) {
+ attributionChainId -= mChainIdOffset;
+ mChainIdOffset = 0;
+ mLargestChainId = attributionChainId;
+ }
+ if (attributionChainId > mLargestChainId) {
+ mLargestChainId = attributionChainId;
+ }
+ }
getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags,
uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
}
@@ -442,6 +511,7 @@ final class DiscreteRegistry {
out.startDocument(null, true);
out.startTag(null, TAG_HISTORY);
out.attributeInt(null, ATTR_VERSION, CURRENT_VERSION);
+ out.attributeInt(null, ATTR_LARGEST_CHAIN_ID, mLargestChainId);
int nUids = mUids.size();
for (int i = 0; i < nUids; i++) {
@@ -476,8 +546,13 @@ final class DiscreteRegistry {
}
private void readFromFile(File f, long beginTimeMillis) {
+ FileInputStream stream;
+ try {
+ stream = new FileInputStream(f);
+ } catch (FileNotFoundException e) {
+ return;
+ }
try {
- FileInputStream stream = new FileInputStream(f);
TypedXmlPullParser parser = Xml.resolvePullParser(stream);
XmlUtils.beginDocument(parser, TAG_HISTORY);
@@ -487,7 +562,6 @@ final class DiscreteRegistry {
if (version != CURRENT_VERSION) {
throw new IllegalStateException("Dropping unsupported discrete history " + f);
}
-
int depth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, depth)) {
if (TAG_UID.equals(parser.getName())) {
@@ -498,8 +572,12 @@ final class DiscreteRegistry {
} catch (Throwable t) {
Slog.e(TAG, "Failed to read file " + f.getName() + " " + t.getMessage() + " "
+ Arrays.toString(t.getStackTrace()));
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
}
-
}
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index dd5df503d936..62472b5f1d75 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -209,6 +209,7 @@ final class HistoricalRegistry {
mMode = other.mMode;
mBaseSnapshotInterval = other.mBaseSnapshotInterval;
mIntervalCompressionMultiplier = other.mIntervalCompressionMultiplier;
+ mDiscreteRegistry = other.mDiscreteRegistry;
}
void systemReady(@NonNull ContentResolver resolver) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
index 66142bff0453..0ae2e381cf14 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
@@ -46,6 +46,8 @@ final class AidlConversionUtils {
return BiometricFingerprintConstants.FINGERPRINT_ERROR_UNABLE_TO_REMOVE;
} else if (aidlError == Error.VENDOR) {
return BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
+ } else if (aidlError == Error.BAD_CALIBRATION) {
+ return BiometricFingerprintConstants.FINGERPRINT_ERROR_BAD_CALIBARTION;
} else {
return BiometricFingerprintConstants.FINGERPRINT_ERROR_UNKNOWN;
}
@@ -78,8 +80,7 @@ final class AidlConversionUtils {
// No framework constant available
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
} else if (aidlAcquiredInfo == AcquiredInfo.IMMOBILE) {
- // No framework constant available
- return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
+ return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
} else if (aidlAcquiredInfo == AcquiredInfo.RETRYING_CAPTURE) {
// No framework constant available
return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
index 160736433112..8d777e1c2787 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
@@ -124,10 +124,12 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId());
pm.incrementAuthForUser(getTargetUserId(), authenticated);
- try {
- getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception when sending onDetected", e);
+ if (getListener() != null) {
+ try {
+ getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when sending onDetected", e);
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 184ddae9699d..88f88a8439cc 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -19,6 +19,8 @@ package com.android.server.display;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
+import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
import android.os.Environment;
import android.os.PowerManager;
import android.text.TextUtils;
@@ -86,6 +88,9 @@ public class DisplayDeviceConfig {
// The details of the proximity sensor associated with this display.
private final SensorData mProximitySensor = new SensorData();
+ private final List<RefreshRateLimitation> mRefreshRateLimitations =
+ new ArrayList<>(2 /*initialCapacity*/);
+
// Nits and backlight values that are loaded from either the display device config file, or
// config.xml. These are the raw values and just used for the dumpsys
private float[] mRawNits;
@@ -306,6 +311,10 @@ public class DisplayDeviceConfig {
return hbmData;
}
+ public List<RefreshRateLimitation> getRefreshRateLimitations() {
+ return mRefreshRateLimitations;
+ }
+
@Override
public String toString() {
String str = "DisplayDeviceConfig{"
@@ -329,6 +338,7 @@ public class DisplayDeviceConfig {
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
+ ", mAmbientLightSensor=" + mAmbientLightSensor
+ ", mProximitySensor=" + mProximitySensor
+ + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
+ "}";
return str;
}
@@ -647,6 +657,13 @@ public class DisplayDeviceConfig {
mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
+ final RefreshRateRange rr = hbm.getRefreshRate_all();
+ if (rr != null) {
+ final float min = rr.getMinimum().floatValue();
+ final float max = rr.getMaximum().floatValue();
+ mRefreshRateLimitations.add(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE, min, max));
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index bff39a932105..182a038d10f7 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -63,6 +63,7 @@ import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
+import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
import android.hardware.display.DisplayViewport;
import android.hardware.display.DisplayedContentSample;
@@ -130,6 +131,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
@@ -2111,6 +2113,11 @@ public final class DisplayManagerService extends SystemService {
DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED);
}
+ private DisplayDevice getDeviceForDisplayLocked(int displayId) {
+ final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ return display == null ? null : display.getPrimaryDisplayDeviceLocked();
+ }
+
private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
@@ -3295,6 +3302,19 @@ public final class DisplayManagerService extends SystemService {
}
return null;
}
+
+ @Override
+ public List<RefreshRateLimitation> getRefreshRateLimitations(int displayId) {
+ final DisplayDeviceConfig config;
+ synchronized (mSyncRoot) {
+ final DisplayDevice device = getDeviceForDisplayLocked(displayId);
+ if (device == null) {
+ return null;
+ }
+ config = device.getDisplayDeviceConfig();
+ }
+ return config.getRefreshRateLimitations();
+ }
}
class DesiredDisplayModeSpecsObserver
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 2364a3c7c2ed..83fc9665f192 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -16,6 +16,8 @@
package com.android.server.display;
+import static android.hardware.display.DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
@@ -26,8 +28,10 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.net.Uri;
@@ -102,6 +106,7 @@ public class DisplayModeDirector {
private final DisplayObserver mDisplayObserver;
private final UdfpsObserver mUdfpsObserver;
private final SensorObserver mSensorObserver;
+ private final HbmObserver mHbmObserver;
private final DeviceConfigInterface mDeviceConfig;
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
@@ -127,7 +132,7 @@ public class DisplayModeDirector {
private int mModeSwitchingType = DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) {
- this(context, handler, new RealInjector());
+ this(context, handler, new RealInjector(context));
}
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
@@ -143,11 +148,13 @@ public class DisplayModeDirector {
mDisplayObserver = new DisplayObserver(context, handler);
mBrightnessObserver = new BrightnessObserver(context, handler);
mUdfpsObserver = new UdfpsObserver();
- mSensorObserver = new SensorObserver(context, (displayId, priority, vote) -> {
+ final BallotBox ballotBox = (displayId, priority, vote) -> {
synchronized (mLock) {
updateVoteLocked(displayId, priority, vote);
}
- });
+ };
+ mSensorObserver = new SensorObserver(context, ballotBox);
+ mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler());
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
mDeviceConfig = injector.getDeviceConfig();
mAlwaysRespectAppRequest = false;
@@ -165,6 +172,7 @@ public class DisplayModeDirector {
mDisplayObserver.observe();
mBrightnessObserver.observe(sensorManager);
mSensorObserver.observe();
+ mHbmObserver.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.
@@ -596,6 +604,7 @@ public class DisplayModeDirector {
mBrightnessObserver.dumpLocked(pw);
mUdfpsObserver.dumpLocked(pw);
mSensorObserver.dumpLocked(pw);
+ mHbmObserver.dumpLocked(pw);
}
}
@@ -938,13 +947,16 @@ public class DisplayModeDirector {
// user seeing the display flickering when the switches occur.
public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8;
+ // High-brightness-mode may need a specific range of refresh-rates to function properly.
+ public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 9;
+
// The proximity sensor needs the refresh rate to be locked in order to function, so this is
// set to a high priority.
- public static final int PRIORITY_PROXIMITY = 9;
+ public static final int PRIORITY_PROXIMITY = 10;
// The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
// to function, so this needs to be the highest priority of all votes.
- public static final int PRIORITY_UDFPS = 10;
+ public static final int PRIORITY_UDFPS = 11;
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
@@ -1021,29 +1033,30 @@ public class DisplayModeDirector {
public static String priorityToString(int priority) {
switch (priority) {
+ case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
+ return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE";
+ case PRIORITY_APP_REQUEST_MAX_REFRESH_RATE:
+ return "PRIORITY_APP_REQUEST_MAX_REFRESH_RATE";
+ case PRIORITY_APP_REQUEST_SIZE:
+ return "PRIORITY_APP_REQUEST_SIZE";
case PRIORITY_DEFAULT_REFRESH_RATE:
return "PRIORITY_DEFAULT_REFRESH_RATE";
case PRIORITY_FLICKER_REFRESH_RATE:
return "PRIORITY_FLICKER_REFRESH_RATE";
case PRIORITY_FLICKER_REFRESH_RATE_SWITCH:
return "PRIORITY_FLICKER_REFRESH_RATE_SWITCH";
- case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
- return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE";
- case PRIORITY_APP_REQUEST_MAX_REFRESH_RATE:
- return "PRIORITY_APP_REQUEST_MAX_REFRESH_RATE";
- case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
- return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE";
- case PRIORITY_APP_REQUEST_SIZE:
- return "PRIORITY_APP_REQUEST_SIZE";
- case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE:
- return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
+ case PRIORITY_HIGH_BRIGHTNESS_MODE:
+ return "PRIORITY_HIGH_BRIGHTNESS_MODE";
+ case PRIORITY_PROXIMITY:
+ return "PRIORITY_PROXIMITY";
case PRIORITY_LOW_POWER_MODE:
return "PRIORITY_LOW_POWER_MODE";
case PRIORITY_UDFPS:
return "PRIORITY_UDFPS";
- case PRIORITY_PROXIMITY:
- return "PRIORITY_PROXIMITY";
-
+ case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
+ return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE";
+ case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE:
+ return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
default:
return Integer.toString(priority);
}
@@ -2155,6 +2168,75 @@ public class DisplayModeDirector {
}
}
+ /**
+ * Listens to DisplayManager for HBM status and applies any refresh-rate restrictions for
+ * HBM that are associated with that display. Restrictions are retrieved from
+ * DisplayManagerInternal but originate in the display-device-config file.
+ */
+ private static class HbmObserver implements DisplayManager.DisplayListener {
+ private final BallotBox mBallotBox;
+ private final Handler mHandler;
+ private final SparseBooleanArray mHbmEnabled = new SparseBooleanArray();
+ private final Injector mInjector;
+
+ private DisplayManagerInternal mDisplayManagerInternal;
+
+ HbmObserver(Injector injector, BallotBox ballotBox, Handler handler) {
+ mInjector = injector;
+ mBallotBox = ballotBox;
+ mHandler = handler;
+ }
+
+ public void observe() {
+ mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
+ mInjector.registerDisplayListener(this, mHandler,
+ DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+ | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED);
+ }
+
+ @Override
+ public void onDisplayAdded(int displayId) {}
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, null);
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ final BrightnessInfo info = mInjector.getBrightnessInfo(displayId);
+ if (info == null) {
+ // Display no longer there. Assume we'll get an onDisplayRemoved very soon.
+ return;
+ }
+ final boolean isHbmEnabled =
+ info.highBrightnessMode != BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
+ if (isHbmEnabled == mHbmEnabled.get(displayId)) {
+ // no change, ignore.
+ return;
+ }
+ Vote vote = null;
+ mHbmEnabled.put(displayId, isHbmEnabled);
+ if (isHbmEnabled) {
+ final List<RefreshRateLimitation> limits =
+ mDisplayManagerInternal.getRefreshRateLimitations(displayId);
+ for (int i = 0; limits != null && i < limits.size(); i++) {
+ final RefreshRateLimitation limitation = limits.get(i);
+ if (limitation.type == REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE) {
+ vote = Vote.forRefreshRates(limitation.range.min, limitation.range.max);
+ break;
+ }
+ }
+ }
+ mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, vote);
+ }
+
+ void dumpLocked(PrintWriter pw) {
+ pw.println(" HbmObserver");
+ pw.println(" mHbmEnabled: " + mHbmEnabled);
+ }
+ }
+
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
public DeviceConfigDisplaySettings() {
}
@@ -2309,10 +2391,21 @@ public class DisplayModeDirector {
void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer);
+
+ void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
+ Handler handler, long flags);
+
+ BrightnessInfo getBrightnessInfo(int displayId);
}
@VisibleForTesting
static class RealInjector implements Injector {
+ private final Context mContext;
+ private DisplayManager mDisplayManager;
+
+ RealInjector(Context context) {
+ mContext = context;
+ }
@Override
@NonNull
@@ -2339,6 +2432,28 @@ public class DisplayModeDirector {
cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
observer, UserHandle.USER_SYSTEM);
}
+
+ @Override
+ public void registerDisplayListener(DisplayManager.DisplayListener listener,
+ Handler handler, long flags) {
+ getDisplayManager().registerDisplayListener(listener, handler, flags);
+ }
+
+ @Override
+ public BrightnessInfo getBrightnessInfo(int displayId) {
+ final Display display = getDisplayManager().getDisplay(displayId);
+ if (display != null) {
+ return display.getBrightnessInfo();
+ }
+ return null;
+ }
+
+ private DisplayManager getDisplayManager() {
+ if (mDisplayManager == null) {
+ mDisplayManager = mContext.getSystemService(DisplayManager.class);
+ }
+ return mDisplayManager;
+ }
}
interface BallotBox {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a3f3a3a503c8..9151e4e1779a 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -140,6 +140,7 @@ import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.ITransientNotificationCallback;
import android.app.IUriGrantsManager;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -549,6 +550,8 @@ public class NotificationManagerService extends SystemService {
// Used for rate limiting toasts by package.
private MultiRateLimiter mToastRateLimiter;
+ private KeyguardManager mKeyguardManager;
+
// The last key in this list owns the hardware.
ArrayList<String> mLights = new ArrayList<>();
@@ -2008,6 +2011,11 @@ public class NotificationManagerService extends SystemService {
}
@VisibleForTesting
+ void setKeyguardManager(KeyguardManager keyguardManager) {
+ mKeyguardManager = keyguardManager;
+ }
+
+ @VisibleForTesting
ShortcutHelper getShortcutHelper() {
return mShortcutHelper;
}
@@ -2653,6 +2661,7 @@ public class NotificationManagerService extends SystemService {
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
mZenModeHelper.onSystemReady();
RoleObserver roleObserver = new RoleObserver(getContext(),
getContext().getSystemService(RoleManager.class),
@@ -7388,7 +7397,6 @@ public class NotificationManagerService extends SystemService {
boolean beep = false;
boolean blink = false;
- final Notification notification = record.getSbn().getNotification();
final String key = record.getKey();
// Should this notification make noise, vibe, or use the LED?
@@ -7410,7 +7418,7 @@ public class NotificationManagerService extends SystemService {
if (!record.isUpdate
&& record.getImportance() > IMPORTANCE_MIN
&& !suppressedByDnd) {
- sendAccessibilityEvent(notification, record.getSbn().getPackageName());
+ sendAccessibilityEvent(record);
sentAccessibilityEvent = true;
}
@@ -7433,7 +7441,7 @@ public class NotificationManagerService extends SystemService {
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
if (!sentAccessibilityEvent) {
- sendAccessibilityEvent(notification, record.getSbn().getPackageName());
+ sendAccessibilityEvent(record);
sentAccessibilityEvent = true;
}
if (DBG) Slog.v(TAG, "Interrupting!");
@@ -8261,17 +8269,30 @@ public class NotificationManagerService extends SystemService {
return (x < low) ? low : ((x > high) ? high : x);
}
- void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
+ void sendAccessibilityEvent(NotificationRecord record) {
if (!mAccessibilityManager.isEnabled()) {
return;
}
- AccessibilityEvent event =
+ final Notification notification = record.getNotification();
+ final CharSequence packageName = record.getSbn().getPackageName();
+ final AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
event.setPackageName(packageName);
event.setClassName(Notification.class.getName());
- event.setParcelableData(notification);
- CharSequence tickerText = notification.tickerText;
+ final int visibilityOverride = record.getPackageVisibilityOverride();
+ final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
+ ? notification.visibility : visibilityOverride;
+ final int userId = record.getUser().getIdentifier();
+ final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
+ if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
+ // Emit the public version if we're on the lockscreen and this notification isn't
+ // publicly visible.
+ event.setParcelableData(notification.publicVersion);
+ } else {
+ event.setParcelableData(notification);
+ }
+ final CharSequence tickerText = notification.tickerText;
if (!TextUtils.isEmpty(tickerText)) {
event.getText().add(tickerText);
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 5fd8e3c6e302..44f7d8869322 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -177,8 +177,10 @@ public class PackageDexOptimizer {
private int performDexOptLI(AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
String[] targetInstructionSets, CompilerStats.PackageStats packageStats,
PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
+ // ClassLoader only refers non-native (jar) shared libraries and must ignore
+ // native (so) shared libraries. See also LoadedApk#createSharedLibraryLoader().
final List<SharedLibraryInfo> sharedLibraries = pkgSetting.getPkgState()
- .getUsesLibraryInfos();
+ .getNonNativeUsesLibraryInfos();
final String[] instructionSets = targetInstructionSets != null ?
targetInstructionSets : getAppDexInstructionSets(
AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 60a757118222..d2ed08f66944 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -157,6 +157,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
private volatile boolean mOkToSendBroadcasts = false;
private volatile boolean mBypassNextStagedInstallerCheck = false;
+ private volatile boolean mBypassNextAllowedApexUpdateCheck = false;
/**
* File storing persisted {@link #mSessions} metadata.
@@ -650,6 +651,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
throw new IllegalArgumentException(
"Non-staged APEX session doesn't support INSTALL_ENABLE_ROLLBACK");
}
+ if (isCalledBySystemOrShell(callingUid) || mBypassNextAllowedApexUpdateCheck) {
+ params.installFlags |= PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK;
+ } else {
+ // Only specific APEX updates (installed through ADB, or for CTS tests) can disable
+ // allowed APEX update check.
+ params.installFlags &= ~PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK;
+ }
}
if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0
@@ -674,6 +682,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
mBypassNextStagedInstallerCheck = false;
+ mBypassNextAllowedApexUpdateCheck = false;
+
if (!params.isMultiPackage) {
// Only system components can circumvent runtime permissions when installing.
if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
@@ -1106,6 +1116,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
mBypassNextStagedInstallerCheck = value;
}
+ @Override
+ public void bypassNextAllowedApexUpdateCheck(boolean value) {
+ if (!isCalledBySystemOrShell(Binder.getCallingUid())) {
+ throw new SecurityException("Caller not allowed to bypass allowed apex update check");
+ }
+ mBypassNextAllowedApexUpdateCheck = value;
+ }
+
/**
* Set an installer to allow for the unlimited silent updates.
*/
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 4b0eb6546888..c33130037027 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -147,6 +147,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -2238,6 +2239,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
.setAdmin(mInstallSource.installerPackageName)
.write();
}
+
+ // Check if APEX update is allowed. We do this check in handleInstall, since this is one of
+ // the places that:
+ // * Shared between staged and non-staged APEX update flows.
+ // * Only is called after boot completes.
+ // The later is important, since isApexUpdateAllowed check depends on the
+ // ModuleInfoProvider, which is only populated after device has booted.
+ if (isApexSession()) {
+ boolean checkApexUpdateAllowed =
+ (params.installFlags & PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK)
+ == 0;
+ synchronized (mLock) {
+ if (checkApexUpdateAllowed && !isApexUpdateAllowed(mPackageName)) {
+ onSessionValidationFailure(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
+ "Update of APEX package " + mPackageName + " is not allowed");
+ return;
+ }
+ }
+ }
+
if (params.isStaged) {
mStagingManager.commitSession(mStagedSession);
// TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even
@@ -2776,6 +2797,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return sessionContains((s) -> !s.isApexSession());
}
+ private boolean isApexUpdateAllowed(String apexPackageName) {
+ return mPm.getModuleInfo(apexPackageName, 0) != null
+ || SystemConfig.getInstance().getAllowedPartnerApexes().contains(apexPackageName);
+ }
+
/**
* Validate apex install.
* <p>
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 364ac42985f1..b0a662b3514d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -436,8 +436,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.nio.charset.StandardCharsets;
import java.security.DigestException;
import java.security.DigestInputStream;
@@ -1918,14 +1920,65 @@ public class PackageManagerService extends IPackageManager.Stub
}
/**
- * A computer provides the functional interface to the snapshot.
+ * A {@link Computer} provides a set of functions that can operate on live data or snapshot
+ * data. At this time, the {@link Computer} is implemented by the
+ * {@link ComputerEngine}, which is in turn extended by {@link ComputerLocked}.
+ *
+ * New functions must be added carefully.
+ * <ol>
+ * <li> New functions must be true functions with respect to data collected in a
+ * {@link Snapshot}. Such data may never be modified from inside a {@link Computer}
+ * function.
+ * </li>
+ *
+ * <li> A new function must be implemented in {@link ComputerEngine}.
+ * </li>
+ *
+ * <li> A new function must be overridden in {@link ComputerLocked} if the function
+ * cannot safely access live data without holding the PackageManagerService lock. The
+ * form of the {@link ComputerLocked} function must be a single call to the
+ * {@link ComputerEngine} implementation, wrapped in a <code>synchronized</code>
+ * block. Functions in {@link ComputerLocked} should never include any other code.
+ * </li>
+ *
+ * Care must be taken when deciding if a function should be overridden in
+ * {@link ComputerLocked}. The complex lock relationships of PackageManagerService
+ * and other managers (like PermissionManager) mean deadlock is possible. On the
+ * other hand, not overriding in {@link ComputerLocked} may leave a function walking
+ * unstable data.
+ *
+ * To coax developers to consider such issues carefully, all methods in
+ * {@link Computer} must be annotated with <code>@LiveImplementation(override =
+ * MANDATORY)</code> or <code>LiveImplementation(locked = NOT_ALLOWED)</code>. A unit
+ * test verifies the annotation and that the annotation corresponds to the code in
+ * {@link ComputerEngine} and {@link ComputerLocked}.
*/
- private interface Computer {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected interface Computer {
+
+ /**
+ * Every method must be annotated.
+ */
+ @Target({ ElementType.METHOD })
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface LiveImplementation {
+ // A Computer method must be annotated with one of the following values:
+ // MANDATORY - the method must be overridden in ComputerEngineLive. The
+ // format of the override is a call to the super method, wrapped in a
+ // synchronization block.
+ // NOT_ALLOWED - the method may not appear in the live computer. It must
+ // be final in the ComputerEngine.
+ int MANDATORY = 1;
+ int NOT_ALLOWED = 2;
+ int override() default MANDATORY;
+ String rationale() default "";
+ }
/**
* Administrative statistics: record that the snapshot has been used. Every call
* to use() increments the usage counter.
*/
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
default void use() {
}
@@ -1933,95 +1986,154 @@ public class PackageManagerService extends IPackageManager.Stub
* Fetch the snapshot usage counter.
* @return The number of times this snapshot was used.
*/
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
default int getUsed() {
return 0;
}
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
@NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid,
int userId, boolean resolveForStart, boolean allowDynamicSplits);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
@NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
@NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
int flags, int userId, int callingUid, boolean includeInstantApps);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
@NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
String resolvedType, int flags, int filterCallingUid, int userId,
boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
String instantAppPkgName);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ActivityInfo getActivityInfo(ComponentName component, int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
int filterCallingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
AndroidPackage getPackage(String packageName);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
AndroidPackage getPackage(int uid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
int filterCallingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ApplicationInfo getApplicationInfo(String packageName, int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
int filterCallingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ComponentName getDefaultHomeActivity(int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType,
int flags, int sourceUserId, int parentUserId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
Intent getHomeIntent();
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
String resolvedType, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
boolean resolveForStart, int userId, Intent intent);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageInfo getPackageInfo(String packageName, int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageInfo getPackageInfoInternal(String packageName, long versionCode, int flags,
int filterCallingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageSetting getPackageSetting(String packageName);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
PackageSetting getPackageSettingInternal(String packageName, int callingUid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
int sourceUserId, int targetUserId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ServiceInfo getServiceInfo(ComponentName component, int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
String getInstantAppPackageName(int callingUid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
String resolveExternalPackageNameLPr(AndroidPackage pkg);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
String resolveInternalPackageNameLPr(String packageName, long versionCode);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
String[] getPackagesForUid(int uid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
UserInfo getProfileParent(int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean canViewInstantApps(int callingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
int flags);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isCallerSameApp(String packageName, int uid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isComponentVisibleToInstantApp(@Nullable ComponentName component);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
@ComponentType int type);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
String resolvedType, int flags);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isInstantApp(String packageName, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
@Nullable ComponentName component, @ComponentType int componentType, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int checkUidPermission(String permName, int uid);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForApplication(int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForComponent(int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForPackage(int flags, int userId);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
boolean isImplicitImageCaptureIntentAndNotSetByDpc);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message);
+ @LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell,
boolean requirePermissionWhenSameUser, String message);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
SigningDetails getSigningDetails(@NonNull String packageName);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
SigningDetails getSigningDetails(int uid);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
boolean filterAppAccess(String packageName, int callingUid, int userId);
+ @LiveImplementation(override = LiveImplementation.MANDATORY)
void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
}
@@ -2030,7 +2142,8 @@ public class PackageManagerService extends IPackageManager.Stub
* is entirely self-contained - it has no implicit access to
* PackageManagerService.
*/
- private static class ComputerEngine implements Computer {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected static class ComputerEngine implements Computer {
// The administrative use counter.
private int mUsed = 0;
@@ -2076,7 +2189,7 @@ public class PackageManagerService extends IPackageManager.Stub
// PackageManagerService attributes that are primitives are referenced through the
// pms object directly. Primitives are the only attributes so referenced.
protected final PackageManagerService mService;
- protected boolean safeMode() {
+ private boolean safeMode() {
return mService.mSafeMode;
}
protected ComponentName resolveComponentName() {
@@ -2130,18 +2243,18 @@ public class PackageManagerService extends IPackageManager.Stub
/**
* Record that the snapshot was used.
*/
- public void use() {
+ public final void use() {
mUsed++;
}
/**
* Return the usage counter.
*/
- public int getUsed() {
+ public final int getUsed() {
return mUsed;
}
- public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
+ public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
int filterCallingUid, int userId, boolean resolveForStart,
boolean allowDynamicSplits) {
@@ -2240,14 +2353,14 @@ public class PackageManagerService extends IPackageManager.Stub
resolveForStart, userId, intent);
}
- public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
+ public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
return queryIntentActivitiesInternal(
intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
}
- public @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
+ public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
String resolvedType, int flags, int userId, int callingUid,
boolean includeInstantApps) {
if (!mUserManager.exists(userId)) return Collections.emptyList();
@@ -2471,7 +2584,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
- public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+ public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
}
@@ -2481,7 +2594,7 @@ public class PackageManagerService extends IPackageManager.Stub
* to clearing. Because it can only be provided by trusted code, its value can be
* trusted and will be used as-is; unlike userId which will be validated by this method.
*/
- public ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
+ public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId);
@@ -2535,8 +2648,8 @@ public class PackageManagerService extends IPackageManager.Stub
return pkg;
}
- public ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
- int filterCallingUid, int userId) {
+ public final ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName,
+ int flags, int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.getPackageLPr(packageName);
if (ps != null) {
@@ -2563,7 +2676,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
- public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+ public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
}
@@ -2573,7 +2686,7 @@ public class PackageManagerService extends IPackageManager.Stub
* to clearing. Because it can only be provided by trusted code, its value can be
* trusted and will be used as-is; unlike userId which will be validated by this method.
*/
- public ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+ public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForApplication(flags, userId);
@@ -2765,7 +2878,7 @@ public class PackageManagerService extends IPackageManager.Stub
* Report the 'Home' activity which is currently set as "always use this one". If non is set
* then reports the most likely home activity or null if there are more than one.
*/
- public ComponentName getDefaultHomeActivity(int userId) {
+ public final ComponentName getDefaultHomeActivity(int userId) {
List<ResolveInfo> allHomeCandidates = new ArrayList<>();
ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
if (cn != null) {
@@ -2793,7 +2906,7 @@ public class PackageManagerService extends IPackageManager.Stub
return lastComponent;
}
- public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
+ public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
int userId) {
Intent intent = getHomeIntent();
List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
@@ -2822,7 +2935,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
- public CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
+ public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
String resolvedType, int flags, int sourceUserId, int parentUserId) {
if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
sourceUserId)) {
@@ -2868,15 +2981,15 @@ public class PackageManagerService extends IPackageManager.Stub
return result;
}
- public Intent getHomeIntent() {
+ public final Intent getHomeIntent() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addCategory(Intent.CATEGORY_DEFAULT);
return intent;
}
- public List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
- String resolvedType, int userId) {
+ public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
+ Intent intent, String resolvedType, int userId) {
CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
if (resolver != null) {
return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
@@ -2895,7 +3008,8 @@ public class PackageManagerService extends IPackageManager.Stub
* @param intent
* @return A filtered list of resolved activities.
*/
- public List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
+ public final List<ResolveInfo> applyPostResolutionFilter(
+ @NonNull List<ResolveInfo> resolveInfos,
String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
boolean resolveForStart, int userId, Intent intent) {
final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
@@ -3041,7 +3155,7 @@ public class PackageManagerService extends IPackageManager.Stub
return resolveInfos;
}
- public List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
+ private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
int userId) {
final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
@@ -3188,7 +3302,7 @@ public class PackageManagerService extends IPackageManager.Stub
return result;
}
- public PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
+ public final PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
if (!mUserManager.exists(userId)) return null;
if (ps == null) {
return null;
@@ -3258,7 +3372,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
+ public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
flags, Binder.getCallingUid(), userId);
}
@@ -3269,7 +3383,7 @@ public class PackageManagerService extends IPackageManager.Stub
* to clearing. Because it can only be provided by trusted code, its value can be
* trusted and will be used as-is; unlike userId which will be validated by this method.
*/
- public PackageInfo getPackageInfoInternal(String packageName, long versionCode,
+ public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
int flags, int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForPackage(flags, userId);
@@ -3340,7 +3454,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Nullable
- public PackageSetting getPackageSetting(String packageName) {
+ public final PackageSetting getPackageSetting(String packageName) {
return getPackageSettingInternal(packageName, Binder.getCallingUid());
}
@@ -3350,7 +3464,7 @@ public class PackageManagerService extends IPackageManager.Stub
return mSettings.getPackageLPr(packageName);
}
- public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
+ public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
return ParceledListSlice.emptyList();
@@ -3489,7 +3603,7 @@ public class PackageManagerService extends IPackageManager.Stub
return new CrossProfileDomainInfo(forwardingInfo, highestApprovalLevel);
}
- public ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
+ public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
int sourceUserId, int targetUserId) {
ResolveInfo forwardingResolveInfo = new ResolveInfo();
final long ident = Binder.clearCallingIdentity();
@@ -3601,7 +3715,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
- public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
+ public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
if (!mUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId);
@@ -3635,7 +3749,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Nullable
- public SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
+ public final SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
return getSharedLibraryInfo(name, version, mSharedLibraries, null);
}
@@ -3671,7 +3785,7 @@ public class PackageManagerService extends IPackageManager.Stub
return ownerUid;
}
- public String resolveExternalPackageNameLPr(AndroidPackage pkg) {
+ public final String resolveExternalPackageNameLPr(AndroidPackage pkg) {
if (pkg.getStaticSharedLibName() != null) {
return pkg.getManifestPackageName();
}
@@ -3745,7 +3859,7 @@ public class PackageManagerService extends IPackageManager.Stub
return packageName;
}
- public String resolveInternalPackageNameLPr(String packageName, long versionCode) {
+ public final String resolveInternalPackageNameLPr(String packageName, long versionCode) {
final int callingUid = Binder.getCallingUid();
return resolveInternalPackageNameInternalLocked(packageName, versionCode,
callingUid);
@@ -3766,7 +3880,7 @@ public class PackageManagerService extends IPackageManager.Stub
* calls to invalidateGetPackagesForUidCache() to locate the points at
* which the cache is invalidated.
*/
- public String[] getPackagesForUid(int uid) {
+ public final String[] getPackagesForUid(int uid) {
return getPackagesForUidInternal(uid, Binder.getCallingUid());
}
@@ -3807,7 +3921,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
- public UserInfo getProfileParent(int userId) {
+ public final UserInfo getProfileParent(int userId) {
final long identity = Binder.clearCallingIdentity();
try {
return mUserManager.getProfileParent(userId);
@@ -3837,7 +3951,7 @@ public class PackageManagerService extends IPackageManager.Stub
* <li>The calling application is the default app prediction service.</li>
* </ol>
*/
- public boolean canViewInstantApps(int callingUid, int userId) {
+ public final boolean canViewInstantApps(int callingUid, int userId) {
if (callingUid < Process.FIRST_APPLICATION_UID) {
return true;
}
@@ -3861,8 +3975,8 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
- public boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
- int flags) {
+ public final boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid,
+ int userId, int flags) {
// Callers can access only the libs they depend on, otherwise they need to explicitly
// ask for the shared libraries given the caller is allowed to access all static libs.
if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
@@ -3945,13 +4059,13 @@ public class PackageManagerService extends IPackageManager.Stub
== PackageManager.PERMISSION_GRANTED;
}
- public boolean isCallerSameApp(String packageName, int uid) {
+ public final boolean isCallerSameApp(String packageName, int uid) {
AndroidPackage pkg = mPackages.get(packageName);
return pkg != null
&& UserHandle.getAppId(uid) == pkg.getUid();
}
- public boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
+ public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
return true;
}
@@ -3964,7 +4078,7 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
- public boolean isComponentVisibleToInstantApp(
+ public final boolean isComponentVisibleToInstantApp(
@Nullable ComponentName component, @ComponentType int type) {
if (type == TYPE_ACTIVITY) {
final ParsedActivity activity = mComponentResolver.getActivity(component);
@@ -4012,13 +4126,13 @@ public class PackageManagerService extends IPackageManager.Stub
* @return {@code true} if the intent is a camera intent and the persistent preferred
* activity was not set by the DPC.
*/
- public boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
- String resolvedType, int flags) {
+ public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
+ int userId, String resolvedType, int flags) {
return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm(
intent, userId, resolvedType, flags);
}
- public boolean isInstantApp(String packageName, int userId) {
+ public final boolean isInstantApp(String packageName, int userId) {
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
false /* checkShell */, "isInstantApp");
@@ -4026,7 +4140,7 @@ public class PackageManagerService extends IPackageManager.Stub
return isInstantAppInternal(packageName, userId, callingUid);
}
- public boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
+ public final boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
int callingUid) {
if (HIDE_EPHEMERAL_APIS) {
return false;
@@ -4160,7 +4274,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- public boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
+ public final boolean isSameProfileGroup(@UserIdInt int callerUserId,
+ @UserIdInt int userId) {
final long identity = Binder.clearCallingIdentity();
try {
return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
@@ -4187,7 +4302,8 @@ public class PackageManagerService extends IPackageManager.Stub
*
* @see #canViewInstantApps(int, int)
*/
- public boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
+ public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
+ int callingUid,
@Nullable ComponentName component, @ComponentType int componentType, int userId) {
// if we're in an isolated process, get the real calling UID
if (Process.isIsolated(callingUid)) {
@@ -4247,7 +4363,7 @@ public class PackageManagerService extends IPackageManager.Stub
/**
* @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
*/
- public boolean shouldFilterApplicationLocked(
+ public final boolean shouldFilterApplicationLocked(
@Nullable PackageSetting ps, int callingUid, int userId) {
return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
}
@@ -4255,8 +4371,8 @@ public class PackageManagerService extends IPackageManager.Stub
/**
* @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
*/
- public boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
- int userId) {
+ public final boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus,
+ int callingUid, int userId) {
boolean filterApp = true;
for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index),
@@ -4280,7 +4396,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
// NOTE: Can't remove without a major refactor. Keep around for now.
- public int checkUidPermission(String permName, int uid) {
+ public final int checkUidPermission(String permName, int uid) {
return mPermissionManager.checkUidPermission(uid, permName);
}
@@ -4330,21 +4446,21 @@ public class PackageManagerService extends IPackageManager.Stub
/**
* Update given flags when being used to request {@link ApplicationInfo}.
*/
- public int updateFlagsForApplication(int flags, int userId) {
+ public final int updateFlagsForApplication(int flags, int userId) {
return updateFlagsForPackage(flags, userId);
}
/**
* Update given flags when being used to request {@link ComponentInfo}.
*/
- public int updateFlagsForComponent(int flags, int userId) {
+ public final int updateFlagsForComponent(int flags, int userId) {
return updateFlags(flags, userId);
}
/**
* Update given flags when being used to request {@link PackageInfo}.
*/
- public int updateFlagsForPackage(int flags, int userId) {
+ public final int updateFlagsForPackage(int flags, int userId) {
final boolean isCallerSystemUser = UserHandle.getCallingUserId()
== UserHandle.USER_SYSTEM;
if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
@@ -4380,14 +4496,14 @@ public class PackageManagerService extends IPackageManager.Stub
* action and a {@code android.intent.category.BROWSABLE} category</li>
* </ul>
*/
- public int updateFlagsForResolve(int flags, int userId, int callingUid,
+ public final int updateFlagsForResolve(int flags, int userId, int callingUid,
boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
return updateFlagsForResolve(flags, userId, callingUid,
wantInstantApps, false /*onlyExposedExplicitly*/,
isImplicitImageCaptureIntentAndNotSetByDpc);
}
- public int updateFlagsForResolve(int flags, int userId, int callingUid,
+ public final int updateFlagsForResolve(int flags, int userId, int callingUid,
boolean wantInstantApps, boolean onlyExposedExplicitly,
boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
// Safe mode means we shouldn't match any third-party components
@@ -4429,7 +4545,7 @@ public class PackageManagerService extends IPackageManager.Stub
* @param checkShell whether to prevent shell from access if there's a debugging restriction
* @param message the message to log on security exception
*/
- public void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
+ public final void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message) {
if (userId < 0) {
throw new IllegalArgumentException("Invalid userId " + userId);
@@ -4467,7 +4583,7 @@ public class PackageManagerService extends IPackageManager.Stub
* @param checkShell whether to prevent shell from access if there's a debugging restriction
* @param message the message to log on security exception
*/
- public void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
+ public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message) {
enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false,
message);
@@ -4484,7 +4600,7 @@ public class PackageManagerService extends IPackageManager.Stub
* reference the same user.
* @param message the message to log on security exception
*/
- public void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
+ public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell,
boolean requirePermissionWhenSameUser, String message) {
if (userId < 0) {
@@ -4736,31 +4852,14 @@ public class PackageManagerService extends IPackageManager.Stub
}
/**
- * The live computer differs from the ComputerEngine in the methods that fetch data
- * from PackageManagerService.
- **/
- private static class ComputerEngineLive extends ComputerEngine {
- ComputerEngineLive(Snapshot args) {
- super(args);
- }
- protected ComponentName resolveComponentName() {
- return mService.mResolveComponentName;
- }
- protected ActivityInfo instantAppInstallerActivity() {
- return mService.mInstantAppInstallerActivity;
- }
- protected ApplicationInfo androidApplication() {
- return mService.mAndroidApplication;
- }
- }
-
- /**
- * This subclass is the external interface to the live computer. For each
- * interface, it takes the PM lock and then delegates to the live
- * computer engine. This is required because there are no locks taken in
- * the engine itself.
+ * This subclass is the external interface to the live computer. Some internal helper
+ * methods are overridden to fetch live data instead of snapshot data. For each
+ * Computer interface that is overridden in this class, the override takes the PM lock
+ * and then delegates to the live computer engine. This is required because there are
+ * no locks taken in the engine itself.
*/
- private static class ComputerLocked extends ComputerEngineLive {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected static class ComputerLocked extends ComputerEngine {
private final Object mLock;
ComputerLocked(Snapshot args) {
@@ -4768,18 +4867,17 @@ public class PackageManagerService extends IPackageManager.Stub
mLock = mService.mLock;
}
- /**
- * Explicilty snapshot {@link Settings#mPackages} for cases where the caller must not lock
- * in order to get package data. It is expected that the caller locks itself to be able
- * to block on changes to the package data and bring itself up to date once the change
- * propagates to it. Use with heavy caution.
- * @return
- */
- private Map<String, PackageSetting> snapshotPackageSettings() {
- return mSettings.snapshot().mPackages;
+ protected final ComponentName resolveComponentName() {
+ return mService.mResolveComponentName;
+ }
+ protected final ActivityInfo instantAppInstallerActivity() {
+ return mService.mInstantAppInstallerActivity;
+ }
+ protected final ApplicationInfo androidApplication() {
+ return mService.mAndroidApplication;
}
- public @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
+ public final @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
String resolvedType, int flags, int userId, int callingUid,
String instantAppPkgName) {
synchronized (mLock) {
@@ -4787,8 +4885,8 @@ public class PackageManagerService extends IPackageManager.Stub
callingUid, instantAppPkgName);
}
}
- public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
- String resolvedType, int flags, int filterCallingUid, int userId,
+ public final @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
+ Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
String instantAppPkgName) {
synchronized (mLock) {
@@ -4797,31 +4895,31 @@ public class PackageManagerService extends IPackageManager.Stub
instantAppPkgName);
}
}
- public ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
+ public final ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
int filterCallingUid, int userId) {
synchronized (mLock) {
return super.getActivityInfoInternalBody(component, flags, filterCallingUid,
userId);
}
}
- public AndroidPackage getPackage(String packageName) {
+ public final AndroidPackage getPackage(String packageName) {
synchronized (mLock) {
return super.getPackage(packageName);
}
}
- public AndroidPackage getPackage(int uid) {
+ public final AndroidPackage getPackage(int uid) {
synchronized (mLock) {
return super.getPackage(uid);
}
}
- public ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
+ public final ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
int filterCallingUid, int userId) {
synchronized (mLock) {
return super.getApplicationInfoInternalBody(packageName, flags, filterCallingUid,
userId);
}
}
- public ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
+ public final ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
Intent intent, int matchFlags, List<ResolveInfo> candidates,
CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
synchronized (mLock) {
@@ -4829,49 +4927,49 @@ public class PackageManagerService extends IPackageManager.Stub
matchFlags, candidates, xpDomainInfo, userId, debug);
}
}
- public PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
+ public final PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
int flags, int filterCallingUid, int userId) {
synchronized (mLock) {
return super.getPackageInfoInternalBody(packageName, versionCode, flags,
filterCallingUid, userId);
}
}
- public PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
+ public final PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
synchronized (mLock) {
return super.getPackageSettingInternal(packageName, callingUid);
}
}
- public ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
+ public final ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
int callingUid) {
synchronized (mLock) {
return super.getInstalledPackagesBody(flags, userId, callingUid);
}
}
- public ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
+ public final ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
int callingUid) {
synchronized (mLock) {
return super.getServiceInfoBody(component, flags, userId, callingUid);
}
}
- public String getInstantAppPackageName(int callingUid) {
+ public final String getInstantAppPackageName(int callingUid) {
synchronized (mLock) {
return super.getInstantAppPackageName(callingUid);
}
}
- public String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
+ public final String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
boolean isCallerInstantApp) {
synchronized (mLock) {
return super.getPackagesForUidInternalBody(callingUid, userId, appId,
isCallerInstantApp);
}
}
- public boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
+ public final boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
int callingUid) {
synchronized (mLock) {
return super.isInstantAppInternalBody(packageName, userId, callingUid);
}
}
- public boolean isInstantAppResolutionAllowedBody(Intent intent,
+ public final boolean isInstantAppResolutionAllowedBody(Intent intent,
List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
int flags) {
synchronized (mLock) {
@@ -4879,33 +4977,33 @@ public class PackageManagerService extends IPackageManager.Stub
skipPackageCheck, flags);
}
}
- public int getPackageUidInternal(String packageName, int flags, int userId,
+ public final int getPackageUidInternal(String packageName, int flags, int userId,
int callingUid) {
synchronized (mLock) {
return super.getPackageUidInternal(packageName, flags, userId, callingUid);
}
}
- public SigningDetails getSigningDetails(@NonNull String packageName) {
+ public final SigningDetails getSigningDetails(@NonNull String packageName) {
synchronized (mLock) {
return super.getSigningDetails(packageName);
}
}
- public SigningDetails getSigningDetails(int uid) {
+ public final SigningDetails getSigningDetails(int uid) {
synchronized (mLock) {
return super.getSigningDetails(uid);
}
}
- public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
+ public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
synchronized (mLock) {
return super.filterAppAccess(pkg, callingUid, userId);
}
}
- public boolean filterAppAccess(String packageName, int callingUid, int userId) {
+ public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
synchronized (mLock) {
return super.filterAppAccess(packageName, callingUid, userId);
}
}
- public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
+ public final void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
synchronized (mLock) {
super.dump(type, fd, pw, dumpState);
}
@@ -12700,21 +12798,6 @@ public class PackageManagerService extends IPackageManager.Stub
return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
}
- /**
- * Ask the package manager to compile layouts in the given package.
- */
- @Override
- public boolean compileLayouts(String packageName) {
- AndroidPackage pkg;
- synchronized (mLock) {
- pkg = mPackages.get(packageName);
- if (pkg == null) {
- return false;
- }
- }
- return mViewCompiler.compileLayouts(pkg);
- }
-
/*package*/ boolean performDexOpt(DexoptOptions options) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return false;
@@ -21397,6 +21480,8 @@ public class PackageManagerService extends IPackageManager.Stub
// for the uninstall-updates case and restricted profiles, remember the per-
// user handle installed state
int[] allUsers;
+ final int freezeUser;
+ final SparseArray<Pair<Integer, String>> enabledStateAndCallerPerUser;
/** enabled state of the uninstalled application */
synchronized (mLock) {
uninstalledPs = mSettings.getPackageLPr(packageName);
@@ -21441,16 +21526,23 @@ public class PackageManagerService extends IPackageManager.Stub
}
info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
- }
- final int freezeUser;
- if (isUpdatedSystemApp(uninstalledPs)
- && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
- // We're downgrading a system app, which will apply to all users, so
- // freeze them all during the downgrade
- freezeUser = UserHandle.USER_ALL;
- } else {
- freezeUser = removeUser;
+ if (isUpdatedSystemApp(uninstalledPs)
+ && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
+ // We're downgrading a system app, which will apply to all users, so
+ // freeze them all during the downgrade
+ freezeUser = UserHandle.USER_ALL;
+ enabledStateAndCallerPerUser = new SparseArray<>();
+ for (int i = 0; i < allUsers.length; i++) {
+ PackageUserState userState = uninstalledPs.readUserState(allUsers[i]);
+ Pair<Integer, String> enabledStateAndCaller =
+ new Pair<>(userState.enabled, userState.lastDisableAppCaller);
+ enabledStateAndCallerPerUser.put(allUsers[i], enabledStateAndCaller);
+ }
+ } else {
+ freezeUser = removeUser;
+ enabledStateAndCallerPerUser = null;
+ }
}
synchronized (mInstallLock) {
@@ -21519,6 +21611,19 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
}
+ if (enabledStateAndCallerPerUser != null) {
+ synchronized (mLock) {
+ for (int i = 0; i < allUsers.length; i++) {
+ Pair<Integer, String> enabledStateAndCaller =
+ enabledStateAndCallerPerUser.get(allUsers[i]);
+ getPackageSetting(packageName)
+ .setEnabled(enabledStateAndCaller.first,
+ allUsers[i],
+ enabledStateAndCaller.second);
+ }
+ mSettings.writeAllUsersPackageRestrictionsLPr();
+ }
+ }
}
return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 49559f299fa0..1aa80a953d6c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -307,6 +307,8 @@ class PackageManagerShellCommand extends ShellCommand {
return runLogVisibility();
case "bypass-staged-installer-check":
return runBypassStagedInstallerCheck();
+ case "bypass-allowed-apex-update-check":
+ return runBypassAllowedApexUpdateCheck();
case "set-silent-updates-policy":
return runSetSilentUpdatesPolicy();
default: {
@@ -424,6 +426,20 @@ class PackageManagerShellCommand extends ShellCommand {
}
}
+ private int runBypassAllowedApexUpdateCheck() {
+ final PrintWriter pw = getOutPrintWriter();
+ try {
+ mInterface.getPackageInstaller()
+ .bypassNextAllowedApexUpdateCheck(Boolean.parseBoolean(getNextArg()));
+ return 0;
+ } catch (RemoteException e) {
+ pw.println("Failure ["
+ + e.getClass().getName() + " - "
+ + e.getMessage() + "]");
+ return -1;
+ }
+ }
+
private int uninstallSystemUpdates(String packageName) {
final PrintWriter pw = getOutPrintWriter();
boolean failedUninstalls = false;
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
index 05879ec9545e..fad0aefd3c0a 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
@@ -28,6 +28,7 @@ import com.android.server.pm.PackageSetting;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
/**
* For use by {@link PackageSetting} to maintain functionality that used to exist in
@@ -110,6 +111,10 @@ public class PackageStateUnserialized {
this.overrideSeInfo = other.overrideSeInfo;
}
+ public @NonNull List<SharedLibraryInfo> getNonNativeUsesLibraryInfos() {
+ return getUsesLibraryInfos().stream()
+ .filter((l) -> !l.isNative()).collect(Collectors.toList());
+ }
// Code below generated by codegen v1.0.14.
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index 5b48abb3e1f2..a5969a88008d 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -135,7 +135,10 @@ class LegacyGlobalActions implements DialogInterface.OnDismissListener, DialogIn
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
- context.registerReceiver(mBroadcastReceiver, filter);
+ // By default CLOSE_SYSTEM_DIALOGS broadcast is sent only for current user, which is user
+ // 10 on devices with headless system user enabled.
+ // In order to receive the broadcast, register the broadcast receiver with UserHandle.ALL.
+ context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
mHasTelephony =
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index ed4a7bf107d1..f72adb609f6f 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -961,11 +961,13 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
@Override
public boolean allocateSpaceForUpdate(String packageFile) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
if (!isUpdatableApexSupported()) {
Log.i(TAG, "Updatable Apex not supported, "
+ "allocateSpaceForUpdate does nothing.");
return true;
}
+ final long token = Binder.clearCallingIdentity();
try {
CompressedApexInfoList apexInfoList = getCompressedApexInfoList(packageFile);
ApexManager apexManager = ApexManager.getInstance();
@@ -975,6 +977,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
e.rethrowAsRuntimeException();
} catch (IOException | UnsupportedOperationException e) {
Slog.e(TAG, "Failed to reserve space for compressed apex: ", e);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
return false;
}
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index f7d61367c81e..95a06fcff734 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -453,6 +453,10 @@ public class Vcn extends Handler {
for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
gatewayConnection.updateSubscriptionSnapshot(mLastSnapshot);
}
+
+ // Update the mobile data state after updating the subscription snapshot as a change in
+ // subIds for a subGroup may affect the mobile data state.
+ handleMobileDataToggled();
}
private void handleMobileDataToggled() {
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 4a07c1ac1e39..885f0e4c78ab 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -19,7 +19,10 @@ package com.android.server.vibrator;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IUidObserver;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
@@ -61,6 +64,9 @@ final class VibrationSettings {
private final SettingsObserver mSettingObserver;
@VisibleForTesting
final UidObserver mUidObserver;
+ @VisibleForTesting
+ final UserObserver mUserReceiver;
+
@GuardedBy("mLock")
private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
@@ -94,6 +100,7 @@ final class VibrationSettings {
mContext = context;
mSettingObserver = new SettingsObserver(handler);
mUidObserver = new UidObserver();
+ mUserReceiver = new UserObserver();
VibrationEffect clickEffect = createEffectFromResource(
com.android.internal.R.array.config_virtualKeyVibePattern);
@@ -150,6 +157,7 @@ final class VibrationSettings {
}
});
+ mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED));
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
registerSettingsObserver(Settings.Global.getUriFor(Settings.Global.APPLY_RAMPING_RINGER));
@@ -345,6 +353,7 @@ final class VibrationSettings {
+ ", mLowPowerMode=" + mLowPowerMode
+ ", mZenMode=" + Settings.Global.zenModeToString(mZenMode)
+ ", mProcStatesCache=" + mUidObserver.mProcStatesCache
+ + ", mHapticChannelMaxVibrationAmplitude=" + getHapticChannelMaxVibrationAmplitude()
+ ", mHapticFeedbackIntensity="
+ intensityToString(getCurrentIntensity(VibrationAttributes.USAGE_TOUCH))
+ ", mHapticFeedbackDefaultIntensity="
@@ -403,6 +412,12 @@ final class VibrationSettings {
}
}
+ private float getHapticChannelMaxVibrationAmplitude() {
+ synchronized (mLock) {
+ return mVibrator == null ? Float.NaN : mVibrator.getHapticChannelMaximumAmplitude();
+ }
+ }
+
private int getSystemSetting(String settingName, int defaultValue) {
return Settings.System.getIntForUser(mContext.getContentResolver(),
settingName, defaultValue, UserHandle.USER_CURRENT);
@@ -457,6 +472,17 @@ final class VibrationSettings {
}
}
+ /** Implementation of {@link BroadcastReceiver} to update settings on current user change. */
+ @VisibleForTesting
+ final class UserObserver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+ updateSettings();
+ }
+ }
+ }
+
/** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
@VisibleForTesting
final class UidObserver extends IUidObserver.Stub {
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index 150fde99b706..45d511159e11 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -844,7 +844,12 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
public List<Step> play() {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePrimitivesStep");
try {
- int segmentCount = effect.getSegments().size();
+ // Load the next PrimitiveSegments to create a single compose call to the vibrator,
+ // limited to the vibrator composition maximum size.
+ int limit = controller.getVibratorInfo().getCompositionSizeMax();
+ int segmentCount = limit > 0
+ ? Math.min(effect.getSegments().size(), segmentIndex + limit)
+ : effect.getSegments().size();
List<PrimitiveSegment> primitives = new ArrayList<>();
for (int i = segmentIndex; i < segmentCount; i++) {
VibrationEffectSegment segment = effect.getSegments().get(i);
@@ -896,7 +901,12 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
public List<Step> play() {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePwleStep");
try {
- int segmentCount = effect.getSegments().size();
+ // Load the next RampSegments to create a single composePwle call to the vibrator,
+ // limited to the vibrator PWLE maximum size.
+ int limit = controller.getVibratorInfo().getPwleSizeMax();
+ int segmentCount = limit > 0
+ ? Math.min(effect.getSegments().size(), segmentIndex + limit)
+ : effect.getSegments().size();
List<RampSegment> pwles = new ArrayList<>();
for (int i = segmentIndex; i < segmentCount; i++) {
VibrationEffectSegment segment = effect.getSegments().get(i);
diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java
index 5dceac2d066c..001d5c440d58 100644
--- a/services/core/java/com/android/server/vibrator/VibratorController.java
+++ b/services/core/java/com/android/server/vibrator/VibratorController.java
@@ -30,19 +30,24 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
import libcore.util.NativeAllocationRegistry;
/** Controls a single vibrator. */
final class VibratorController {
private static final String TAG = "VibratorController";
+ // TODO(b/167947076): load suggested range from config
+ private static final int SUGGESTED_FREQUENCY_SAFE_RANGE = 200;
private final Object mLock = new Object();
private final NativeWrapper mNativeWrapper;
- private final VibratorInfo mVibratorInfo;
+ private final VibratorInfo.Builder mVibratorInfoBuilder;
@GuardedBy("mLock")
+ private VibratorInfo mVibratorInfo;
+ @GuardedBy("mLock")
+ private boolean mVibratorInfoLoaded;
+ @GuardedBy("mLock")
private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners =
new RemoteCallbackList<>();
@GuardedBy("mLock")
@@ -66,10 +71,10 @@ final class VibratorController {
NativeWrapper nativeWrapper) {
mNativeWrapper = nativeWrapper;
mNativeWrapper.init(vibratorId, listener);
- // TODO(b/167947076): load suggested range from config
- mVibratorInfo = mNativeWrapper.getInfo(/* suggestedFrequencyRange= */ 200);
- Preconditions.checkNotNull(mVibratorInfo, "Failed to retrieve data for vibrator %d",
- vibratorId);
+ mVibratorInfoBuilder = new VibratorInfo.Builder(vibratorId);
+ mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE,
+ mVibratorInfoBuilder);
+ mVibratorInfo = mVibratorInfoBuilder.build();
}
/** Register state listener for this vibrator. */
@@ -103,7 +108,15 @@ final class VibratorController {
/** Return the {@link VibratorInfo} representing the vibrator controlled by this instance. */
public VibratorInfo getVibratorInfo() {
- return mVibratorInfo;
+ synchronized (mLock) {
+ if (!mVibratorInfoLoaded) {
+ // Try to load the vibrator metadata that has failed in the last attempt.
+ mVibratorInfoLoaded = mNativeWrapper.getInfo(SUGGESTED_FREQUENCY_SAFE_RANGE,
+ mVibratorInfoBuilder);
+ mVibratorInfo = mVibratorInfoBuilder.build();
+ }
+ return mVibratorInfo;
+ }
}
/**
@@ -361,7 +374,8 @@ final class VibratorController {
private static native void alwaysOnDisable(long nativePtr, long id);
- private static native VibratorInfo getInfo(long nativePtr, float suggestedFrequencyRange);
+ private static native boolean getInfo(long nativePtr, float suggestedFrequencyRange,
+ VibratorInfo.Builder infoBuilder);
private long mNativePtr = 0;
@@ -428,9 +442,11 @@ final class VibratorController {
alwaysOnDisable(mNativePtr, id);
}
- /** Return device vibrator metadata. */
- public VibratorInfo getInfo(float suggestedFrequencyRange) {
- return getInfo(mNativePtr, suggestedFrequencyRange);
+ /**
+ * Loads device vibrator metadata and returns true if all metadata was loaded successfully.
+ */
+ public boolean getInfo(float suggestedFrequencyRange, VibratorInfo.Builder infoBuilder) {
+ return getInfo(mNativePtr, suggestedFrequencyRange, infoBuilder);
}
}
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 53f1035ee422..782e18b0250c 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -129,7 +129,9 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -3140,7 +3142,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
- private void writeWallpaperAttributes(TypedXmlSerializer out, String tag,
+
+ @VisibleForTesting
+ void writeWallpaperAttributes(TypedXmlSerializer out, String tag,
WallpaperData wallpaper)
throws IllegalArgumentException, IllegalStateException, IOException {
if (DEBUG) {
@@ -3179,6 +3183,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
out.attributeInt(null, "colorValue" + i, wc.toArgb());
}
}
+
+ int allColorsCount = wallpaper.primaryColors.getAllColors().size();
+ out.attributeInt(null, "allColorsCount", allColorsCount);
+ if (allColorsCount > 0) {
+ int index = 0;
+ for (Map.Entry<Integer, Integer> entry : wallpaper.primaryColors.getAllColors()
+ .entrySet()) {
+ out.attributeInt(null, "allColorsValue" + index, entry.getKey());
+ out.attributeInt(null, "allColorsPopulation" + index, entry.getValue());
+ index++;
+ }
+ }
+
out.attributeInt(null, "colorHints", wallpaper.primaryColors.getColorHints());
}
@@ -3410,7 +3427,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
- private void parseWallpaperAttributes(TypedXmlPullParser parser, WallpaperData wallpaper,
+ @VisibleForTesting
+ void parseWallpaperAttributes(TypedXmlPullParser parser, WallpaperData wallpaper,
boolean keepDimensionHints) throws XmlPullParserException {
final int id = parser.getAttributeInt(null, "id", -1);
if (id != -1) {
@@ -3437,7 +3455,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
wpData.mPadding.right = getAttributeInt(parser, "paddingRight", 0);
wpData.mPadding.bottom = getAttributeInt(parser, "paddingBottom", 0);
int colorsCount = getAttributeInt(parser, "colorsCount", 0);
- if (colorsCount > 0) {
+ int allColorsCount = getAttributeInt(parser, "allColorsCount", 0);
+ if (allColorsCount > 0) {
+ Map<Integer, Integer> allColors = new HashMap<>(allColorsCount);
+ for (int i = 0; i < allColorsCount; i++) {
+ int colorInt = getAttributeInt(parser, "allColorsValue" + i, 0);
+ int population = getAttributeInt(parser, "allColorsPopulation" + i, 0);
+ allColors.put(colorInt, population);
+ }
+ int colorHints = getAttributeInt(parser, "colorHints", 0);
+ wallpaper.primaryColors = new WallpaperColors(allColors, colorHints);
+ } else if (colorsCount > 0) {
Color primary = null, secondary = null, tertiary = null;
for (int i = 0; i < colorsCount; i++) {
Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index ac0665a37c0b..a24319f7a98c 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1542,6 +1542,52 @@ final class AccessibilityController {
mEmbeddedDisplayIdList.add(displayId);
}
+ boolean shellRootIsAbove(WindowState windowState, ShellRoot shellRoot) {
+ int wsLayer = mService.mPolicy.getWindowLayerLw(windowState);
+ int shellLayer = mService.mPolicy.getWindowLayerFromTypeLw(shellRoot.getWindowType(),
+ true);
+ return shellLayer >= wsLayer;
+ }
+
+ int addShellRootsIfAbove(WindowState windowState, ArrayList<ShellRoot> shellRoots,
+ int shellRootIndex, List<WindowInfo> windows, Set<IBinder> addedWindows,
+ Region unaccountedSpace, boolean focusedWindowAdded) {
+ while (shellRootIndex < shellRoots.size()
+ && shellRootIsAbove(windowState, shellRoots.get(shellRootIndex))) {
+ ShellRoot shellRoot = shellRoots.get(shellRootIndex);
+ shellRootIndex++;
+ final WindowInfo info = shellRoot.getWindowInfo();
+ if (info == null) {
+ continue;
+ }
+
+ info.layer = addedWindows.size();
+ windows.add(info);
+ addedWindows.add(info.token);
+ unaccountedSpace.op(info.regionInScreen, unaccountedSpace,
+ Region.Op.REVERSE_DIFFERENCE);
+ if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
+ break;
+ }
+ }
+ return shellRootIndex;
+ }
+
+ private ArrayList<ShellRoot> getSortedShellRoots(
+ SparseArray<ShellRoot> originalShellRoots) {
+ ArrayList<ShellRoot> sortedShellRoots = new ArrayList<>(originalShellRoots.size());
+ for (int i = originalShellRoots.size() - 1; i >= 0; --i) {
+ sortedShellRoots.add(originalShellRoots.valueAt(i));
+ }
+
+ sortedShellRoots.sort((left, right) ->
+ mService.mPolicy.getWindowLayerFromTypeLw(right.getWindowType(), true)
+ - mService.mPolicy.getWindowLayerFromTypeLw(left.getWindowType(),
+ true));
+
+ return sortedShellRoots;
+ }
+
/**
* Check if windows have changed, and send them to the accessibility subsystem if they have.
*
@@ -1601,9 +1647,22 @@ final class AccessibilityController {
final int visibleWindowCount = visibleWindows.size();
HashSet<Integer> skipRemainingWindowsForTasks = new HashSet<>();
+ ArrayList<ShellRoot> shellRoots = getSortedShellRoots(dc.mShellRoots);
+
// Iterate until we figure out what is touchable for the entire screen.
+ int shellRootIndex = 0;
for (int i = visibleWindowCount - 1; i >= 0; i--) {
final WindowState windowState = visibleWindows.valueAt(i);
+ int prevShellRootIndex = shellRootIndex;
+ shellRootIndex = addShellRootsIfAbove(windowState, shellRoots, shellRootIndex,
+ windows, addedWindows, unaccountedSpace, focusedWindowAdded);
+
+ // If a Shell Root was added, it could have accounted for all the space already.
+ if (shellRootIndex > prevShellRootIndex && unaccountedSpace.isEmpty()
+ && focusedWindowAdded) {
+ break;
+ }
+
final Region regionInScreen = new Region();
computeWindowRegionInScreen(windowState, regionInScreen);
@@ -1627,16 +1686,6 @@ final class AccessibilityController {
}
}
- for (int i = dc.mShellRoots.size() - 1; i >= 0; --i) {
- final WindowInfo info = dc.mShellRoots.valueAt(i).getWindowInfo();
- if (info == null) {
- continue;
- }
- info.layer = addedWindows.size();
- windows.add(info);
- addedWindows.add(info.token);
- }
-
// Remove child/parent references to windows that were not added.
final int windowCount = windows.size();
for (int i = 0; i < windowCount; i++) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 79346e057d9d..b156e12a1ce8 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -677,8 +677,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private boolean mInSizeCompatModeForBounds = false;
// Whether the aspect ratio restrictions applied to the activity bounds in applyAspectRatio().
- // TODO(b/182268157): Aspect ratio can also be applie in resolveFixedOrientationConfiguration
- // but that isn't reflected in this boolean.
private boolean mIsAspectRatioApplied = false;
// Bounds populated in resolveFixedOrientationConfiguration when this activity is letterboxed
@@ -5777,10 +5775,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void onStartingWindowDrawn() {
+ boolean wasTaskVisible = false;
if (task != null) {
mSplashScreenStyleEmpty = true;
+ wasTaskVisible = task.getHasBeenVisible();
task.setHasBeenVisible(true);
}
+
+ // The transition may not be executed if the starting process hasn't attached. But if the
+ // starting window is drawn, the transition can start earlier. Exclude finishing and bubble
+ // because it may be a trampoline.
+ if (!wasTaskVisible && mStartingData != null && !finishing && !mLaunchedFromBubble
+ && !mDisplayContent.mAppTransition.isReady()
+ && !mDisplayContent.mAppTransition.isRunning()) {
+ // The pending transition state will be cleared after the transition is started, so
+ // save the state for launching the client later (used by LaunchActivityItem).
+ mStartingData.mIsTransitionForward = mDisplayContent.isNextTransitionForward();
+ mDisplayContent.executeAppTransition();
+ }
}
/** Called when the windows associated app window container are drawn. */
@@ -6493,6 +6505,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|| dc.mChangingContainers.contains(this));
}
+ boolean isTransitionForward() {
+ return (mStartingData != null && mStartingData.mIsTransitionForward)
+ || mDisplayContent.isNextTransitionForward();
+ }
+
private int getAnimationLayer() {
// The leash is parented to the animation layer. We need to preserve the z-order by using
// the prefix order index, but we boost if necessary.
@@ -7247,41 +7264,48 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
- final int parentWidth = parentBounds.width();
- final int parentHeight = parentBounds.height();
- float aspect = Math.max(parentWidth, parentHeight)
- / (float) Math.min(parentWidth, parentHeight);
+ final Rect parentAppBounds = newParentConfig.windowConfiguration.getAppBounds();
+ final Rect containingBounds = new Rect();
+ final Rect containingAppBounds = new Rect();
+ // Need to shrink the containing bounds into a square because the parent orientation does
+ // not match the activity requested orientation.
+ if (forcedOrientation == ORIENTATION_LANDSCAPE) {
+ // Shrink height to match width. Position height within app bounds.
+ final int bottom = Math.min(parentAppBounds.top + parentBounds.width(),
+ parentAppBounds.bottom);
+ containingBounds.set(parentBounds.left, parentAppBounds.top, parentBounds.right,
+ bottom);
+ containingAppBounds.set(parentAppBounds.left, parentAppBounds.top,
+ parentAppBounds.right, bottom);
+ } else {
+ // Shrink width to match height. Position width within app bounds.
+ final int right = Math.min(parentAppBounds.left + parentBounds.height(),
+ parentAppBounds.right);
+ containingBounds.set(parentAppBounds.left, parentBounds.top, right,
+ parentBounds.bottom);
+ containingAppBounds.set(parentAppBounds.left, parentAppBounds.top, right,
+ parentAppBounds.bottom);
+ }
+
+ Rect mTmpFullBounds = new Rect(resolvedBounds);
+ resolvedBounds.set(containingBounds);
// Override from config_fixedOrientationLetterboxAspectRatio or via ADB with
// set-fixed-orientation-letterbox-aspect-ratio.
final float letterboxAspectRatioOverride =
mWmService.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
- aspect = letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
- ? letterboxAspectRatioOverride : aspect;
-
- // Adjust the fixed orientation letterbox bounds to fit the app request aspect ratio in
- // order to use the extra available space.
- final float maxAspectRatio = info.getMaxAspectRatio();
- final float minAspectRatio = info.getMinAspectRatio();
- if (aspect > maxAspectRatio && maxAspectRatio != 0) {
- aspect = maxAspectRatio;
- } else if (aspect < minAspectRatio) {
- aspect = minAspectRatio;
- }
-
- // Store the current bounds to be able to revert to size compat mode values below if needed.
- Rect mTmpFullBounds = new Rect(resolvedBounds);
+ final float desiredAspectRatio =
+ letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
+ ? letterboxAspectRatioOverride : computeAspectRatio(parentBounds);
+ // Apply aspect ratio to resolved bounds
+ mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingAppBounds,
+ containingBounds, desiredAspectRatio, true);
+
+ // Vertically center if orientation is landscape. Bounds will later be horizontally centered
+ // in {@link updateResolvedBoundsHorizontalPosition()} regardless of orientation.
if (forcedOrientation == ORIENTATION_LANDSCAPE) {
- final int height = (int) Math.rint(parentWidth / aspect);
- final int top = parentBounds.centerY() - height / 2;
- resolvedBounds.set(parentBounds.left, top, parentBounds.right, top + height);
- } else {
- final int width = (int) Math.rint(parentHeight / aspect);
- final Rect parentAppBounds = newParentConfig.windowConfiguration.getAppBounds();
- final int left = width <= parentAppBounds.width()
- // Avoid overlapping with the horizontal decor area when possible.
- ? parentAppBounds.left : parentBounds.centerX() - width / 2;
- resolvedBounds.set(left, parentBounds.top, left + width, parentBounds.bottom);
+ final int offsetY = parentBounds.centerY() - resolvedBounds.centerY();
+ resolvedBounds.offset(0, offsetY);
}
if (mCompatDisplayInsets != null) {
@@ -7323,8 +7347,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// then they should be aligned later in #updateResolvedBoundsHorizontalPosition().
if (!mTmpBounds.isEmpty()) {
resolvedBounds.set(mTmpBounds);
- // Exclude the horizontal decor area.
- resolvedBounds.left = parentAppBounds.left;
}
if (!resolvedBounds.isEmpty() && !resolvedBounds.equals(parentBounds)) {
// Compute the configuration based on the resolved bounds. If aspect ratio doesn't
@@ -7385,13 +7407,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mIsAspectRatioApplied =
applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
}
- // If the bounds are restricted by fixed aspect ratio, the resolved bounds should be put in
- // the container app bounds. Otherwise the entire container bounds are available.
- final boolean fillContainer = resolvedBounds.equals(containingBounds);
- if (!fillContainer) {
- // The horizontal position should not cover insets.
- resolvedBounds.left = containingAppBounds.left;
- }
// Use resolvedBounds to compute other override configurations such as appBounds. The bounds
// are calculated in compat container space. The actual position on screen will be applied
@@ -7458,6 +7473,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Align to top of parent (bounds) - this is a UX choice and exclude the horizontal decor
// if needed. Horizontal position is adjusted in updateResolvedBoundsHorizontalPosition.
// Above coordinates are in "@" space, now place "*" and "#" to screen space.
+ final boolean fillContainer = resolvedBounds.equals(containingBounds);
final int screenPosX = fillContainer ? containerBounds.left : containerAppBounds.left;
final int screenPosY = containerBounds.top;
if (screenPosX != 0 || screenPosY != 0) {
@@ -7694,6 +7710,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return true;
}
+ private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
+ Rect containingBounds) {
+ return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
+ 0 /* desiredAspectRatio */, false /* fixedOrientationLetterboxed */);
+ }
+
/**
* Applies aspect ratio restrictions to outBounds. If no restrictions, then no change is
* made to outBounds.
@@ -7702,17 +7724,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
- Rect containingBounds) {
+ Rect containingBounds, float desiredAspectRatio, boolean fixedOrientationLetterboxed) {
final float maxAspectRatio = info.getMaxAspectRatio();
final Task rootTask = getRootTask();
final float minAspectRatio = info.getMinAspectRatio();
if (task == null || rootTask == null
- || (inMultiWindowMode() && !shouldCreateCompatDisplayInsets())
- || (maxAspectRatio == 0 && minAspectRatio == 0)
+ || (inMultiWindowMode() && !shouldCreateCompatDisplayInsets()
+ && !fixedOrientationLetterboxed)
+ || (maxAspectRatio < 1 && minAspectRatio < 1 && desiredAspectRatio < 1)
|| isInVrUiMode(getConfiguration())) {
- // We don't enforce aspect ratio if the activity task is in multiwindow unless it
- // is in size-compat mode. We also don't set it if we are in VR mode.
+ // We don't enforce aspect ratio if the activity task is in multiwindow unless it is in
+ // size-compat mode or is letterboxed from fixed orientation. We also don't set it if we
+ // are in VR mode.
return false;
}
@@ -7720,20 +7744,30 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final int containingAppHeight = containingAppBounds.height();
final float containingRatio = computeAspectRatio(containingAppBounds);
+ if (desiredAspectRatio < 1) {
+ desiredAspectRatio = containingRatio;
+ }
+
+ if (maxAspectRatio >= 1 && desiredAspectRatio > maxAspectRatio) {
+ desiredAspectRatio = maxAspectRatio;
+ } else if (minAspectRatio >= 1 && desiredAspectRatio < minAspectRatio) {
+ desiredAspectRatio = minAspectRatio;
+ }
+
int activityWidth = containingAppWidth;
int activityHeight = containingAppHeight;
- if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
+ if (containingRatio > desiredAspectRatio) {
if (containingAppWidth < containingAppHeight) {
// Width is the shorter side, so we use that to figure-out what the max. height
// should be given the aspect ratio.
- activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
+ activityHeight = (int) ((activityWidth * desiredAspectRatio) + 0.5f);
} else {
// Height is the shorter side, so we use that to figure-out what the max. width
// should be given the aspect ratio.
- activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
+ activityWidth = (int) ((activityHeight * desiredAspectRatio) + 0.5f);
}
- } else if (containingRatio < minAspectRatio) {
+ } else if (containingRatio < desiredAspectRatio) {
boolean adjustWidth;
switch (getRequestedConfigurationOrientation()) {
case ORIENTATION_LANDSCAPE:
@@ -7761,9 +7795,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
break;
}
if (adjustWidth) {
- activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
+ activityWidth = (int) ((activityHeight / desiredAspectRatio) + 0.5f);
} else {
- activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
+ activityHeight = (int) ((activityWidth / desiredAspectRatio) + 0.5f);
}
}
@@ -7787,6 +7821,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
outBounds.set(containingBounds.left, containingBounds.top, right, bottom);
+ // If the bounds are restricted by fixed aspect ratio, then out bounds should be put in the
+ // container app bounds. Otherwise the entire container bounds are available.
+ if (!outBounds.equals(containingBounds)) {
+ // The horizontal position should not cover insets.
+ outBounds.left = containingAppBounds.left;
+ }
+
return true;
}
@@ -8094,8 +8135,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
preserveWindow);
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
- lifecycleItem = ResumeActivityItem.obtain(
- mDisplayContent.isNextTransitionForward());
+ lifecycleItem = ResumeActivityItem.obtain(isTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 7fe0f5be287c..d3d1c1ca6a2b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -836,7 +836,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
- final DisplayContent dc = r.mDisplayContent;
+ final boolean isTransitionForward = r.isTransitionForward();
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
@@ -845,7 +845,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
- r.takeOptions(), dc.isNextTransitionForward(),
+ r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
r.getLaunchedFromBubble()));
@@ -853,7 +853,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
- lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
+ lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
lifecycleItem = PauseActivityItem.obtain();
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 23dff87c4418..c7cf4b05564f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3833,7 +3833,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// 4. Update the IME control target to apply any inset change and animation.
// 5. Reparent the IME container surface to either the input target app, or the IME window
// parent.
- updateImeControlTarget();
+ updateImeControlTarget(true /* forceUpdateImeParent */);
}
@VisibleForTesting
@@ -3965,12 +3965,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
void updateImeControlTarget() {
+ updateImeControlTarget(false /* forceUpdateImeParent */);
+ }
+
+ void updateImeControlTarget(boolean forceUpdateImeParent) {
InsetsControlTarget prevImeControlTarget = mImeControlTarget;
mImeControlTarget = computeImeControlTarget();
mInsetsStateController.onImeControlTargetChanged(mImeControlTarget);
- // Update Ime parent when IME insets leash created, which is the best time that default
- // IME visibility has been settled down after IME control target changed.
- if (prevImeControlTarget != mImeControlTarget) {
+ // Update Ime parent when IME insets leash created or the new IME layering target might
+ // updated from setImeLayeringTarget, which is the best time that default IME visibility
+ // has been settled down after IME control target changed.
+ if (prevImeControlTarget != mImeControlTarget || forceUpdateImeParent) {
updateImeParent();
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index ea80b8bb5286..c510603d1d7d 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
@@ -3383,6 +3384,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
*/
void lockAllProfileTasks(@UserIdInt int userId) {
forAllLeafTasks(task -> {
+ final ActivityRecord top = task.topRunningActivity();
+ if (top != null && !top.finishing
+ && ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER.equals(top.intent.getAction())
+ && top.packageName.equals(
+ mService.getSysUiServiceComponentLocked().getPackageName())) {
+ // Do nothing since the task is already secure by sysui.
+ return;
+ }
+
if (task.getActivity(activity -> !activity.finishing && activity.mUserId == userId)
!= null) {
mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java
index b56e76d91370..be6a5d2fe27b 100644
--- a/services/core/java/com/android/server/wm/ShellRoot.java
+++ b/services/core/java/com/android/server/wm/ShellRoot.java
@@ -50,6 +50,7 @@ public class ShellRoot {
private SurfaceControl mSurfaceControl = null;
private IWindow mAccessibilityWindow;
private IBinder.DeathRecipient mAccessibilityWindowDeath;
+ private int mWindowType;
ShellRoot(@NonNull IWindow client, @NonNull DisplayContent dc,
@WindowManager.ShellRootLayer final int shellRootLayer) {
@@ -64,19 +65,18 @@ public class ShellRoot {
return;
}
mClient = client;
- int windowType;
switch (shellRootLayer) {
case SHELL_ROOT_LAYER_DIVIDER:
- windowType = TYPE_DOCK_DIVIDER;
+ mWindowType = TYPE_DOCK_DIVIDER;
break;
case SHELL_ROOT_LAYER_PIP:
- windowType = TYPE_APPLICATION_OVERLAY;
+ mWindowType = TYPE_APPLICATION_OVERLAY;
break;
default:
throw new IllegalArgumentException(shellRootLayer
+ " is not an acceptable shell root layer.");
}
- mToken = new WindowToken.Builder(dc.mWmService, client.asBinder(), windowType)
+ mToken = new WindowToken.Builder(dc.mWmService, client.asBinder(), mWindowType)
.setDisplayContent(dc)
.setPersistOnEmpty(true)
.setOwnerCanManageAppTokens(true)
@@ -89,6 +89,10 @@ public class ShellRoot {
mToken.getPendingTransaction().show(mSurfaceControl);
}
+ int getWindowType() {
+ return mWindowType;
+ }
+
void clear() {
if (mClient != null) {
mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
diff --git a/services/core/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java
index 59de43ac95a3..3f9c93bbcfbe 100644
--- a/services/core/java/com/android/server/wm/StartingData.java
+++ b/services/core/java/com/android/server/wm/StartingData.java
@@ -26,6 +26,12 @@ public abstract class StartingData {
protected final WindowManagerService mService;
protected final int mTypeParams;
+ /**
+ * Tell whether the launching activity should use
+ * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_IS_FORWARD_NAVIGATION}.
+ */
+ boolean mIsTransitionForward;
+
protected StartingData(WindowManagerService service, int typeParams) {
mService = service;
mTypeParams = typeParams;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 565f99f80890..325f10f65af2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -974,10 +974,7 @@ class Task extends WindowContainer<WindowContainer> {
}
void removeIfPossible(String reason) {
- final boolean isRootTask = isRootTask();
- if (!isRootTask) {
- mAtmService.getLockTaskController().clearLockedTask(this);
- }
+ mAtmService.getLockTaskController().clearLockedTask(this);
if (shouldDeferRemoval()) {
if (DEBUG_ROOT_TASK) Slog.i(TAG,
"removeTask:" + reason + " deferring removing taskId=" + mTaskId);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e9dd521670a9..2c8fcebdd50f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2463,6 +2463,17 @@ public class WindowManagerService extends IWindowManager.Stub
configChanged = displayContent.updateOrientation();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ final DisplayInfo rotatedDisplayInfo =
+ win.mToken.getFixedRotationTransformDisplayInfo();
+ if (rotatedDisplayInfo != null) {
+ outSurfaceControl.setTransformHint(rotatedDisplayInfo.rotation);
+ } else {
+ // We have to update the transform hint of display here, but we need to get if from
+ // SurfaceFlinger, so set it as rotation of display for most cases, then
+ // SurfaceFlinger would still update the transform hint of display in next frame.
+ outSurfaceControl.setTransformHint(displayContent.getDisplayInfo().rotation);
+ }
+
if (toBeDisplayed && win.mIsWallpaper) {
displayContent.mWallpaperController.updateWallpaperOffset(win, false /* sync */);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 07ac73b05706..bba50a75a3b9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2568,6 +2568,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private void setupWindowForRemoveOnExit() {
mRemoveOnExit = true;
setDisplayLayoutNeeded();
+ getDisplayContent().getDisplayPolicy().removeWindowLw(this);
// Request a focus update as this window's input channel is already gone. Otherwise
// we could have no focused window in input manager.
final boolean focusChanged = mWmService.updateFocusedWindowLocked(
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index e13ef99e17dd..a94ad4ad7ef2 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -997,10 +997,7 @@ void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration
}
void NativeInputManager::displayRemoved(JNIEnv* env, int32_t displayId) {
- // Set an empty list to remove all handles from the specific display.
- std::vector<sp<InputWindowHandle>> windowHandles;
- mInputManager->getDispatcher()->setInputWindows({{displayId, windowHandles}});
- mInputManager->getDispatcher()->setFocusedApplication(displayId, nullptr);
+ mInputManager->getDispatcher()->displayRemoved(displayId);
}
void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index 698e3f75d0ed..9029fe7cca66 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -41,8 +41,18 @@ static JavaVM* sJvm = nullptr;
static jmethodID sMethodIdOnComplete;
static jclass sFrequencyMappingClass;
static jmethodID sFrequencyMappingCtor;
-static jclass sVibratorInfoClass;
-static jmethodID sVibratorInfoCtor;
+static struct {
+ jmethodID setCapabilities;
+ jmethodID setSupportedEffects;
+ jmethodID setSupportedBraking;
+ jmethodID setPwlePrimitiveDurationMax;
+ jmethodID setPwleSizeMax;
+ jmethodID setSupportedPrimitive;
+ jmethodID setPrimitiveDelayMax;
+ jmethodID setCompositionSizeMax;
+ jmethodID setQFactor;
+ jmethodID setFrequencyMapping;
+} sVibratorInfoBuilderClassInfo;
static struct {
jfieldID id;
jfieldID scale;
@@ -352,68 +362,88 @@ static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong ptr,
wrapper->halCall<void>(alwaysOnDisableFn, "alwaysOnDisable");
}
-static jobject vibratorGetInfo(JNIEnv* env, jclass /* clazz */, jlong ptr,
- jfloat suggestedSafeRange) {
+static jboolean vibratorGetInfo(JNIEnv* env, jclass /* clazz */, jlong ptr,
+ jfloat suggestedSafeRange, jobject vibratorInfoBuilder) {
VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr);
if (wrapper == nullptr) {
ALOGE("vibratorGetInfo failed because native wrapper was not initialized");
- return nullptr;
+ return JNI_FALSE;
}
vibrator::Info info = wrapper->getVibratorInfo();
- jlong capabilities =
- static_cast<jlong>(info.capabilities.valueOr(vibrator::Capabilities::NONE));
- jfloat minFrequency = static_cast<jfloat>(info.minFrequency.valueOr(NAN));
- jfloat resonantFrequency = static_cast<jfloat>(info.resonantFrequency.valueOr(NAN));
- jfloat frequencyResolution = static_cast<jfloat>(info.frequencyResolution.valueOr(NAN));
- jfloat qFactor = static_cast<jfloat>(info.qFactor.valueOr(NAN));
- jintArray supportedEffects = nullptr;
- jintArray supportedBraking = nullptr;
- jintArray supportedPrimitives = nullptr;
- jintArray primitiveDurations = nullptr;
- jfloatArray maxAmplitudes = nullptr;
-
+ if (info.capabilities.isOk()) {
+ env->CallObjectMethod(vibratorInfoBuilder, sVibratorInfoBuilderClassInfo.setCapabilities,
+ static_cast<jlong>(info.capabilities.value()));
+ }
if (info.supportedEffects.isOk()) {
std::vector<aidl::Effect> effects = info.supportedEffects.value();
- supportedEffects = env->NewIntArray(effects.size());
+ jintArray supportedEffects = env->NewIntArray(effects.size());
env->SetIntArrayRegion(supportedEffects, 0, effects.size(),
reinterpret_cast<jint*>(effects.data()));
+ env->CallObjectMethod(vibratorInfoBuilder,
+ sVibratorInfoBuilderClassInfo.setSupportedEffects, supportedEffects);
}
if (info.supportedBraking.isOk()) {
std::vector<aidl::Braking> braking = info.supportedBraking.value();
- supportedBraking = env->NewIntArray(braking.size());
+ jintArray supportedBraking = env->NewIntArray(braking.size());
env->SetIntArrayRegion(supportedBraking, 0, braking.size(),
reinterpret_cast<jint*>(braking.data()));
+ env->CallObjectMethod(vibratorInfoBuilder,
+ sVibratorInfoBuilderClassInfo.setSupportedBraking, supportedBraking);
}
- if (info.supportedPrimitives.isOk()) {
- std::vector<aidl::CompositePrimitive> primitives = info.supportedPrimitives.value();
- supportedPrimitives = env->NewIntArray(primitives.size());
- env->SetIntArrayRegion(supportedPrimitives, 0, primitives.size(),
- reinterpret_cast<jint*>(primitives.data()));
+ if (info.pwlePrimitiveDurationMax.isOk()) {
+ env->CallObjectMethod(vibratorInfoBuilder,
+ sVibratorInfoBuilderClassInfo.setPwlePrimitiveDurationMax,
+ static_cast<jint>(info.pwlePrimitiveDurationMax.value().count()));
+ }
+ if (info.pwleSizeMax.isOk()) {
+ // Use (pwleMaxSize - 1) to account for a possible extra braking segment added by the
+ // vibratorPerformPwleEffect method.
+ env->CallObjectMethod(vibratorInfoBuilder, sVibratorInfoBuilderClassInfo.setPwleSizeMax,
+ static_cast<jint>(info.pwleSizeMax.value() - 1));
}
- if (info.primitiveDurations.isOk()) {
- std::vector<int32_t> durations;
- for (auto duration : info.primitiveDurations.value()) {
- durations.push_back(duration.count());
+ if (info.supportedPrimitives.isOk()) {
+ auto durations = info.primitiveDurations.valueOr({});
+ for (auto& primitive : info.supportedPrimitives.value()) {
+ auto primitiveIdx = static_cast<size_t>(primitive);
+ auto duration = durations.size() > primitiveIdx ? durations[primitiveIdx].count() : 0;
+ env->CallObjectMethod(vibratorInfoBuilder,
+ sVibratorInfoBuilderClassInfo.setSupportedPrimitive,
+ static_cast<jint>(primitive), static_cast<jint>(duration));
}
- primitiveDurations = env->NewIntArray(durations.size());
- env->SetIntArrayRegion(primitiveDurations, 0, durations.size(),
- reinterpret_cast<jint*>(durations.data()));
}
+ if (info.primitiveDelayMax.isOk()) {
+ env->CallObjectMethod(vibratorInfoBuilder,
+ sVibratorInfoBuilderClassInfo.setPrimitiveDelayMax,
+ static_cast<jint>(info.primitiveDelayMax.value().count()));
+ }
+ if (info.compositionSizeMax.isOk()) {
+ env->CallObjectMethod(vibratorInfoBuilder,
+ sVibratorInfoBuilderClassInfo.setCompositionSizeMax,
+ static_cast<jint>(info.compositionSizeMax.value()));
+ }
+ if (info.qFactor.isOk()) {
+ env->CallObjectMethod(vibratorInfoBuilder, sVibratorInfoBuilderClassInfo.setQFactor,
+ static_cast<jfloat>(info.qFactor.value()));
+ }
+
+ jfloat minFrequency = static_cast<jfloat>(info.minFrequency.valueOr(NAN));
+ jfloat resonantFrequency = static_cast<jfloat>(info.resonantFrequency.valueOr(NAN));
+ jfloat frequencyResolution = static_cast<jfloat>(info.frequencyResolution.valueOr(NAN));
+ jfloatArray maxAmplitudes = nullptr;
if (info.maxAmplitudes.isOk()) {
std::vector<float> amplitudes = info.maxAmplitudes.value();
maxAmplitudes = env->NewFloatArray(amplitudes.size());
env->SetFloatArrayRegion(maxAmplitudes, 0, amplitudes.size(),
reinterpret_cast<jfloat*>(amplitudes.data()));
}
-
jobject frequencyMapping = env->NewObject(sFrequencyMappingClass, sFrequencyMappingCtor,
minFrequency, resonantFrequency, frequencyResolution,
suggestedSafeRange, maxAmplitudes);
+ env->CallObjectMethod(vibratorInfoBuilder, sVibratorInfoBuilderClassInfo.setFrequencyMapping,
+ frequencyMapping);
- return env->NewObject(sVibratorInfoClass, sVibratorInfoCtor, wrapper->getVibratorId(),
- capabilities, supportedEffects, supportedBraking, supportedPrimitives,
- primitiveDurations, qFactor, frequencyMapping);
+ return info.checkAndLogFailure("vibratorGetInfo") ? JNI_FALSE : JNI_TRUE;
}
static const JNINativeMethod method_table[] = {
@@ -433,7 +463,7 @@ static const JNINativeMethod method_table[] = {
{"setExternalControl", "(JZ)V", (void*)vibratorSetExternalControl},
{"alwaysOnEnable", "(JJJJ)V", (void*)vibratorAlwaysOnEnable},
{"alwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable},
- {"getInfo", "(JF)Landroid/os/VibratorInfo;", (void*)vibratorGetInfo},
+ {"getInfo", "(JFLandroid/os/VibratorInfo$Builder;)Z", (void*)vibratorGetInfo},
};
int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env) {
@@ -459,11 +489,38 @@ int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env
sFrequencyMappingClass = static_cast<jclass>(env->NewGlobalRef(frequencyMappingClass));
sFrequencyMappingCtor = GetMethodIDOrDie(env, sFrequencyMappingClass, "<init>", "(FFFF[F)V");
- jclass vibratorInfoClass = FindClassOrDie(env, "android/os/VibratorInfo");
- sVibratorInfoClass = (jclass)env->NewGlobalRef(vibratorInfoClass);
- sVibratorInfoCtor =
- GetMethodIDOrDie(env, sVibratorInfoClass, "<init>",
- "(IJ[I[I[I[IFLandroid/os/VibratorInfo$FrequencyMapping;)V");
+ jclass vibratorInfoBuilderClass = FindClassOrDie(env, "android/os/VibratorInfo$Builder");
+ sVibratorInfoBuilderClassInfo.setCapabilities =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setCapabilities",
+ "(J)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setSupportedEffects =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setSupportedEffects",
+ "([I)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setSupportedBraking =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setSupportedBraking",
+ "([I)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setPwlePrimitiveDurationMax =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setPwlePrimitiveDurationMax",
+ "(I)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setPwleSizeMax =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setPwleSizeMax",
+ "(I)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setSupportedPrimitive =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setSupportedPrimitive",
+ "(II)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setPrimitiveDelayMax =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setPrimitiveDelayMax",
+ "(I)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setCompositionSizeMax =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setCompositionSizeMax",
+ "(I)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setQFactor =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setQFactor",
+ "(F)Landroid/os/VibratorInfo$Builder;");
+ sVibratorInfoBuilderClassInfo.setFrequencyMapping =
+ GetMethodIDOrDie(env, vibratorInfoBuilderClass, "setFrequencyMapping",
+ "(Landroid/os/VibratorInfo$FrequencyMapping;)"
+ "Landroid/os/VibratorInfo$Builder;");
return jniRegisterNativeMethods(env,
"com/android/server/vibrator/VibratorController$NativeWrapper",
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 3e2e37c834f1..82aaa61527d1 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -77,6 +77,10 @@
<xs:annotation name="final"/>
</xs:element>
<xs:element name="timing" type="hbmTiming" minOccurs="1" maxOccurs="1"/>
+ <xs:element type="refreshRateRange" name="refreshRate" minOccurs="0" maxOccurs="1">
+ <xs:annotation name="nullable"/>
+ <xs:annotation name="final"/>
+ </xs:element>
</xs:all>
<xs:attribute name="enabled" type="xs:boolean" use="optional"/>
</xs:complexType>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index d40854a87453..6e2e3625f60c 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -44,10 +44,12 @@ package com.android.server.display.config {
ctor public HighBrightnessMode();
method public boolean getEnabled();
method @NonNull public final java.math.BigDecimal getMinimumLux_all();
+ method @Nullable public final com.android.server.display.config.RefreshRateRange getRefreshRate_all();
method public com.android.server.display.config.HbmTiming getTiming_all();
method @NonNull public final java.math.BigDecimal getTransitionPoint_all();
method public void setEnabled(boolean);
method public final void setMinimumLux_all(@NonNull java.math.BigDecimal);
+ method public final void setRefreshRate_all(@Nullable com.android.server.display.config.RefreshRateRange);
method public void setTiming_all(com.android.server.display.config.HbmTiming);
method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c5dc6b7a0426..78ad59f8c01b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -17565,10 +17565,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public boolean isUsbDataSignalingEnabled(String packageName) {
+ final CallerIdentity caller = getCallerIdentity(packageName);
synchronized (getLockObject()) {
- final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(
- getCallerIdentity(packageName));
- return admin.mUsbDataSignalingEnabled;
+ // If the caller is an admin, return the policy set by itself. Otherwise
+ // return the device-wide policy.
+ if (isDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller)) {
+ return getProfileOwnerOrDeviceOwnerLocked(caller).mUsbDataSignalingEnabled;
+ } else {
+ return isUsbDataSignalingEnabledInternalLocked();
+ }
}
}
@@ -17578,12 +17583,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
Preconditions.checkCallAuthorization(isSystemUid(caller));
synchronized (getLockObject()) {
- final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
- UserHandle.USER_SYSTEM);
- return admin == null || admin.mUsbDataSignalingEnabled;
+ return isUsbDataSignalingEnabledInternalLocked();
}
}
+ private boolean isUsbDataSignalingEnabledInternalLocked() {
+ final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
+ UserHandle.USER_SYSTEM);
+ return admin == null || admin.mUsbDataSignalingEnabled;
+ }
+
@Override
public boolean canUsbDataSignalingBeDisabled() {
return mInjector.binderWithCleanCallingIdentity(() ->
diff --git a/services/net/Android.bp b/services/net/Android.bp
index f92db86bb880..dd864aed4e8e 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -37,15 +37,7 @@ java_library {
name: "services.net-module-wifi",
srcs: [
":framework-services-net-module-wifi-shared-srcs",
- ":net-module-utils-srcs",
":net-utils-services-common-srcs",
- "java/android/net/ip/IpClientCallbacks.java",
- "java/android/net/ip/IpClientManager.java",
- "java/android/net/ip/IpClientUtil.java",
- "java/android/net/util/KeepalivePacketDataUtil.java",
- "java/android/net/util/NetworkConstants.java",
- "java/android/net/IpMemoryStore.java",
- "java/android/net/NetworkMonitorManager.java",
],
sdk_version: "module_current",
min_sdk_version: "30",
@@ -89,11 +81,7 @@ filegroup {
filegroup {
name: "services-connectivity-shared-srcs",
srcs: [
- // TODO: move to networkstack-client
- "java/android/net/IpMemoryStore.java",
- "java/android/net/NetworkMonitorManager.java",
// TODO: move to libs/net
- "java/android/net/util/KeepalivePacketDataUtil.java",
"java/android/net/util/NetworkConstants.java",
],
}
diff --git a/services/net/java/android/net/IpMemoryStore.java b/services/net/java/android/net/IpMemoryStore.java
deleted file mode 100644
index 8df2e0d08e0e..000000000000
--- a/services/net/java/android/net/IpMemoryStore.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.net.networkstack.ModuleNetworkStackClient;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
-
-/**
- * Manager class used to communicate with the ip memory store service in the network stack,
- * which is running in a separate module.
- * @hide
-*/
-public class IpMemoryStore extends IpMemoryStoreClient {
- private static final String TAG = IpMemoryStore.class.getSimpleName();
- @NonNull private final CompletableFuture<IIpMemoryStore> mService;
- @NonNull private final AtomicReference<CompletableFuture<IIpMemoryStore>> mTailNode;
-
- public IpMemoryStore(@NonNull final Context context) {
- super(context);
- mService = new CompletableFuture<>();
- mTailNode = new AtomicReference<CompletableFuture<IIpMemoryStore>>(mService);
- getModuleNetworkStackClient(context).fetchIpMemoryStore(
- new IIpMemoryStoreCallbacks.Stub() {
- @Override
- public void onIpMemoryStoreFetched(@NonNull final IIpMemoryStore memoryStore) {
- mService.complete(memoryStore);
- }
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
- });
- }
-
- /*
- * If the IpMemoryStore is ready, this function will run the request synchronously.
- * Otherwise, it will enqueue the requests for execution immediately after the
- * service becomes ready. The requests are guaranteed to be executed in the order
- * they are sumbitted.
- */
- @Override
- protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
- mTailNode.getAndUpdate(future -> future.handle((store, exception) -> {
- if (exception != null) {
- // this should never happens since we also catch the exception below
- Log.wtf(TAG, "Error fetching IpMemoryStore", exception);
- return store;
- }
-
- try {
- cb.accept(store);
- } catch (Exception e) {
- Log.wtf(TAG, "Exception occured: " + e.getMessage());
- }
- return store;
- }));
- }
-
- @VisibleForTesting
- protected ModuleNetworkStackClient getModuleNetworkStackClient(Context context) {
- return ModuleNetworkStackClient.getInstance(context);
- }
-
- /** Gets an instance of the memory store */
- @NonNull
- public static IpMemoryStore getMemoryStore(final Context context) {
- return new IpMemoryStore(context);
- }
-}
diff --git a/services/net/java/android/net/NetworkMonitorManager.java b/services/net/java/android/net/NetworkMonitorManager.java
deleted file mode 100644
index 0f669817f52e..000000000000
--- a/services/net/java/android/net/NetworkMonitorManager.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.Hide;
-import android.annotation.NonNull;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * A convenience wrapper for INetworkMonitor.
- *
- * Wraps INetworkMonitor calls, making them a bit more friendly to use. Currently handles:
- * - Clearing calling identity
- * - Ignoring RemoteExceptions
- * - Converting to stable parcelables
- *
- * By design, all methods on INetworkMonitor are asynchronous oneway IPCs and are thus void. All the
- * wrapper methods in this class return a boolean that callers can use to determine whether
- * RemoteException was thrown.
- */
-@Hide
-public class NetworkMonitorManager {
-
- @NonNull private final INetworkMonitor mNetworkMonitor;
- @NonNull private final String mTag;
-
- public NetworkMonitorManager(@NonNull INetworkMonitor networkMonitorManager,
- @NonNull String tag) {
- mNetworkMonitor = networkMonitorManager;
- mTag = tag;
- }
-
- public NetworkMonitorManager(@NonNull INetworkMonitor networkMonitorManager) {
- this(networkMonitorManager, NetworkMonitorManager.class.getSimpleName());
- }
-
- private void log(String s, Throwable e) {
- Log.e(mTag, s, e);
- }
-
- // CHECKSTYLE:OFF Generated code
-
- public boolean start() {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.start();
- return true;
- } catch (RemoteException e) {
- log("Error in start", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean launchCaptivePortalApp() {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.launchCaptivePortalApp();
- return true;
- } catch (RemoteException e) {
- log("Error in launchCaptivePortalApp", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyCaptivePortalAppFinished(int response) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyCaptivePortalAppFinished(response);
- return true;
- } catch (RemoteException e) {
- log("Error in notifyCaptivePortalAppFinished", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean setAcceptPartialConnectivity() {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.setAcceptPartialConnectivity();
- return true;
- } catch (RemoteException e) {
- log("Error in setAcceptPartialConnectivity", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean forceReevaluation(int uid) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.forceReevaluation(uid);
- return true;
- } catch (RemoteException e) {
- log("Error in forceReevaluation", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyPrivateDnsChanged(config);
- return true;
- } catch (RemoteException e) {
- log("Error in notifyPrivateDnsChanged", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyDnsResponse(int returnCode) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyDnsResponse(returnCode);
- return true;
- } catch (RemoteException e) {
- log("Error in notifyDnsResponse", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyNetworkConnected(lp, nc);
- return true;
- } catch (RemoteException e) {
- log("Error in notifyNetworkConnected", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyNetworkDisconnected() {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyNetworkDisconnected();
- return true;
- } catch (RemoteException e) {
- log("Error in notifyNetworkDisconnected", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyLinkPropertiesChanged(LinkProperties lp) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyLinkPropertiesChanged(lp);
- return true;
- } catch (RemoteException e) {
- log("Error in notifyLinkPropertiesChanged", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- public boolean notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
- final long token = Binder.clearCallingIdentity();
- try {
- mNetworkMonitor.notifyNetworkCapabilitiesChanged(nc);
- return true;
- } catch (RemoteException e) {
- log("Error in notifyNetworkCapabilitiesChanged", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // CHECKSTYLE:ON Generated code
-}
diff --git a/services/net/java/android/net/ip/IpClientCallbacks.java b/services/net/java/android/net/ip/IpClientCallbacks.java
deleted file mode 100644
index b17fcaa132a1..000000000000
--- a/services/net/java/android/net/ip/IpClientCallbacks.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import android.net.DhcpResultsParcelable;
-import android.net.Layer2PacketParcelable;
-import android.net.LinkProperties;
-
-import java.util.List;
-
-/**
- * Callbacks for handling IpClient events.
- *
- * This is a convenience class to allow clients not to override all methods of IIpClientCallbacks,
- * and avoid unparceling arguments.
- * These methods are called asynchronously on a Binder thread, as IpClient lives in a different
- * process.
- * @hide
- */
-public class IpClientCallbacks {
-
- /**
- * Callback called upon IpClient creation.
- *
- * @param ipClient The Binder token to communicate with IpClient.
- */
- public void onIpClientCreated(IIpClient ipClient) {}
-
- /**
- * Callback called prior to DHCP discovery/renewal.
- *
- * <p>In order to receive onPreDhcpAction(), call #withPreDhcpAction() when constructing a
- * ProvisioningConfiguration.
- *
- * <p>Implementations of onPreDhcpAction() must call IpClient#completedPreDhcpAction() to
- * indicate that DHCP is clear to proceed.
- */
- public void onPreDhcpAction() {}
-
- /**
- * Callback called after DHCP discovery/renewal.
- */
- public void onPostDhcpAction() {}
-
- /**
- * Callback called when new DHCP results are available.
- *
- * <p>This is purely advisory and not an indication of provisioning success or failure. This is
- * only here for callers that want to expose DHCPv4 results to other APIs
- * (e.g., WifiInfo#setInetAddress).
- *
- * <p>DHCPv4 or static IPv4 configuration failure or success can be determined by whether or not
- * the passed-in DhcpResults object is null.
- */
- public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
- // In general callbacks would not use a parcelable directly (DhcpResultsParcelable), and
- // would use a wrapper instead, because of the lack of safety of stable parcelables. But
- // there are already two classes in the tree for DHCP information: DhcpInfo and DhcpResults,
- // and neither of them exposes an appropriate API (they are bags of mutable fields and can't
- // be changed because they are public API and @UnsupportedAppUsage, being no better than the
- // stable parcelable). Adding a third class would cost more than the gain considering that
- // the only client of this callback is WiFi, which will end up converting the results to
- // DhcpInfo anyway.
- }
-
- /**
- * Indicates that provisioning was successful.
- */
- public void onProvisioningSuccess(LinkProperties newLp) {}
-
- /**
- * Indicates that provisioning failed.
- */
- public void onProvisioningFailure(LinkProperties newLp) {}
-
- /**
- * Invoked on LinkProperties changes.
- */
- public void onLinkPropertiesChange(LinkProperties newLp) {}
-
- /**Called when the internal IpReachabilityMonitor (if enabled) has
- * detected the loss of a critical number of required neighbors.
- */
- public void onReachabilityLost(String logMsg) {}
-
- /**
- * Called when the IpClient state machine terminates.
- */
- public void onQuit() {}
-
- /**
- * Called to indicate that a new APF program must be installed to filter incoming packets.
- */
- public void installPacketFilter(byte[] filter) {}
-
- /**
- * Called to indicate that the APF Program & data buffer must be read asynchronously from the
- * wifi driver.
- *
- * <p>Due to Wifi HAL limitations, the current implementation only supports dumping the entire
- * buffer. In response to this request, the driver returns the data buffer asynchronously
- * by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
- */
- public void startReadPacketFilter() {}
-
- /**
- * If multicast filtering cannot be accomplished with APF, this function will be called to
- * actuate multicast filtering using another means.
- */
- public void setFallbackMulticastFilter(boolean enabled) {}
-
- /**
- * Enabled/disable Neighbor Discover offload functionality. This is called, for example,
- * whenever 464xlat is being started or stopped.
- */
- public void setNeighborDiscoveryOffload(boolean enable) {}
-
- /**
- * Invoked on starting preconnection process.
- */
- public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {}
-}
diff --git a/services/net/java/android/net/ip/IpClientManager.java b/services/net/java/android/net/ip/IpClientManager.java
deleted file mode 100644
index b45405f39f0f..000000000000
--- a/services/net/java/android/net/ip/IpClientManager.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import android.annotation.Hide;
-import android.annotation.NonNull;
-import android.net.NattKeepalivePacketData;
-import android.net.ProxyInfo;
-import android.net.TcpKeepalivePacketData;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.shared.Layer2Information;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.KeepalivePacketDataUtil;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * A convenience wrapper for IpClient.
- *
- * Wraps IIpClient calls, making them a bit more friendly to use. Currently handles:
- * - Clearing calling identity
- * - Ignoring RemoteExceptions
- * - Converting to stable parcelables
- *
- * By design, all methods on IIpClient are asynchronous oneway IPCs and are thus void. All the
- * wrapper methods in this class return a boolean that callers can use to determine whether
- * RemoteException was thrown.
- */
-@Hide
-public class IpClientManager {
- @NonNull private final IIpClient mIpClient;
- @NonNull private final String mTag;
-
- public IpClientManager(@NonNull IIpClient ipClient, @NonNull String tag) {
- mIpClient = ipClient;
- mTag = tag;
- }
-
- public IpClientManager(@NonNull IIpClient ipClient) {
- this(ipClient, IpClientManager.class.getSimpleName());
- }
-
- private void log(String s, Throwable e) {
- Log.e(mTag, s, e);
- }
-
- /**
- * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be
- * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to
- * proceed.
- */
- public boolean completedPreDhcpAction() {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.completedPreDhcpAction();
- return true;
- } catch (RemoteException e) {
- log("Error completing PreDhcpAction", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Confirm the provisioning configuration.
- */
- public boolean confirmConfiguration() {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.confirmConfiguration();
- return true;
- } catch (RemoteException e) {
- log("Error confirming IpClient configuration", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Indicate that packet filter read is complete.
- */
- public boolean readPacketFilterComplete(byte[] data) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.readPacketFilterComplete(data);
- return true;
- } catch (RemoteException e) {
- log("Error notifying IpClient of packet filter read", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Shut down this IpClient instance altogether.
- */
- public boolean shutdown() {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.shutdown();
- return true;
- } catch (RemoteException e) {
- log("Error shutting down IpClient", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Start provisioning with the provided parameters.
- */
- public boolean startProvisioning(ProvisioningConfiguration prov) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.startProvisioning(prov.toStableParcelable());
- return true;
- } catch (RemoteException e) {
- log("Error starting IpClient provisioning", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Stop this IpClient.
- *
- * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
- */
- public boolean stop() {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.stop();
- return true;
- } catch (RemoteException e) {
- log("Error stopping IpClient", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Set the TCP buffer sizes to use.
- *
- * This may be called, repeatedly, at any time before or after a call to
- * #startProvisioning(). The setting is cleared upon calling #stop().
- */
- public boolean setTcpBufferSizes(String tcpBufferSizes) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.setTcpBufferSizes(tcpBufferSizes);
- return true;
- } catch (RemoteException e) {
- log("Error setting IpClient TCP buffer sizes", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Set the HTTP Proxy configuration to use.
- *
- * This may be called, repeatedly, at any time before or after a call to
- * #startProvisioning(). The setting is cleared upon calling #stop().
- */
- public boolean setHttpProxy(ProxyInfo proxyInfo) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.setHttpProxy(proxyInfo);
- return true;
- } catch (RemoteException e) {
- log("Error setting IpClient proxy", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Enable or disable the multicast filter. Attempts to use APF to accomplish the filtering,
- * if not, Callback.setFallbackMulticastFilter() is called.
- */
- public boolean setMulticastFilter(boolean enabled) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.setMulticastFilter(enabled);
- return true;
- } catch (RemoteException e) {
- log("Error setting multicast filter", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Add a TCP keepalive packet filter before setting up keepalive offload.
- */
- public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketData pkt) {
- return addKeepalivePacketFilter(slot, KeepalivePacketDataUtil.toStableParcelable(pkt));
- }
-
- /**
- * Add a TCP keepalive packet filter before setting up keepalive offload.
- * @deprecated This method is for use on pre-S platforms where TcpKeepalivePacketData is not
- * system API. On newer platforms use
- * addKeepalivePacketFilter(int, TcpKeepalivePacketData) instead.
- */
- @Deprecated
- public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.addKeepalivePacketFilter(slot, pkt);
- return true;
- } catch (RemoteException e) {
- log("Error adding Keepalive Packet Filter ", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Add a NAT-T keepalive packet filter before setting up keepalive offload.
- */
- public boolean addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.addNattKeepalivePacketFilter(
- slot, KeepalivePacketDataUtil.toStableParcelable(pkt));
- return true;
- } catch (RemoteException e) {
- log("Error adding NAT-T Keepalive Packet Filter ", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Remove a keepalive packet filter after stopping keepalive offload.
- */
- public boolean removeKeepalivePacketFilter(int slot) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.removeKeepalivePacketFilter(slot);
- return true;
- } catch (RemoteException e) {
- log("Error removing Keepalive Packet Filter ", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Set the L2 key and group hint for storing info into the memory store.
- */
- public boolean setL2KeyAndGroupHint(String l2Key, String groupHint) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.setL2KeyAndGroupHint(l2Key, groupHint);
- return true;
- } catch (RemoteException e) {
- log("Failed setL2KeyAndGroupHint", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Notify IpClient that preconnection is complete and that the link is ready for use.
- * The success parameter indicates whether the packets passed in by 'onPreconnectionStart'
- * were successfully sent to the network or not.
- */
- public boolean notifyPreconnectionComplete(boolean success) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.notifyPreconnectionComplete(success);
- return true;
- } catch (RemoteException e) {
- log("Error notifying IpClient Preconnection completed", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * Update the bssid, L2 key and group hint layer2 information.
- */
- public boolean updateLayer2Information(Layer2Information info) {
- final long token = Binder.clearCallingIdentity();
- try {
- mIpClient.updateLayer2Information(info.toStableParcelable());
- return true;
- } catch (RemoteException e) {
- log("Error updating layer2 information", e);
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-}
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
deleted file mode 100644
index 426614ec2f53..000000000000
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import android.content.Context;
-import android.net.DhcpResultsParcelable;
-import android.net.Layer2PacketParcelable;
-import android.net.LinkProperties;
-import android.net.networkstack.ModuleNetworkStackClient;
-import android.os.ConditionVariable;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-
-
-/**
- * Utilities and wrappers to simplify communication with IpClient, which lives in the NetworkStack
- * process.
- *
- * @hide
- */
-public class IpClientUtil {
- // TODO: remove with its callers
- public static final String DUMP_ARG = "ipclient";
-
- /**
- * Subclass of {@link IpClientCallbacks} allowing clients to block until provisioning is
- * complete with {@link WaitForProvisioningCallbacks#waitForProvisioning()}.
- */
- public static class WaitForProvisioningCallbacks extends IpClientCallbacks {
- private final ConditionVariable mCV = new ConditionVariable();
- private LinkProperties mCallbackLinkProperties;
-
- /**
- * Block until either {@link #onProvisioningSuccess(LinkProperties)} or
- * {@link #onProvisioningFailure(LinkProperties)} is called.
- */
- public LinkProperties waitForProvisioning() {
- mCV.block();
- return mCallbackLinkProperties;
- }
-
- @Override
- public void onProvisioningSuccess(LinkProperties newLp) {
- mCallbackLinkProperties = newLp;
- mCV.open();
- }
-
- @Override
- public void onProvisioningFailure(LinkProperties newLp) {
- mCallbackLinkProperties = null;
- mCV.open();
- }
- }
-
- /**
- * Create a new IpClient.
- *
- * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of
- * {@link IIpClientCallbacks}.
- * @see {@link ModuleNetworkStackClient#makeIpClient(String, IIpClientCallbacks)}
- */
- public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) {
- ModuleNetworkStackClient.getInstance(context)
- .makeIpClient(ifName, new IpClientCallbacksProxy(callback));
- }
-
- /**
- * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}.
- */
- private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub {
- protected final IpClientCallbacks mCb;
-
- /**
- * Create a new IpClientCallbacksProxy.
- */
- public IpClientCallbacksProxy(IpClientCallbacks cb) {
- mCb = cb;
- }
-
- @Override
- public void onIpClientCreated(IIpClient ipClient) {
- mCb.onIpClientCreated(ipClient);
- }
-
- @Override
- public void onPreDhcpAction() {
- mCb.onPreDhcpAction();
- }
-
- @Override
- public void onPostDhcpAction() {
- mCb.onPostDhcpAction();
- }
-
- // This is purely advisory and not an indication of provisioning
- // success or failure. This is only here for callers that want to
- // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
- // DHCPv4 or static IPv4 configuration failure or success can be
- // determined by whether or not the passed-in DhcpResults object is
- // null or not.
- @Override
- public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
- mCb.onNewDhcpResults(dhcpResults);
- }
-
- @Override
- public void onProvisioningSuccess(LinkProperties newLp) {
- mCb.onProvisioningSuccess(newLp);
- }
- @Override
- public void onProvisioningFailure(LinkProperties newLp) {
- mCb.onProvisioningFailure(newLp);
- }
-
- // Invoked on LinkProperties changes.
- @Override
- public void onLinkPropertiesChange(LinkProperties newLp) {
- mCb.onLinkPropertiesChange(newLp);
- }
-
- // Called when the internal IpReachabilityMonitor (if enabled) has
- // detected the loss of a critical number of required neighbors.
- @Override
- public void onReachabilityLost(String logMsg) {
- mCb.onReachabilityLost(logMsg);
- }
-
- // Called when the IpClient state machine terminates.
- @Override
- public void onQuit() {
- mCb.onQuit();
- }
-
- // Install an APF program to filter incoming packets.
- @Override
- public void installPacketFilter(byte[] filter) {
- mCb.installPacketFilter(filter);
- }
-
- // Asynchronously read back the APF program & data buffer from the wifi driver.
- // Due to Wifi HAL limitations, the current implementation only supports dumping the entire
- // buffer. In response to this request, the driver returns the data buffer asynchronously
- // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
- @Override
- public void startReadPacketFilter() {
- mCb.startReadPacketFilter();
- }
-
- // If multicast filtering cannot be accomplished with APF, this function will be called to
- // actuate multicast filtering using another means.
- @Override
- public void setFallbackMulticastFilter(boolean enabled) {
- mCb.setFallbackMulticastFilter(enabled);
- }
-
- // Enabled/disable Neighbor Discover offload functionality. This is
- // called, for example, whenever 464xlat is being started or stopped.
- @Override
- public void setNeighborDiscoveryOffload(boolean enable) {
- mCb.setNeighborDiscoveryOffload(enable);
- }
-
- // Invoked on starting preconnection process.
- @Override
- public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {
- mCb.onPreconnectionStart(packets);
- }
-
- @Override
- public int getInterfaceVersion() {
- return this.VERSION;
- }
-
- @Override
- public String getInterfaceHash() {
- return this.HASH;
- }
- }
-
- /**
- * Dump logs for the specified IpClient.
- * TODO: remove callers and delete
- */
- public static void dumpIpClient(
- IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("IpClient logs have moved to dumpsys network_stack");
- }
-}
diff --git a/services/net/java/android/net/util/DhcpResultsCompatUtil.java b/services/net/java/android/net/util/DhcpResultsCompatUtil.java
deleted file mode 100644
index fce0834c116e..000000000000
--- a/services/net/java/android/net/util/DhcpResultsCompatUtil.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.net.shared.IpConfigurationParcelableUtil.unparcelAddress;
-
-import android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.DhcpResultsParcelable;
-
-import java.net.Inet4Address;
-
-/**
- * Compatibility utility for code that still uses DhcpResults.
- *
- * TODO: remove this class when all usages of DhcpResults (including Wifi in AOSP) are removed.
- */
-public class DhcpResultsCompatUtil {
-
- /**
- * Convert a DhcpResultsParcelable to DhcpResults.
- *
- * contract {
- * returns(null) implies p == null
- * returnsNotNull() implies p != null
- * }
- */
- @Nullable
- public static DhcpResults fromStableParcelable(@Nullable DhcpResultsParcelable p) {
- if (p == null) return null;
- final DhcpResults results = new DhcpResults(p.baseConfiguration);
- results.leaseDuration = p.leaseDuration;
- results.mtu = p.mtu;
- results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
- results.vendorInfo = p.vendorInfo;
- results.serverHostName = p.serverHostName;
- results.captivePortalApiUrl = p.captivePortalApiUrl;
- return results;
- }
-}
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
deleted file mode 100644
index 566698576026..000000000000
--- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.InvalidPacketException;
-import android.net.KeepalivePacketData;
-import android.net.NattKeepalivePacketData;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketData;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.os.Build;
-import android.system.OsConstants;
-import android.util.Log;
-
-import com.android.net.module.util.IpUtils;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Utility class to convert to/from keepalive data parcelables.
- *
- * TODO: move to networkstack-client library when it is moved to frameworks/libs/net.
- * This class cannot go into other shared libraries as it depends on NetworkStack AIDLs.
- * @hide
- */
-public final class KeepalivePacketDataUtil {
- private static final int IPV4_HEADER_LENGTH = 20;
- private static final int IPV6_HEADER_LENGTH = 40;
- private static final int TCP_HEADER_LENGTH = 20;
-
- private static final String TAG = KeepalivePacketDataUtil.class.getSimpleName();
-
- /**
- * Convert a NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
- */
- @NonNull
- public static NattKeepalivePacketDataParcelable toStableParcelable(
- @NonNull NattKeepalivePacketData pkt) {
- final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
- final InetAddress srcAddress = pkt.getSrcAddress();
- final InetAddress dstAddress = pkt.getDstAddress();
- parcel.srcAddress = srcAddress.getAddress();
- parcel.srcPort = pkt.getSrcPort();
- parcel.dstAddress = dstAddress.getAddress();
- parcel.dstPort = pkt.getDstPort();
- return parcel;
- }
-
- /**
- * Convert a TcpKeepalivePacketData to a TcpKeepalivePacketDataParcelable.
- */
- @NonNull
- public static TcpKeepalivePacketDataParcelable toStableParcelable(
- @NonNull TcpKeepalivePacketData pkt) {
- final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
- final InetAddress srcAddress = pkt.getSrcAddress();
- final InetAddress dstAddress = pkt.getDstAddress();
- parcel.srcAddress = srcAddress.getAddress();
- parcel.srcPort = pkt.getSrcPort();
- parcel.dstAddress = dstAddress.getAddress();
- parcel.dstPort = pkt.getDstPort();
- parcel.seq = pkt.getTcpSeq();
- parcel.ack = pkt.getTcpAck();
- parcel.rcvWnd = pkt.getTcpWindow();
- parcel.rcvWndScale = pkt.getTcpWindowScale();
- parcel.tos = pkt.getIpTos();
- parcel.ttl = pkt.getIpTtl();
- return parcel;
- }
-
- /**
- * Factory method to create tcp keepalive packet structure.
- * @hide
- */
- public static TcpKeepalivePacketData fromStableParcelable(
- TcpKeepalivePacketDataParcelable tcpDetails) throws InvalidPacketException {
- final byte[] packet;
- try {
- if ((tcpDetails.srcAddress != null) && (tcpDetails.dstAddress != null)
- && (tcpDetails.srcAddress.length == 4 /* V4 IP length */)
- && (tcpDetails.dstAddress.length == 4 /* V4 IP length */)) {
- packet = buildV4Packet(tcpDetails);
- } else {
- // TODO: support ipv6
- throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
- }
- return new TcpKeepalivePacketData(
- InetAddress.getByAddress(tcpDetails.srcAddress),
- tcpDetails.srcPort,
- InetAddress.getByAddress(tcpDetails.dstAddress),
- tcpDetails.dstPort,
- packet,
- tcpDetails.seq, tcpDetails.ack, tcpDetails.rcvWnd, tcpDetails.rcvWndScale,
- tcpDetails.tos, tcpDetails.ttl);
- } catch (UnknownHostException e) {
- throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
- }
-
- }
-
- /**
- * Build ipv4 tcp keepalive packet, not including the link-layer header.
- */
- // TODO : if this code is ever moved to the network stack, factorize constants with the ones
- // over there.
- private static byte[] buildV4Packet(TcpKeepalivePacketDataParcelable tcpDetails) {
- final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
- ByteBuffer buf = ByteBuffer.allocate(length);
- buf.order(ByteOrder.BIG_ENDIAN);
- buf.put((byte) 0x45); // IP version and IHL
- buf.put((byte) tcpDetails.tos); // TOS
- buf.putShort((short) length);
- buf.putInt(0x00004000); // ID, flags=DF, offset
- buf.put((byte) tcpDetails.ttl); // TTL
- buf.put((byte) OsConstants.IPPROTO_TCP);
- final int ipChecksumOffset = buf.position();
- buf.putShort((short) 0); // IP checksum
- buf.put(tcpDetails.srcAddress);
- buf.put(tcpDetails.dstAddress);
- buf.putShort((short) tcpDetails.srcPort);
- buf.putShort((short) tcpDetails.dstPort);
- buf.putInt(tcpDetails.seq); // Sequence Number
- buf.putInt(tcpDetails.ack); // ACK
- buf.putShort((short) 0x5010); // TCP length=5, flags=ACK
- buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale)); // Window size
- final int tcpChecksumOffset = buf.position();
- buf.putShort((short) 0); // TCP checksum
- // URG is not set therefore the urgent pointer is zero.
- buf.putShort((short) 0); // Urgent pointer
-
- buf.putShort(ipChecksumOffset, com.android.net.module.util.IpUtils.ipChecksum(buf, 0));
- buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum(
- buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH));
-
- return buf.array();
- }
-
- // TODO: add buildV6Packet.
-
- /**
- * Get a {@link TcpKeepalivePacketDataParcelable} from {@link KeepalivePacketData}, if the
- * generic class actually contains TCP keepalive data.
- *
- * @deprecated This method is used on R platforms where android.net.TcpKeepalivePacketData was
- * not yet system API. Newer platforms should use android.net.TcpKeepalivePacketData directly.
- *
- * @param data A {@link KeepalivePacketData} that may contain TCP keepalive data.
- * @return A parcelable containing TCP keepalive data, or null if the input data does not
- * contain TCP keepalive data.
- */
- @Deprecated
- @SuppressWarnings("AndroidFrameworkCompatChange") // API version check used to Log.wtf
- @Nullable
- public static TcpKeepalivePacketDataParcelable parseTcpKeepalivePacketData(
- @Nullable KeepalivePacketData data) {
- if (data == null) return null;
-
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
- Log.wtf(TAG, "parseTcpKeepalivePacketData should not be used after R, use "
- + "TcpKeepalivePacketData instead.");
- }
-
- // Reconstruct TcpKeepalivePacketData from the packet contained in KeepalivePacketData
- final ByteBuffer buffer = ByteBuffer.wrap(data.getPacket());
- buffer.order(ByteOrder.BIG_ENDIAN);
-
- // Most of the fields are accessible from the KeepalivePacketData superclass: instead of
- // using Struct to parse everything, just extract the extra fields necessary for
- // TcpKeepalivePacketData.
- final int tcpSeq;
- final int tcpAck;
- final int wndSize;
- final int ipTos;
- final int ttl;
- try {
- // This only support IPv4, because TcpKeepalivePacketData only supports IPv4 for R and
- // below, and this method should not be used on newer platforms.
- tcpSeq = buffer.getInt(IPV4_HEADER_LENGTH + 4);
- tcpAck = buffer.getInt(IPV4_HEADER_LENGTH + 8);
- wndSize = buffer.getShort(IPV4_HEADER_LENGTH + 14);
- ipTos = buffer.get(1);
- ttl = buffer.get(8);
- } catch (IndexOutOfBoundsException e) {
- return null;
- }
-
- final TcpKeepalivePacketDataParcelable p = new TcpKeepalivePacketDataParcelable();
- p.srcAddress = data.getSrcAddress().getAddress();
- p.srcPort = data.getSrcPort();
- p.dstAddress = data.getDstAddress().getAddress();
- p.dstPort = data.getDstPort();
- p.seq = tcpSeq;
- p.ack = tcpAck;
- // TcpKeepalivePacketData could actually use non-zero wndScale, but this does not affect
- // actual functionality as generated packets will be the same (no wndScale option added)
- p.rcvWnd = wndSize;
- p.rcvWndScale = 0;
- p.tos = ipTos;
- p.ttl = ttl;
- return p;
- }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index e99113d1296f..acf50b4569c6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -323,6 +323,8 @@ public class DeviceIdleControllerTest {
when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
doNothing().when(mWakeLock).acquire();
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any());
+ doNothing().when(mAlarmManager)
+ .setWindow(anyInt(), anyLong(), anyLong(), anyString(), any(), any());
doReturn(mock(Sensor.class)).when(mSensorManager)
.getDefaultSensor(eq(Sensor.TYPE_SIGNIFICANT_MOTION), eq(true));
doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt());
@@ -1043,24 +1045,28 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
- longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT));
+ longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT),
+ longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
// Should just alternate between IDLE and IDLE_MAINTENANCE now.
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
- longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET));
+ longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
+ longThat(l -> l == mConstants.FLEX_TIME_SHORT));
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
- longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT));
+ longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
+ longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
- longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET));
+ longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
+ longThat(l -> l == mConstants.FLEX_TIME_SHORT));
// Test that motion doesn't reset the idle timeout.
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
@@ -1068,7 +1074,8 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
- longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT));
+ longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
+ longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
}
///////////////// EXIT conditions ///////////////////
@@ -1824,9 +1831,9 @@ public class DeviceIdleControllerTest {
.forClass(AlarmManager.OnAlarmListener.class);
final ArgumentCaptor<AlarmManager.OnAlarmListener> motionRegistrationAlarmListener =
ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);
- doNothing().when(mAlarmManager).set(anyInt(), anyLong(), eq("DeviceIdleController.motion"),
- motionAlarmListener.capture(), any());
- doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+ doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
+ eq("DeviceIdleController.motion"), motionAlarmListener.capture(), any());
+ doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
eq("DeviceIdleController.motion_registration"),
motionRegistrationAlarmListener.capture(), any());
@@ -1900,9 +1907,9 @@ public class DeviceIdleControllerTest {
mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
.forClass(AlarmManager.OnAlarmListener.class);
- doNothing().when(mAlarmManager)
- .set(anyInt(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
- doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+ doNothing().when(mAlarmManager).setWindow(
+ anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
+ doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
eq("DeviceIdleController.motion_registration"),
alarmListener.capture(), any());
ArgumentCaptor<TriggerEventListener> listenerCaptor =
@@ -1944,9 +1951,9 @@ public class DeviceIdleControllerTest {
mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
.forClass(AlarmManager.OnAlarmListener.class);
- doNothing().when(mAlarmManager)
- .set(anyInt(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
- doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+ doNothing().when(mAlarmManager).setWindow(
+ anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
+ doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
eq("DeviceIdleController.motion_registration"),
alarmListener.capture(), any());
ArgumentCaptor<SensorEventListener> listenerCaptor =
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 280204dfd481..eab1afbd931e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -1914,11 +1914,11 @@ public class AlarmManagerServiceTest {
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(false, true, MODE_DEFAULT);
+ assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
- mockExactAlarmPermissionGrant(true, true, MODE_ALLOWED);
- assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+ mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+ assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
}
private void mockChangeEnabled(long changeId, boolean enabled) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index 5a42c4bc7f3a..53483f6d70bc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -31,6 +31,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -57,6 +58,9 @@ import android.service.wallpaper.WallpaperService;
import android.testing.TestableContext;
import android.util.Log;
import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
import android.view.Display;
import androidx.test.filters.FlakyTest;
@@ -82,9 +86,12 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.quality.Strictness;
+import org.xmlpull.v1.XmlPullParserException;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
/**
* Tests for the {@link WallpaperManagerService} class.
@@ -355,6 +362,31 @@ public class WallpaperManagerServiceTests {
verifyDisplayData();
}
+ @Test
+ public void testXmlSerializationRoundtrip() {
+ WallpaperData systemWallpaperData = mService.getCurrentWallpaperData(FLAG_SYSTEM, 0);
+ try {
+ TypedXmlSerializer serializer = Xml.newBinarySerializer();
+ serializer.setOutput(new ByteArrayOutputStream(), StandardCharsets.UTF_8.name());
+ serializer.startDocument(StandardCharsets.UTF_8.name(), true);
+ mService.writeWallpaperAttributes(serializer, "wp", systemWallpaperData);
+ } catch (IOException e) {
+ fail("exception occurred while writing system wallpaper attributes");
+ }
+
+ WallpaperData shouldMatchSystem = new WallpaperData(systemWallpaperData.userId,
+ systemWallpaperData.wallpaperFile.getParentFile(),
+ systemWallpaperData.wallpaperFile.getAbsolutePath(),
+ systemWallpaperData.cropFile.getAbsolutePath());
+ try {
+ TypedXmlPullParser parser = Xml.newBinaryPullParser();
+ mService.parseWallpaperAttributes(parser, shouldMatchSystem, true);
+ } catch (XmlPullParserException e) {
+ fail("exception occurred while parsing wallpaper");
+ }
+ assertEquals(systemWallpaperData.primaryColors, shouldMatchSystem.primaryColors);
+ }
+
// Verify that after continue switch user from userId 0 to lastUserId, the wallpaper data for
// non-current user must not bind to wallpaper service.
private void verifyNoConnectionBeforeLastUser(int lastUserId) {
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 aadaba4d2fce..f4f907355aee 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java
@@ -127,8 +127,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema1",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
@@ -159,8 +159,8 @@ public class AppSearchImplPlatformTest {
new AppSearchSchema.Builder("schema1").build(),
new AppSearchSchema.Builder("schema2").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema1",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
@@ -233,8 +233,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema1",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
@@ -263,8 +263,8 @@ public class AppSearchImplPlatformTest {
"database",
/*schemas=*/ Collections.emptyList(),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*schemaVersion=*/ 0);
@@ -292,8 +292,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
@@ -327,8 +327,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
@@ -355,8 +355,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("Schema"),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.singletonList("Schema"),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
@@ -370,7 +370,7 @@ public class AppSearchImplPlatformTest {
}
@Test
- public void testSetSchema_defaultNotPackageAccessible() throws Exception {
+ public void testSetSchema_defaultNotVisibleToPackages() throws Exception {
String packageName = "com.package";
// Make sure package doesn't global query privileges
@@ -384,8 +384,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
assertThat(mVisibilityStore
@@ -399,7 +399,7 @@ public class AppSearchImplPlatformTest {
}
@Test
- public void testSetSchema_packageAccessible() throws Exception {
+ public void testSetSchema_visibleToPackages() throws Exception {
// Values for a "foo" client
String packageNameFoo = "packageFoo";
byte[] sha256CertFoo = new byte[] {10};
@@ -423,8 +423,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"Schema",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
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 b67ebe423eab..183cb8603c33 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java
@@ -132,7 +132,7 @@ public class VisibilityStoreTest {
}
@Test
- public void testSetVisibility_platformSurfaceable() throws Exception {
+ public void testSetVisibility_displayedBySystem() throws Exception {
// Make sure we have global query privileges
PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
when(mockPackageManager
@@ -143,9 +143,9 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
- /*schemasNotPlatformSurfaceable=*/ ImmutableSet.of(
+ /*schemasNotDisplayedBySystem=*/ ImmutableSet.of(
"prefix/schema1", "prefix/schema2"),
- /*schemasPackageAccessible=*/ Collections.emptyMap());
+ /*schemasVisibleToPackages=*/ Collections.emptyMap());
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
@@ -168,9 +168,9 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
- /*schemasNotPlatformSurfaceable=*/ ImmutableSet.of(
+ /*schemasNotDisplayedBySystem=*/ ImmutableSet.of(
"prefix/schema1", "prefix/schema3"),
- /*schemasPackageAccessible=*/ Collections.emptyMap());
+ /*schemasVisibleToPackages=*/ Collections.emptyMap());
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
@@ -200,8 +200,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
- /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
- /*schemasPackageAccessible=*/ Collections.emptyMap());
+ /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap());
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
@@ -229,7 +229,7 @@ public class VisibilityStoreTest {
}
@Test
- public void testSetVisibility_packageAccessible() throws Exception {
+ public void testSetVisibility_visibleToPackages() throws Exception {
// Values for a "foo" client
String packageNameFoo = "packageFoo";
byte[] sha256CertFoo = new byte[] {10};
@@ -272,8 +272,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
- /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"prefix/schemaFoo",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo)),
"prefix/schemaBar",
@@ -339,8 +339,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
- /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"prefix/schemaFoo",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
@@ -392,8 +392,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
- /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"prefix/schemaFoo",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
@@ -425,8 +425,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
/*packageName=*/ "",
/*databaseName=*/ "",
- /*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
- /*schemasPackageAccessible=*/ ImmutableMap.of(
+ /*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
+ /*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
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 f032402f47a0..02bb168dbde6 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
@@ -22,7 +22,7 @@ import static com.android.server.appsearch.external.localstorage.util.PrefixUtil
import static com.google.common.truth.Truth.assertThat;
-import static org.testng.Assert.expectThrows;
+import static org.junit.Assert.assertThrows;
import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSchema;
@@ -34,6 +34,7 @@ import android.app.appsearch.SetSchemaResponse;
import android.app.appsearch.StorageInfo;
import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context;
+import android.os.Process;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -55,7 +56,6 @@ import com.android.server.appsearch.proto.SearchSpecProto;
import com.android.server.appsearch.proto.StatusProto;
import com.android.server.appsearch.proto.StringIndexingConfig;
import com.android.server.appsearch.proto.TermMatchType;
-import com.android.server.appsearch.visibilitystore.VisibilityStore;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -391,7 +391,7 @@ public class AppSearchImplTest {
DocumentProto.Builder actualDocument = documentProto.toBuilder();
AppSearchException e =
- expectThrows(
+ assertThrows(
AppSearchException.class, () -> removePrefixesFromDocument(actualDocument));
assertThat(e).hasMessageThat().contains("Found unexpected multiple prefix names");
}
@@ -416,7 +416,7 @@ public class AppSearchImplTest {
DocumentProto.Builder actualDocument = documentProto.toBuilder();
AppSearchException e =
- expectThrows(
+ assertThrows(
AppSearchException.class, () -> removePrefixesFromDocument(actualDocument));
assertThat(e).hasMessageThat().contains("Found unexpected multiple prefix names");
}
@@ -431,8 +431,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -480,8 +480,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -499,7 +499,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
/*visibilityStore=*/ null,
- VisibilityStore.NO_OP_UID,
+ Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
@@ -513,7 +513,7 @@ public class AppSearchImplTest {
.setSchema(context.getPackageName() + "$database1/Type1")
.build();
AppSearchException e =
- expectThrows(
+ assertThrows(
AppSearchException.class,
() -> PrefixUtil.getPrefix(invalidDoc.getNamespace()));
assertThat(e)
@@ -538,10 +538,8 @@ public class AppSearchImplTest {
assertThat(initStats.hasDeSync()).isFalse();
assertThat(initStats.getDocumentStoreRecoveryCause())
.isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
- // TODO(b/187879464): There should not be a recovery here, but icing lib reports one if the
- // doc had no tokens. Once the mentioned bug is fixed, uncomment this.
- // assertThat(initStats.getIndexRestorationCause())
- // .isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
+ assertThat(initStats.getIndexRestorationCause())
+ .isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
assertThat(initStats.getSchemaStoreRecoveryCause())
.isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
assertThat(initStats.getDocumentStoreDataStatus())
@@ -558,7 +556,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
/*visibilityStore=*/ null,
- VisibilityStore.NO_OP_UID,
+ Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).isEmpty();
@@ -569,8 +567,8 @@ public class AppSearchImplTest {
"database1",
Collections.singletonList(new AppSearchSchema.Builder("Type1").build()),
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -585,7 +583,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
/*visibilityStore=*/ null,
- VisibilityStore.NO_OP_UID,
+ Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
@@ -604,8 +602,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -638,8 +636,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -647,8 +645,8 @@ public class AppSearchImplTest {
"database2",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -692,8 +690,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -734,8 +732,8 @@ public class AppSearchImplTest {
"database1",
schema1,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -747,8 +745,8 @@ public class AppSearchImplTest {
"database2",
schema2,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -790,8 +788,8 @@ public class AppSearchImplTest {
"database1",
schema1,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -803,8 +801,8 @@ public class AppSearchImplTest {
"database2",
schema2,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -851,7 +849,7 @@ public class AppSearchImplTest {
searchSpec,
/*callerPackageName=*/ "",
/*visibilityStore=*/ null,
- VisibilityStore.NO_OP_UID,
+ Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(searchResultPage.getResults()).isEmpty();
@@ -893,8 +891,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -938,8 +936,8 @@ public class AppSearchImplTest {
"database1",
oldSchemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -954,8 +952,8 @@ public class AppSearchImplTest {
"database1",
newSchemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*version=*/ 0);
assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("Text");
@@ -977,8 +975,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1010,8 +1008,8 @@ public class AppSearchImplTest {
"database1",
finalSchemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1024,8 +1022,8 @@ public class AppSearchImplTest {
"database1",
finalSchemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*version=*/ 0);
@@ -1062,8 +1060,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -1071,8 +1069,8 @@ public class AppSearchImplTest {
"database2",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1111,8 +1109,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*version=*/ 0);
@@ -1156,8 +1154,8 @@ public class AppSearchImplTest {
"database",
schema,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1218,8 +1216,8 @@ public class AppSearchImplTest {
"database",
schema,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -1227,8 +1225,8 @@ public class AppSearchImplTest {
"database",
schema,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1273,8 +1271,8 @@ public class AppSearchImplTest {
"database1",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
assertThat(mAppSearchImpl.getPackageToDatabases())
@@ -1287,8 +1285,8 @@ public class AppSearchImplTest {
"database2",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
assertThat(mAppSearchImpl.getPackageToDatabases())
@@ -1301,8 +1299,8 @@ public class AppSearchImplTest {
"database1",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
assertThat(mAppSearchImpl.getPackageToDatabases())
@@ -1360,8 +1358,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1511,8 +1509,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1534,8 +1532,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1550,8 +1548,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1599,8 +1597,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1622,8 +1620,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1644,8 +1642,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -1653,8 +1651,8 @@ public class AppSearchImplTest {
"database2",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1700,15 +1698,15 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
appSearchImpl.close();
// Check all our public APIs
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.setSchema(
@@ -1716,15 +1714,15 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0));
- expectThrows(
+ assertThrows(
IllegalStateException.class, () -> appSearchImpl.getSchema("package", "database"));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.putDocument(
@@ -1733,13 +1731,13 @@ public class AppSearchImplTest {
new GenericDocument.Builder<>("namespace", "id", "type").build(),
/*logger=*/ null));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.getDocument(
"package", "database", "namespace", "id", Collections.emptyMap()));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.query(
@@ -1749,7 +1747,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().build(),
/*logger=*/ null));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.globalQuery(
@@ -1757,19 +1755,19 @@ public class AppSearchImplTest {
new SearchSpec.Builder().build(),
"package",
/*visibilityStore=*/ null,
- VisibilityStore.NO_OP_UID,
+ Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() -> appSearchImpl.getNextPage(/*nextPageToken=*/ 1L));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() -> appSearchImpl.invalidateNextPageToken(/*nextPageToken=*/ 1L));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.reportUsage(
@@ -1780,7 +1778,7 @@ public class AppSearchImplTest {
/*usageTimestampMillis=*/ 1000L,
/*systemUsage=*/ false));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.remove(
@@ -1790,7 +1788,7 @@ public class AppSearchImplTest {
"id",
/*removeStatsBuilder=*/ null));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.removeByQuery(
@@ -1800,15 +1798,15 @@ public class AppSearchImplTest {
new SearchSpec.Builder().build(),
/*removeStatsBuilder=*/ null));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() -> appSearchImpl.getStorageInfoForPackage("package"));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() -> appSearchImpl.getStorageInfoForDatabase("package", "database"));
- expectThrows(
+ assertThrows(
IllegalStateException.class,
() -> appSearchImpl.persistToDisk(PersistType.Code.FULL));
}
@@ -1827,8 +1825,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1866,8 +1864,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1892,7 +1890,7 @@ public class AppSearchImplTest {
// Delete the first document
appSearchImpl.remove("package", "database", "namespace1", "id1", /*statsBuilder=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
- expectThrows(
+ assertThrows(
AppSearchException.class,
() ->
appSearchImpl.getDocument(
@@ -1909,7 +1907,7 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
- expectThrows(
+ assertThrows(
AppSearchException.class,
() ->
appSearchImpl2.getDocument(
@@ -1938,8 +1936,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1972,7 +1970,7 @@ public class AppSearchImplTest {
.build(),
/*statsBuilder=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
- expectThrows(
+ assertThrows(
AppSearchException.class,
() ->
appSearchImpl.getDocument(
@@ -1989,7 +1987,7 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
- expectThrows(
+ assertThrows(
AppSearchException.class,
() ->
appSearchImpl2.getDocument(
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 f20e8c6d13a9..9b75561fd2ec 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
@@ -25,6 +25,7 @@ import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
+import android.app.appsearch.exceptions.AppSearchException;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
@@ -32,17 +33,24 @@ import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
import com.android.server.appsearch.proto.DeleteStatsProto;
+import com.android.server.appsearch.proto.DocumentProto;
import com.android.server.appsearch.proto.InitializeStatsProto;
import com.android.server.appsearch.proto.PutDocumentStatsProto;
+import com.android.server.appsearch.proto.PutResultProto;
import com.android.server.appsearch.proto.QueryStatsProto;
import com.android.server.appsearch.proto.ScoringSpecProto;
+import com.android.server.appsearch.proto.StatusProto;
import com.android.server.appsearch.proto.TermMatchType;
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import java.io.File;
import java.util.Collections;
import java.util.List;
@@ -279,7 +287,7 @@ public class AppSearchLoggerTest {
// Testing actual logging
//
@Test
- public void testLoggingStats_initialize() throws Exception {
+ public void testLoggingStats_initializeWithoutDocuments_success() throws Exception {
// Create an unused AppSearchImpl to generated an InitializeStats.
InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
AppSearchImpl.create(mTemporaryFolder.newFolder(), initStatsBuilder, ALWAYS_OPTIMIZE);
@@ -295,25 +303,139 @@ public class AppSearchLoggerTest {
.isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
assertThat(iStats.getDocumentCount()).isEqualTo(0);
assertThat(iStats.getSchemaTypeCount()).isEqualTo(0);
+ assertThat(iStats.hasReset()).isEqualTo(false);
+ assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
}
@Test
- public void testLoggingStats_putDocument() throws Exception {
- // Insert schema
+ public void testLoggingStats_initializeWithDocuments_success() throws Exception {
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
+ final File folder = mTemporaryFolder.newFolder();
+
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(folder, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
- Collections.singletonList(new AppSearchSchema.Builder("type").build());
+ ImmutableList.of(
+ new AppSearchSchema.Builder("Type1").build(),
+ new AppSearchSchema.Builder("Type2").build());
+ appSearchImpl.setSchema(
+ testPackageName,
+ testDatabase,
+ schemas,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+ GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
+ GenericDocument doc2 = new GenericDocument.Builder<>("namespace", "id2", "Type1").build();
+ appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
+ appSearchImpl.putDocument(testPackageName, testDatabase, doc2, mLogger);
+ appSearchImpl.close();
+
+ // Create another appsearchImpl on the same folder
+ InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
+ AppSearchImpl.create(folder, initStatsBuilder, ALWAYS_OPTIMIZE);
+ InitializeStats iStats = initStatsBuilder.build();
+
+ assertThat(iStats).isNotNull();
+ assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
+ // Total latency captured in LocalStorage
+ assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
+ assertThat(iStats.hasDeSync()).isFalse();
+ assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
+ assertThat(iStats.getDocumentStoreDataStatus())
+ .isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
+ assertThat(iStats.getDocumentCount()).isEqualTo(2);
+ assertThat(iStats.getSchemaTypeCount()).isEqualTo(2);
+ assertThat(iStats.hasReset()).isEqualTo(false);
+ assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
+ }
+
+ @Test
+ public void testLoggingStats_initialize_failure() throws Exception {
+ final String testPackageName = "testPackage";
+ final String testDatabase = "testDatabase";
+ final File folder = mTemporaryFolder.newFolder();
+
+ AppSearchImpl appSearchImpl =
+ AppSearchImpl.create(folder, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+
+ List<AppSearchSchema> schemas =
+ ImmutableList.of(
+ new AppSearchSchema.Builder("Type1").build(),
+ new AppSearchSchema.Builder("Type2").build());
+ appSearchImpl.setSchema(
+ testPackageName,
+ testDatabase,
+ schemas,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ // Insert a valid doc
+ GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
+ appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
+
+ // Insert the invalid doc with an invalid namespace right into icing
+ DocumentProto invalidDoc =
+ DocumentProto.newBuilder()
+ .setNamespace("invalidNamespace")
+ .setUri("id2")
+ .setSchema(String.format("%s$%s/Type1", testPackageName, testDatabase))
+ .build();
+ PutResultProto putResultProto = appSearchImpl.mIcingSearchEngineLocked.put(invalidDoc);
+ assertThat(putResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.OK);
+ appSearchImpl.close();
+
+ // Create another appsearchImpl on the same folder
+ InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
+ AppSearchImpl.create(folder, initStatsBuilder, ALWAYS_OPTIMIZE);
+ InitializeStats iStats = initStatsBuilder.build();
+
+ // Some of other fields are already covered by AppSearchImplTest#testReset()
+ assertThat(iStats).isNotNull();
+ assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
+ assertThat(iStats.hasReset()).isTrue();
+ }
+
+ @Test
+ public void testLoggingStats_putDocument_success() throws Exception {
+ // Insert schema
+ final String testPackageName = "testPackage";
+ final String testDatabase = "testDatabase";
+ AppSearchSchema testSchema =
+ new AppSearchSchema.Builder("type")
+ .addProperty(
+ new AppSearchSchema.StringPropertyConfig.Builder("subject")
+ .setCardinality(
+ AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+ .setIndexingType(
+ AppSearchSchema.StringPropertyConfig
+ .INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(
+ AppSearchSchema.StringPropertyConfig
+ .TOKENIZER_TYPE_PLAIN)
+ .build())
+ .build();
+ List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
- GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
+
+ GenericDocument document =
+ new GenericDocument.Builder<>("namespace", "id", "type")
+ .setPropertyString("subject", "testPut example1")
+ .build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
@@ -322,43 +444,119 @@ public class AppSearchLoggerTest {
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
+ // The latency related native stats have been tested in testCopyNativeStats
assertThat(pStats.getNativeDocumentSizeBytes()).isGreaterThan(0);
+ assertThat(pStats.getNativeNumTokensIndexed()).isGreaterThan(0);
}
@Test
- public void testLoggingStats_search() throws Exception {
+ public void testLoggingStats_putDocument_failure() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
- List<AppSearchSchema> schemas =
- Collections.singletonList(new AppSearchSchema.Builder("type").build());
+ AppSearchSchema testSchema =
+ new AppSearchSchema.Builder("type")
+ .addProperty(
+ new AppSearchSchema.StringPropertyConfig.Builder("subject")
+ .setCardinality(
+ AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+ .setIndexingType(
+ AppSearchSchema.StringPropertyConfig
+ .INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(
+ AppSearchSchema.StringPropertyConfig
+ .TOKENIZER_TYPE_PLAIN)
+ .build())
+ .build();
+ List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
- GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
- mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
+ GenericDocument document =
+ new GenericDocument.Builder<>("namespace", "id", "type")
+ .setPropertyString("nonExist", "testPut example1")
+ .build();
+
+ // We mainly want to check the status code in stats. So we don't need to inspect the
+ // exception here.
+ Assert.assertThrows(
+ AppSearchException.class,
+ () -> mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger));
+
+ PutDocumentStats pStats = mLogger.mPutDocumentStats;
+ assertThat(pStats).isNotNull();
+ assertThat(pStats.getPackageName()).isEqualTo(testPackageName);
+ assertThat(pStats.getDatabase()).isEqualTo(testDatabase);
+ assertThat(pStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
+ }
+
+ @Test
+ public void testLoggingStats_search_success() throws Exception {
+ // Insert schema
+ final String testPackageName = "testPackage";
+ final String testDatabase = "testDatabase";
+ AppSearchSchema testSchema =
+ new AppSearchSchema.Builder("type")
+ .addProperty(
+ new AppSearchSchema.StringPropertyConfig.Builder("subject")
+ .setCardinality(
+ AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+ .setIndexingType(
+ AppSearchSchema.StringPropertyConfig
+ .INDEXING_TYPE_PREFIXES)
+ .setTokenizerType(
+ AppSearchSchema.StringPropertyConfig
+ .TOKENIZER_TYPE_PLAIN)
+ .build())
+ .build();
+ List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
+ mAppSearchImpl.setSchema(
+ testPackageName,
+ testDatabase,
+ schemas,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+ GenericDocument document1 =
+ new GenericDocument.Builder<>("namespace", "id1", "type")
+ .setPropertyString("subject", "testPut example1")
+ .build();
+ GenericDocument document2 =
+ new GenericDocument.Builder<>("namespace", "id2", "type")
+ .setPropertyString("subject", "testPut example2")
+ .build();
+ GenericDocument document3 =
+ new GenericDocument.Builder<>("namespace", "id3", "type")
+ .setPropertyString("subject", "testPut 3")
+ .build();
+ mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
+ mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
+ mAppSearchImpl.putDocument(testPackageName, testDatabase, document3, mLogger);
// No query filters specified. package2 should only get its own documents back.
SearchSpec searchSpec =
- new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
+ .build();
+ String queryStr = "testPut e";
SearchResultPage searchResultPage =
mAppSearchImpl.query(
- testPackageName,
- testDatabase,
- /*QueryExpression=*/ "",
- searchSpec,
- /*logger=*/ mLogger);
+ testPackageName, testDatabase, queryStr, searchSpec, /*logger=*/ mLogger);
- assertThat(searchResultPage.getResults()).hasSize(1);
- assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
+ assertThat(searchResultPage.getResults()).hasSize(2);
+ // The ranking strategy is LIFO
+ assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
+ assertThat(searchResultPage.getResults().get(1).getGenericDocument()).isEqualTo(document1);
SearchStats sStats = mLogger.mSearchStats;
@@ -368,17 +566,59 @@ public class AppSearchLoggerTest {
assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
assertThat(sStats.getTotalLatencyMillis()).isGreaterThan(0);
assertThat(sStats.getVisibilityScope()).isEqualTo(SearchStats.VISIBILITY_SCOPE_LOCAL);
- assertThat(sStats.getTermCount()).isEqualTo(0);
- // assertThat(sStats.getNativeQueryLength()).isEqualTo(0);
+ assertThat(sStats.getTermCount()).isEqualTo(2);
+ assertThat(sStats.getQueryLength()).isEqualTo(queryStr.length());
assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(1);
assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(1);
- assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(1);
+ assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(2);
assertThat(sStats.isFirstPage()).isTrue();
- assertThat(sStats.getScoredDocumentCount()).isEqualTo(1);
+ assertThat(sStats.getRankingStrategy())
+ .isEqualTo(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP);
+ assertThat(sStats.getScoredDocumentCount()).isEqualTo(2);
+ assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void testLoggingStats_search_failure() throws Exception {
+ final String testPackageName = "testPackage";
+ final String testDatabase = "testDatabase";
+ List<AppSearchSchema> schemas =
+ ImmutableList.of(
+ new AppSearchSchema.Builder("Type1").build(),
+ new AppSearchSchema.Builder("Type2").build());
+ mAppSearchImpl.setSchema(
+ testPackageName,
+ testDatabase,
+ schemas,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ SearchSpec searchSpec =
+ new SearchSpec.Builder()
+ .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
+ .setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
+ .addFilterPackageNames("anotherPackage")
+ .build();
+
+ mAppSearchImpl.query(
+ testPackageName,
+ testPackageName,
+ /* queryExpression= */ "",
+ searchSpec,
+ /*logger=*/ mLogger);
+
+ SearchStats sStats = mLogger.mSearchStats;
+ assertThat(sStats).isNotNull();
+ assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
+ assertThat(sStats.getDatabase()).isEqualTo(testPackageName);
+ assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
}
@Test
- public void testLoggingStats_remove() throws Exception {
+ public void testLoggingStats_remove_success() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
@@ -391,8 +631,8 @@ public class AppSearchLoggerTest {
testDatabase,
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document =
@@ -406,12 +646,59 @@ public class AppSearchLoggerTest {
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
// delete by namespace + id
+ assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(1);
}
@Test
- public void testLoggingStats_removeByQuery() throws Exception {
+ public void testLoggingStats_remove_failure() throws Exception {
+ // Insert schema
+ final String testPackageName = "testPackage";
+ final String testDatabase = "testDatabase";
+ final String testNamespace = "testNameSpace";
+ final String testId = "id";
+ List<AppSearchSchema> schemas =
+ Collections.singletonList(new AppSearchSchema.Builder("type").build());
+ mAppSearchImpl.setSchema(
+ testPackageName,
+ testDatabase,
+ schemas,
+ /*visibilityStore=*/ null,
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+ /*forceOverride=*/ false,
+ /*version=*/ 0);
+
+ GenericDocument document =
+ new GenericDocument.Builder<>(testNamespace, testId, "type").build();
+ mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
+
+ RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
+
+ // We mainly want to check the status code in stats. So we don't need to inspect the
+ // exception here.
+ Assert.assertThrows(
+ AppSearchException.class,
+ () ->
+ mAppSearchImpl.remove(
+ testPackageName,
+ testDatabase,
+ testNamespace,
+ "invalidId",
+ rStatsBuilder));
+
+ RemoveStats rStats = rStatsBuilder.build();
+ assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
+ assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
+ assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
+ // delete by namespace + id
+ assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
+ assertThat(rStats.getDeletedDocumentCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void testLoggingStats_removeByQuery_success() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
@@ -423,8 +710,8 @@ public class AppSearchLoggerTest {
testDatabase,
schemas,
/*visibilityStore=*/ null,
- /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
+ /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
+ /*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document1 =
@@ -444,6 +731,7 @@ public class AppSearchLoggerTest {
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
+ assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
// delete by query
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.QUERY_VALUE);
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(2);
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
index d3feb12912ad..64a670dcdb38 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
@@ -46,7 +46,6 @@ public class SnippetTest {
PREFIX,
Collections.singletonMap(PREFIX + SCHEMA_TYPE, SCHEMA_TYPE_CONFIG_PROTO));
- // TODO(tytytyww): Add tests for Double and Long Snippets.
@Test
public void testSingleStringSnippet() {
final String propertyKeyString = "content";
@@ -112,7 +111,6 @@ public class SnippetTest {
assertThat(match.getSnippet()).isEqualTo(window);
}
- // TODO(tytytyww): Add tests for Double and Long Snippets.
@Test
public void testNoSnippets() {
final String propertyKeyString = "content";
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 6d9068675a72..57d994155d5b 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
@@ -254,14 +254,25 @@ public class AppSearchStatsTest {
@Test
public void testAppSearchStats_SetSchemaStats() {
+ SchemaMigrationStats schemaMigrationStats =
+ new SchemaMigrationStats.Builder()
+ .setGetSchemaLatencyMillis(1)
+ .setQueryAndTransformLatencyMillis(2)
+ .setFirstSetSchemaLatencyMillis(3)
+ .setSecondSetSchemaLatencyMillis(4)
+ .setSaveDocumentLatencyMillis(5)
+ .setMigratedDocumentCount(6)
+ .setSavedDocumentCount(7)
+ .build();
int nativeLatencyMillis = 1;
int newTypeCount = 2;
int compatibleTypeChangeCount = 3;
int indexIncompatibleTypeChangeCount = 4;
int backwardsIncompatibleTypeChangeCount = 5;
- final SetSchemaStats sStats =
+ SetSchemaStats sStats =
new SetSchemaStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
.setStatusCode(TEST_STATUS_CODE)
+ .setSchemaMigrationStats(schemaMigrationStats)
.setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
.setNativeLatencyMillis(nativeLatencyMillis)
.setNewTypeCount(newTypeCount)
@@ -274,6 +285,7 @@ public class AppSearchStatsTest {
assertThat(sStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
assertThat(sStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
assertThat(sStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(sStats.getSchemaMigrationStats()).isEqualTo(schemaMigrationStats);
assertThat(sStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
assertThat(sStats.getNewTypeCount()).isEqualTo(newTypeCount);
@@ -285,6 +297,35 @@ public class AppSearchStatsTest {
}
@Test
+ public void testAppSearchStats_SchemaMigrationStats() {
+ int getSchemaLatency = 1;
+ int queryAndTransformLatency = 2;
+ int firstSetSchemaLatency = 3;
+ int secondSetSchemaLatency = 4;
+ int saveDocumentLatency = 5;
+ int migratedDocumentCount = 6;
+ int savedDocumentCount = 7;
+ SchemaMigrationStats sStats =
+ new SchemaMigrationStats.Builder()
+ .setGetSchemaLatencyMillis(getSchemaLatency)
+ .setQueryAndTransformLatencyMillis(queryAndTransformLatency)
+ .setFirstSetSchemaLatencyMillis(firstSetSchemaLatency)
+ .setSecondSetSchemaLatencyMillis(secondSetSchemaLatency)
+ .setSaveDocumentLatencyMillis(saveDocumentLatency)
+ .setMigratedDocumentCount(migratedDocumentCount)
+ .setSavedDocumentCount(savedDocumentCount)
+ .build();
+
+ assertThat(sStats.getGetSchemaLatencyMillis()).isEqualTo(getSchemaLatency);
+ assertThat(sStats.getQueryAndTransformLatencyMillis()).isEqualTo(queryAndTransformLatency);
+ assertThat(sStats.getFirstSetSchemaLatencyMillis()).isEqualTo(firstSetSchemaLatency);
+ assertThat(sStats.getSecondSetSchemaLatencyMillis()).isEqualTo(secondSetSchemaLatency);
+ assertThat(sStats.getSaveDocumentLatencyMillis()).isEqualTo(saveDocumentLatency);
+ assertThat(sStats.getMigratedDocumentCount()).isEqualTo(migratedDocumentCount);
+ assertThat(sStats.getSavedDocumentCount()).isEqualTo(savedDocumentCount);
+ }
+
+ @Test
public void testAppSearchStats_RemoveStats() {
int nativeLatencyMillis = 1;
@RemoveStats.DeleteType int deleteType = 2;
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 c0df2e33ffed..cae6c863ab02 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -48,8 +48,11 @@ import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Handler;
@@ -120,7 +123,7 @@ public class DisplayModeDirectorTest {
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext);
when(mContext.getContentResolver()).thenReturn(resolver);
- mInjector = new FakesInjector();
+ mInjector = spy(new FakesInjector());
mHandler = new Handler(Looper.getMainLooper());
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
@@ -1256,13 +1259,163 @@ public class DisplayModeDirectorTest {
assertNull(vote);
}
+ @Test
+ public void testHbmVoting_forHdr() {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
+ director.start(createMockSensorManager());
+
+ ArgumentCaptor<DisplayListener> captor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+ | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ DisplayListener listener = captor.getValue();
+
+ // Specify Limitation
+ when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
+ List.of(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
+ 60.f, 60.f)));
+
+ // Verify that there is no HBM vote initially
+ Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertVoteForRefreshRate(vote, 60.f);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+ }
+
+ @Test
+ public void testHbmVoting_forSunlight() {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
+ director.start(createMockSensorManager());
+
+ ArgumentCaptor<DisplayListener> captor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+ | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ DisplayListener listener = captor.getValue();
+
+ // Specify Limitation
+ when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
+ List.of(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
+ 60.f, 60.f)));
+
+ // Verify that there is no HBM vote initially
+ Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertVoteForRefreshRate(vote, 60.f);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+ }
+
+ @Test
+ public void testHbmVoting_forSunlight_NoLimitation() {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
+ director.start(createMockSensorManager());
+
+ ArgumentCaptor<DisplayListener> captor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+ | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ DisplayListener listener = captor.getValue();
+
+ // Specify Limitation for different display
+ when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID + 1)).thenReturn(
+ List.of(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
+ 60.f, 60.f)));
+
+ // Verify that there is no HBM vote initially
+ Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn off HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(0.43f, 0.1f, 0.8f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+ }
+
+ @Test
+ public void testHbmVoting_RemovedDisplay() {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0);
+ director.start(createMockSensorManager());
+
+ ArgumentCaptor<DisplayListener> captor =
+ ArgumentCaptor.forClass(DisplayListener.class);
+ verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+ | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ DisplayListener listener = captor.getValue();
+
+ // Specify Limitation for different display
+ when(mDisplayManagerInternalMock.getRefreshRateLimitations(DISPLAY_ID)).thenReturn(
+ List.of(new RefreshRateLimitation(
+ DisplayManagerInternal.REFRESH_RATE_LIMIT_HIGH_BRIGHTNESS_MODE,
+ 60.f, 60.f)));
+
+ // Verify that there is no HBM vote initially
+ Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+
+ // Turn on HBM
+ when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
+ new BrightnessInfo(1.0f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT));
+ listener.onDisplayChanged(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertVoteForRefreshRate(vote, 60.f);
+
+ // Turn off HBM
+ listener.onDisplayRemoved(DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE);
+ assertNull(vote);
+ }
+
private void assertVoteForRefreshRate(Vote vote, float refreshRate) {
assertThat(vote).isNotNull();
final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate);
assertThat(vote.refreshRateRange).isEqualTo(expectedRange);
}
- private static class FakeDeviceConfig extends FakeDeviceConfigInterface {
+ public static class FakeDeviceConfig extends FakeDeviceConfigInterface {
@Override
public String getProperty(String namespace, String name) {
Preconditions.checkArgument(DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace));
@@ -1403,7 +1556,7 @@ public class DisplayModeDirectorTest {
mHandler.runWithScissors(() -> { }, 500 /*timeout*/);
}
- static class FakesInjector implements DisplayModeDirector.Injector {
+ public static class FakesInjector implements DisplayModeDirector.Injector {
private final FakeDeviceConfig mDeviceConfig;
private ContentObserver mBrightnessObserver;
private ContentObserver mPeakRefreshRateObserver;
@@ -1444,6 +1597,14 @@ public class DisplayModeDirectorTest {
mPeakRefreshRateObserver = observer;
}
+ @Override
+ public void registerDisplayListener(DisplayListener listener, Handler handler, long flag) {}
+
+ @Override
+ public BrightnessInfo getBrightnessInfo(int displayId) {
+ return null;
+ }
+
void notifyPeakRefreshRateChanged() {
if (mPeakRefreshRateObserver != null) {
mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/,
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 7df2dd6988bf..019254d542b2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -649,7 +649,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
protected class MockAppSearchManager implements IAppSearchManager {
- protected Map<String, List<PackageIdentifier>> mSchemasPackageAccessible =
+ protected Map<String, List<PackageIdentifier>> mSchemasVisibleToPackages =
new ArrayMap<>(1);
private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1);
@@ -659,19 +659,19 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override
public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles,
- List<String> schemasNotPlatformSurfaceable,
- Map<String, List<Bundle>> schemasPackageAccessibleBundles, boolean forceOverride,
+ List<String> schemasNotDisplayedBySystem,
+ Map<String, List<Bundle>> schemasVisibleToPackagesBundles, boolean forceOverride,
int version, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchResultCallback callback) throws RemoteException {
for (Map.Entry<String, List<Bundle>> entry :
- schemasPackageAccessibleBundles.entrySet()) {
+ schemasVisibleToPackagesBundles.entrySet()) {
final String key = entry.getKey();
final List<PackageIdentifier> packageIdentifiers;
- if (!mSchemasPackageAccessible.containsKey(key)) {
+ if (!mSchemasVisibleToPackages.containsKey(key)) {
packageIdentifiers = new ArrayList<>(entry.getValue().size());
- mSchemasPackageAccessible.put(key, packageIdentifiers);
+ mSchemasVisibleToPackages.put(key, packageIdentifiers);
} else {
- packageIdentifiers = mSchemasPackageAccessible.get(key);
+ packageIdentifiers = mSchemasVisibleToPackages.get(key);
}
for (int i = 0; i < entry.getValue().size(); i++) {
packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 558fb309ad98..976a588273a7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -18,7 +18,11 @@ package com.android.server.pm;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.fail;
+
import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isPrivate;
+import static java.lang.reflect.Modifier.isProtected;
import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isStatic;
@@ -44,9 +48,12 @@ import org.junit.runner.RunWith;
import java.io.File;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
@@ -393,6 +400,178 @@ public class PackageManagerServiceTest {
Assert.assertEquals(3600000003L, multiPackage[1].timeouts.maxPendingTimeUs);
}
+ // Report an error from the Computer structure validation test.
+ private void flag(String name, String msg) {
+ fail(name + " " + msg);
+ }
+
+ // Return a string that identifies a Method. This is not very efficient but it is not
+ // called very often.
+ private String displayName(Method m) {
+ String r = m.getName();
+ String p = Arrays.toString(m.getGenericParameterTypes())
+ .replaceAll("([a-zA-Z0-9]+\\.)+", "")
+ .replace("class ", "")
+ .replaceAll("^\\[", "(")
+ .replaceAll("\\]$", ")");
+ return r + p;
+ }
+
+ // Match a method to an array of Methods. Matching is on method signature: name and
+ // parameter types. If a method in the declared array matches, return it. Otherwise
+ // return null.
+ private Method matchMethod(Method m, Method[] declared) {
+ String n = m.getName();
+ Type[] t = m.getGenericParameterTypes();
+ for (int i = 0; i < declared.length; i++) {
+ Method l = declared[i];
+ if (l != null && l.getName().equals(n)
+ && Arrays.equals(l.getGenericParameterTypes(), t)) {
+ Method result = l;
+ // Set the method to null since it has been visited already.
+ declared[i] = null;
+ return result;
+ }
+ }
+ return null;
+ }
+
+ // Return the boolean locked value. A null return means the annotation was not
+ // found. This method will fail if the annotation is found but is not one of the
+ // known constants.
+ private Boolean getOverride(Method m) {
+ final String name = "Computer." + displayName(m);
+ final PackageManagerService.Computer.LiveImplementation annotation =
+ m.getAnnotation(PackageManagerService.Computer.LiveImplementation.class);
+ if (annotation == null) {
+ return null;
+ }
+ final int override = annotation.override();
+ if (override == PackageManagerService.Computer.LiveImplementation.MANDATORY) {
+ return true;
+ } else if (override == PackageManagerService.Computer.LiveImplementation.NOT_ALLOWED) {
+ return false;
+ } else {
+ flag(name, "invalid Live value: " + override);
+ return null;
+ }
+ }
+
+ @Test
+ public void testComputerStructure() {
+ // Verify that Copmuter methods are properly annotated and that ComputerLocked is
+ // properly populated per annotations.
+ // Call PackageManagerService.validateComputer();
+ Class base = PackageManagerService.Computer.class;
+
+ HashMap<Method, Boolean> methodType = new HashMap<>();
+
+ // Verify that all Computer methods are annotated and that the annotation
+ // parameter locked() is valid.
+ for (Method m : base.getDeclaredMethods()) {
+ final String name = "Computer." + displayName(m);
+ Boolean override = getOverride(m);
+ if (override == null) {
+ flag(name, "missing required Live annotation");
+ }
+ methodType.put(m, override);
+ }
+
+ Class coreClass = PackageManagerService.ComputerEngine.class;
+ final Method[] coreMethods = coreClass.getDeclaredMethods();
+
+ // Examine every method in the core. If it inherits from a base method it must be
+ // "public final" if the base is NOT_ALLOWED or "public" if the base is MANDATORY.
+ // If the core method does not inherit from the base then it must be either
+ // private or protected.
+ for (Method m : base.getDeclaredMethods()) {
+ String name = "Computer." + displayName(m);
+ final boolean locked = methodType.get(m);
+ final Method core = matchMethod(m, coreMethods);
+ if (core == null) {
+ flag(name, "not overridden in ComputerEngine");
+ continue;
+ }
+ name = "ComputerEngine." + displayName(m);
+ final int modifiers = core.getModifiers();
+ if (!locked) {
+ if (!isPublic(modifiers)) {
+ flag(name, "is not public");
+ }
+ if (!isFinal(modifiers)) {
+ flag(name, "is not final");
+ }
+ }
+ }
+ // Any methods left in the coreMethods array must be private or protected.
+ // Protected methods must be overridden (and final) in the live list.
+ Method[] coreHelpers = new Method[coreMethods.length];
+ int coreIndex = 0;
+ for (Method m : coreMethods) {
+ if (m != null) {
+ final String name = "ComputerEngine." + displayName(m);
+ final int modifiers = m.getModifiers();
+ if (isPrivate(modifiers)) {
+ // Okay
+ } else if (isProtected(modifiers)) {
+ coreHelpers[coreIndex++] = m;
+ } else {
+ flag(name, "is neither private nor protected");
+ }
+ }
+ }
+
+ Class liveClass = PackageManagerService.ComputerLocked.class;
+ final Method[] liveMethods = liveClass.getDeclaredMethods();
+
+ // Examine every method in the live list. Every method must be final and must
+ // inherit either from base or core. If the method inherits from a base method
+ // then the base must be MANDATORY.
+ for (Method m : base.getDeclaredMethods()) {
+ String name = "Computer." + displayName(m);
+ final boolean locked = methodType.get(m);
+ final Method live = matchMethod(m, liveMethods);
+ if (live == null) {
+ if (locked) {
+ flag(name, "not overridden in ComputerLocked");
+ }
+ continue;
+ }
+ if (!locked) {
+ flag(name, "improperly overridden in ComputerLocked");
+ continue;
+ }
+
+ name = "ComputerLocked." + displayName(m);
+ final int modifiers = live.getModifiers();
+ if (!locked) {
+ if (!isPublic(modifiers)) {
+ flag(name, "is not public");
+ }
+ if (!isFinal(modifiers)) {
+ flag(name, "is not final");
+ }
+ }
+ }
+ for (Method m : coreHelpers) {
+ if (m == null) {
+ continue;
+ }
+ String name = "ComputerLocked." + displayName(m);
+ final Method live = matchMethod(m, liveMethods);
+ if (live == null) {
+ flag(name, "is not overridden in ComputerLocked");
+ continue;
+ }
+ }
+ for (Method m : liveMethods) {
+ if (m != null) {
+ String name = "ComputerLocked." + displayName(m);
+ flag(name, "illegal local method");
+ }
+ }
+ }
+
private static PerPackageReadTimeouts[] getPerPackageReadTimeouts(String knownDigestersList) {
final String defaultTimeouts = "3600000001:3600000002:3600000003";
List<PerPackageReadTimeouts> result = PerPackageReadTimeouts.parseDigestersList(
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 17d99e652726..f880563e2880 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -222,6 +222,64 @@ public class SystemConfigTest {
}
/**
+ * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_APP_CONFIGS}
+ * permission flag for the tag: {@code allowed-partner-apex}.
+ */
+ @Test
+ public void readPermissions_allowAppConfigs_parsesPartnerApexAllowList()
+ throws IOException {
+ final String contents =
+ "<config>\n"
+ + " <allowed-partner-apex package=\"com.android.apex1\" />\n"
+ + "</config>";
+ final File folder = createTempSubfolder("folder");
+ createTempFile(folder, "partner-apex-allowlist.xml", contents);
+
+ mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
+
+ assertThat(mSysConfig.getAllowedPartnerApexes()).containsExactly("com.android.apex1");
+ }
+
+ /**
+ * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_APP_CONFIGS}
+ * permission flag for the tag: {@code allowed-partner-apex}.
+ */
+ @Test
+ public void readPermissions_allowAppConfigs_parsesPartnerApexAllowList_noPackage()
+ throws IOException {
+ final String contents =
+ "<config>\n"
+ + " <allowed-partner-apex/>\n"
+ + "</config>";
+ final File folder = createTempSubfolder("folder");
+ createTempFile(folder, "partner-apex-allowlist.xml", contents);
+
+ mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
+
+ assertThat(mSysConfig.getAllowedPartnerApexes()).isEmpty();
+ }
+
+
+ /**
+ * Tests that readPermissions works correctly without {@link SystemConfig#ALLOW_APP_CONFIGS}
+ * permission flag for the tag: {@code allowed-partner-apex}.
+ */
+ @Test
+ public void readPermissions_notAllowAppConfigs_doesNotParsePartnerApexAllowList()
+ throws IOException {
+ final String contents =
+ "<config>\n"
+ + " <allowed-partner-apex package=\"com.android.apex1\" />\n"
+ + "</config>";
+ final File folder = createTempSubfolder("folder");
+ createTempFile(folder, "partner-apex-allowlist.xml", contents);
+
+ mSysConfig.readPermissions(folder, /* Grant all but ALLOW_APP_CONFIGS flag */ ~0x08);
+
+ assertThat(mSysConfig.getAllowedPartnerApexes()).isEmpty();
+ }
+
+ /**
* Creates folderName/fileName in the mTemporaryFolder and fills it with the contents.
*
* @param folderName subdirectory of mTemporaryFolder to put the file, creating if needed
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index a24691791938..4c157c0e0a73 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -1179,6 +1179,36 @@ public class AppStandbyControllerTests {
assertBucket(STANDBY_BUCKET_RESTRICTED);
}
+ /**
+ * Test that an app that "timed out" into the RESTRICTED bucket can be raised out by system
+ * interaction.
+ */
+ @Test
+ public void testSystemInteractionOverridesRestrictedTimeout() throws Exception {
+ reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
+ assertBucket(STANDBY_BUCKET_ACTIVE);
+
+ // Long enough that it could have timed out into RESTRICTED.
+ mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD * 4;
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_RESTRICTED);
+
+ // Report system interaction.
+ mInjector.mElapsedRealtime += 1000;
+ reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
+
+ // Ensure that it's raised out of RESTRICTED for the system interaction elevation duration.
+ assertBucket(STANDBY_BUCKET_ACTIVE);
+ mInjector.mElapsedRealtime += 1000;
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_ACTIVE);
+
+ // Elevation duration over. Should fall back down.
+ mInjector.mElapsedRealtime += 10 * MINUTE_MS;
+ mController.checkIdleStates(USER_ID);
+ assertBucket(STANDBY_BUCKET_RESTRICTED);
+ }
+
@Test
public void testRestrictedBucketDisabled() throws Exception {
mInjector.mIsRestrictedBucketEnabled = false;
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
index 058575817acf..0449e4450d06 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
@@ -56,6 +56,8 @@ final class FakeVibratorControllerProvider {
private int[] mSupportedEffects;
private int[] mSupportedBraking;
private int[] mSupportedPrimitives;
+ private int mCompositionSizeMax;
+ private int mPwleSizeMax;
private float mMinFrequency = Float.NaN;
private float mResonantFrequency = Float.NaN;
private float mFrequencyResolution = Float.NaN;
@@ -151,12 +153,22 @@ final class FakeVibratorControllerProvider {
}
@Override
- public VibratorInfo getInfo(float suggestedFrequencyRange) {
- VibratorInfo.FrequencyMapping frequencyMapping = new VibratorInfo.FrequencyMapping(
- mMinFrequency, mResonantFrequency, mFrequencyResolution,
- suggestedFrequencyRange, mMaxAmplitudes);
- return new VibratorInfo(vibratorId, mCapabilities, mSupportedEffects, mSupportedBraking,
- mSupportedPrimitives, null, mQFactor, frequencyMapping);
+ public boolean getInfo(float suggestedFrequencyRange, VibratorInfo.Builder infoBuilder) {
+ infoBuilder.setCapabilities(mCapabilities);
+ infoBuilder.setSupportedBraking(mSupportedBraking);
+ infoBuilder.setPwleSizeMax(mPwleSizeMax);
+ infoBuilder.setSupportedEffects(mSupportedEffects);
+ if (mSupportedPrimitives != null) {
+ for (int primitive : mSupportedPrimitives) {
+ infoBuilder.setSupportedPrimitive(primitive, EFFECT_DURATION);
+ }
+ }
+ infoBuilder.setCompositionSizeMax(mCompositionSizeMax);
+ infoBuilder.setQFactor(mQFactor);
+ infoBuilder.setFrequencyMapping(new VibratorInfo.FrequencyMapping(mMinFrequency,
+ mResonantFrequency, mFrequencyResolution, suggestedFrequencyRange,
+ mMaxAmplitudes));
+ return true;
}
private void applyLatency() {
@@ -236,6 +248,16 @@ final class FakeVibratorControllerProvider {
mSupportedPrimitives = primitives;
}
+ /** Set the max number of primitives allowed in a composition by the fake vibrator hardware. */
+ public void setCompositionSizeMax(int compositionSizeMax) {
+ mCompositionSizeMax = compositionSizeMax;
+ }
+
+ /** Set the max number of PWLEs allowed in a composition by the fake vibrator hardware. */
+ public void setPwleSizeMax(int pwleSizeMax) {
+ mPwleSizeMax = pwleSizeMax;
+ }
+
/** Set the resonant frequency of the fake vibrator hardware. */
public void setResonantFrequency(float frequencyHz) {
mResonantFrequency = frequencyHz;
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 855012459bd6..7d24a2f5845e 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -33,6 +33,7 @@ import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
import android.media.AudioManager;
import android.os.Handler;
import android.os.PowerManagerInternal;
@@ -69,6 +70,7 @@ import org.mockito.junit.MockitoRule;
public class VibrationSettingsTest {
private static final int UID = 1;
+ private static final int USER_OPERATION_TIMEOUT_MILLIS = 60_000; // 1 min
private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
.setBatterySaverEnabled(true).build();
@@ -408,6 +410,25 @@ public class VibrationSettingsTest {
}
@Test
+ public void getCurrentIntensity_updateTriggeredAfterUserSwitched() {
+ mFakeVibrator.setDefaultRingVibrationIntensity(Vibrator.VIBRATION_INTENSITY_OFF);
+ setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_HIGH);
+ assertEquals(Vibrator.VIBRATION_INTENSITY_HIGH,
+ mVibrationSettings.getCurrentIntensity(VibrationAttributes.USAGE_RINGTONE));
+
+ // Switching user is not working with FakeSettingsProvider.
+ // Testing the broadcast flow manually.
+ Settings.System.putIntForUser(mContextSpy.getContentResolver(),
+ Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW,
+ UserHandle.USER_CURRENT);
+ mVibrationSettings.mUserReceiver.onReceive(mContextSpy,
+ new Intent(Intent.ACTION_USER_SWITCHED));
+ assertEquals(Vibrator.VIBRATION_INTENSITY_LOW,
+ mVibrationSettings.getCurrentIntensity(VibrationAttributes.USAGE_RINGTONE));
+ }
+
+ @Test
public void getFallbackEffect_returnsEffectsFromSettings() {
assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_TICK));
assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_TEXTURE_TICK));
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 f02e2f081e3b..b8fdb552e453 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -356,7 +356,8 @@ public class VibrationThreadTest {
@Test
public void vibrate_singleVibratorComposed_runsVibration() throws Exception {
- mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
long vibrationId = 1;
VibrationEffect effect = VibrationEffect.startComposition()
@@ -374,7 +375,7 @@ public class VibrationThreadTest {
assertEquals(Arrays.asList(
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0),
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 0)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+ fakeVibrator.getEffectSegments());
}
@Test
@@ -395,6 +396,27 @@ public class VibrationThreadTest {
}
@Test
+ public void vibrate_singleVibratorLargeComposition_splitsVibratorComposeCalls() {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+ fakeVibrator.setCompositionSizeMax(2);
+
+ long vibrationId = 1;
+ VibrationEffect effect = VibrationEffect.startComposition()
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.8f)
+ .compose();
+ VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+ waitForCompletion(thread);
+
+ verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+ // Vibrator compose called twice.
+ verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+ assertEquals(3, fakeVibrator.getEffectSegments().size());
+ }
+
+ @Test
public void vibrate_singleVibratorComposedEffects_runsDifferentVibrations() throws Exception {
mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
@@ -432,12 +454,13 @@ public class VibrationThreadTest {
@Test
public void vibrate_singleVibratorPwle_runsComposePwle() throws Exception {
- mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
- mVibratorProviders.get(VIBRATOR_ID).setSupportedBraking(Braking.CLAB);
- mVibratorProviders.get(VIBRATOR_ID).setMinFrequency(100);
- mVibratorProviders.get(VIBRATOR_ID).setResonantFrequency(150);
- mVibratorProviders.get(VIBRATOR_ID).setFrequencyResolution(50);
- mVibratorProviders.get(VIBRATOR_ID).setMaxAmplitudes(
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ fakeVibrator.setSupportedBraking(Braking.CLAB);
+ fakeVibrator.setMinFrequency(100);
+ fakeVibrator.setResonantFrequency(150);
+ fakeVibrator.setFrequencyResolution(50);
+ fakeVibrator.setMaxAmplitudes(
0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
long vibrationId = 1;
@@ -462,8 +485,34 @@ public class VibrationThreadTest {
expectedRamp(/* amplitude= */ 0.6f, /* frequency= */ 200, /* duration= */ 30),
expectedRamp(/* StartAmplitude= */ 0.6f, /* endAmplitude= */ 0.5f,
/* startFrequency= */ 200, /* endFrequency= */ 100, /* duration= */ 40)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
- assertEquals(Arrays.asList(Braking.CLAB), mVibratorProviders.get(VIBRATOR_ID).getBraking());
+ fakeVibrator.getEffectSegments());
+ assertEquals(Arrays.asList(Braking.CLAB), fakeVibrator.getBraking());
+ }
+
+ @Test
+ public void vibrate_singleVibratorLargePwle_splitsVibratorComposeCalls() {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ fakeVibrator.setMinFrequency(100);
+ fakeVibrator.setResonantFrequency(150);
+ fakeVibrator.setFrequencyResolution(50);
+ fakeVibrator.setMaxAmplitudes(1, 1, 1);
+ fakeVibrator.setPwleSizeMax(2);
+
+ long vibrationId = 1;
+ VibrationEffect effect = VibrationEffect.startWaveform()
+ .addStep(1, 10)
+ .addRamp(0, 20)
+ .addStep(0.8f, 1, 30)
+ .addRamp(0.6f, -1, 40)
+ .build();
+ VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+ waitForCompletion(thread);
+
+ verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+ // Vibrator compose called twice.
+ verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+ assertEquals(4, fakeVibrator.getEffectSegments().size());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
index 9e98e7d0410c..a732bd18676a 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java
@@ -298,11 +298,13 @@ public class VibratorControllerTest {
private void mockVibratorCapabilities(int capabilities) {
VibratorInfo.FrequencyMapping frequencyMapping = new VibratorInfo.FrequencyMapping(
Float.NaN, Float.NaN, Float.NaN, Float.NaN, null);
- when(mNativeWrapperMock.getInfo(anyFloat())).thenReturn(
- new VibratorInfo.Builder(VIBRATOR_ID)
- .setCapabilities(capabilities)
- .setFrequencyMapping(frequencyMapping)
- .build());
+ when(mNativeWrapperMock.getInfo(anyFloat(), any(VibratorInfo.Builder.class)))
+ .then(invocation -> {
+ ((VibratorInfo.Builder) invocation.getArgument(1))
+ .setCapabilities(capabilities)
+ .setFrequencyMapping(frequencyMapping);
+ return true;
+ });
}
private PrebakedSegment createPrebaked(int effectId, int effectStrength) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 3862d754b8f5..71c05b5c46f7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -48,6 +48,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationChannel;
@@ -111,6 +112,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
NotificationUsageStats mUsageStats;
@Mock
IAccessibilityManager mAccessibilityService;
+ @Mock
+ KeyguardManager mKeyguardManager;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
1 << 30);
@@ -153,6 +156,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
when(mVibrator.hasFrequencyControl()).thenReturn(false);
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
long serviceReturnValue = IntPair.of(
AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
@@ -174,6 +178,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
mService.setScreenOn(false);
mService.setUsageStats(mUsageStats);
mService.setAccessibilityManager(accessibilityManager);
+ mService.setKeyguardManager(mKeyguardManager);
mService.mScreenOn = false;
mService.mInCallStateOffHook = false;
mService.mNotificationPulseEnabled = true;
@@ -496,6 +501,94 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
}
@Test
+ public void testLockedPrivateA11yRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+ }
+
+ @Test
+ public void testLockedOverridePrivateA11yRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
+ r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+ }
+
+ @Test
+ public void testLockedPublicA11yNoRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification(), event.getParcelableData());
+ }
+
+ @Test
+ public void testUnlockedPrivateA11yNoRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification(), event.getParcelableData());
+ }
+
+ @Test
public void testBeepInsistently() throws Exception {
NotificationRecord r = getInsistentBeepyNotification();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 9267285b446b..9cf29d4dcc50 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -53,6 +54,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.refEq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -1012,12 +1014,26 @@ public class RootWindowContainerTests extends WindowTestsBase {
// Create another activity on top and the user id is 1
final ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(task)
.setUid(UserHandle.PER_USER_RANGE + 1).build();
+ doReturn(true).when(topActivity).okToShowLocked();
+ topActivity.intent.setAction(Intent.ACTION_MAIN);
// Make sure the listeners will be notified for putting the task to locked state
TaskChangeNotificationController controller = mAtm.getTaskChangeNotificationController();
spyOn(controller);
mWm.mRoot.lockAllProfileTasks(0);
verify(controller).notifyTaskProfileLocked(eq(taskId), eq(0));
+
+ // Create the work lock activity on top of the task
+ final ActivityRecord workLockActivity = new ActivityBuilder(mAtm).setTask(task)
+ .setUid(UserHandle.PER_USER_RANGE + 1).build();
+ doReturn(true).when(workLockActivity).okToShowLocked();
+ workLockActivity.intent.setAction(ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
+ doReturn(workLockActivity.mActivityComponent).when(mAtm).getSysUiServiceComponentLocked();
+
+ // Make sure the listener won't be notified again.
+ clearInvocations(controller);
+ mWm.mRoot.lockAllProfileTasks(0);
+ verify(controller, never()).notifyTaskProfileLocked(anyInt(), anyInt());
}
/**
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 4e261deb67f6..4872ec511ccc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -401,6 +401,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertFitted();
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
+ final Rect currentAppBounds = mActivity.getWindowConfiguration().getAppBounds();
final Rect originalBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
final int notchHeight = 100;
@@ -428,8 +429,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Because the display cannot rotate, the portrait activity will fit the short side of
// display with keeping portrait bounds [200, 0 - 700, 1000] in center.
assertEquals(newDisplayBounds.height(), currentBounds.height());
- assertEquals(currentBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
- currentBounds.width());
+ assertEquals(currentAppBounds.height() * newDisplayBounds.height()
+ / newDisplayBounds.width(), currentAppBounds.width());
assertFitted();
// The appBounds should be [200, 100 - 700, 1000].
final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index d93ebb383b3b..0ebff1d253ef 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -60,6 +60,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
@@ -121,8 +122,8 @@ public class TaskTests extends WindowTestsBase {
@Test
public void testRemoveContainer() {
- final Task taskController1 = createTask(mDisplayContent);
- final Task task = createTaskInRootTask(taskController1, 0 /* userId */);
+ final Task rootTask = createTask(mDisplayContent);
+ final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
task.removeIfPossible();
@@ -130,12 +131,14 @@ public class TaskTests extends WindowTestsBase {
assertNull(task.getParent());
assertEquals(0, task.getChildCount());
assertNull(activity.getParent());
+ verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(task);
+ verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(rootTask);
}
@Test
public void testRemoveContainer_deferRemoval() {
- final Task taskController1 = createTask(mDisplayContent);
- final Task task = createTaskInRootTask(taskController1, 0 /* userId */);
+ final Task rootTask = createTask(mDisplayContent);
+ final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
doReturn(true).when(task).shouldDeferRemoval();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 17303a4aa7e1..beaca68b9a37 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -29,11 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger;
-import android.media.AudioAttributes;
import android.media.AudioFormat;
-import android.media.AudioManager;
-import android.media.AudioRecord;
-import android.media.MediaRecorder;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -66,12 +62,16 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.Instant;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
/**
* A class that provides the communication with the HotwordDetectionService.
@@ -81,33 +81,38 @@ final class HotwordDetectionConnection {
// TODO (b/177502877): Set the Debug flag to false before shipping.
private static final boolean DEBUG = true;
- // Number of bytes per sample of audio (which is a short).
- private static final int BYTES_PER_SAMPLE = 2;
// TODO: These constants need to be refined.
private static final long VALIDATION_TIMEOUT_MILLIS = 3000;
- private static final long VOICE_INTERACTION_TIMEOUT_TO_OPEN_MIC_MILLIS = 2000;
- private static final int MAX_STREAMING_SECONDS = 10;
- private static final int MICROPHONE_BUFFER_LENGTH_SECONDS = 8;
- private static final int HOTWORD_AUDIO_LENGTH_SECONDS = 3;
private static final long MAX_UPDATE_TIMEOUT_MILLIS = 6000;
+ private static final Duration MAX_UPDATE_TIMEOUT_DURATION =
+ Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS);
private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
// TODO: This may need to be a Handler(looper)
private final ScheduledExecutorService mScheduledExecutorService =
Executors.newSingleThreadScheduledExecutor();
- private final AtomicBoolean mUpdateStateFinish = new AtomicBoolean(false);
+ private final AtomicBoolean mUpdateStateAfterStartFinished = new AtomicBoolean(false);
+ private final @NonNull ServiceConnectionFactory mServiceConnectionFactory;
final Object mLock;
final int mVoiceInteractionServiceUid;
final ComponentName mDetectionComponentName;
final int mUser;
final Context mContext;
- final @NonNull ServiceConnector<IHotwordDetectionService> mRemoteHotwordDetectionService;
- boolean mBound;
volatile HotwordDetectionServiceIdentity mIdentity;
+ private IHotwordRecognitionStatusCallback mCallback;
+ private IMicrophoneHotwordDetectionVoiceInteractionCallback mSoftwareCallback;
+ private Instant mLastRestartInstant;
+
+ private ScheduledFuture<?> mCancellationTaskFuture;
@GuardedBy("mLock")
private ParcelFileDescriptor mCurrentAudioSink;
+ @GuardedBy("mLock")
+ private boolean mValidatingDspTrigger = false;
+ @GuardedBy("mLock")
+ private boolean mPerformingSoftwareHotwordDetection;
+ private @NonNull ServiceConnection mRemoteHotwordDetectionService;
HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid,
ComponentName serviceName, int userId, boolean bindInstantServiceAllowed,
@@ -121,50 +126,36 @@ final class HotwordDetectionConnection {
final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE);
intent.setComponent(mDetectionComponentName);
- mRemoteHotwordDetectionService = new ServiceConnector.Impl<IHotwordDetectionService>(
- mContext, intent, bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, mUser,
- IHotwordDetectionService.Stub::asInterface) {
- @Override // from ServiceConnector.Impl
- protected void onServiceConnectionStatusChanged(IHotwordDetectionService service,
- boolean connected) {
- if (DEBUG) {
- Slog.d(TAG, "onServiceConnectionStatusChanged connected = " + connected);
- }
- synchronized (mLock) {
- mBound = connected;
- }
- }
+ mServiceConnectionFactory = new ServiceConnectionFactory(intent, bindInstantServiceAllowed);
- @Override
- protected long getAutoDisconnectTimeoutMs() {
- return -1;
- }
+ mRemoteHotwordDetectionService = mServiceConnectionFactory.create();
- @Override
- public void binderDied() {
- super.binderDied();
- Slog.w(TAG, "binderDied");
- try {
- callback.onError(-1);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to report onError status: " + e);
- }
- }
- };
- mRemoteHotwordDetectionService.connect();
if (callback == null) {
updateStateLocked(options, sharedMemory);
return;
}
- updateAudioFlinger();
- updateContentCaptureManager();
- updateStateWithCallbackLocked(options, sharedMemory, callback);
+ mCallback = callback;
+
+ mLastRestartInstant = Instant.now();
+ updateStateAfterProcessStart(options, sharedMemory);
+
+ // TODO(volnov): we need to be smarter here, e.g. schedule it a bit more often, but wait
+ // until the current session is closed.
+ mCancellationTaskFuture = mScheduledExecutorService.scheduleAtFixedRate(() -> {
+ if (DEBUG) {
+ Slog.i(TAG, "Time to restart the process, TTL has passed");
+ }
+
+ synchronized (mLock) {
+ restartProcessLocked();
+ }
+ }, 30, 30, TimeUnit.MINUTES);
}
- private void updateStateWithCallbackLocked(PersistableBundle options,
- SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ private void updateStateAfterProcessStart(
+ PersistableBundle options, SharedMemory sharedMemory) {
if (DEBUG) {
- Slog.d(TAG, "updateStateWithCallbackLocked");
+ Slog.d(TAG, "updateStateAfterProcessStart");
}
mRemoteHotwordDetectionService.postAsync(service -> {
AndroidFuture<Void> future = new AndroidFuture<>();
@@ -183,21 +174,21 @@ final class HotwordDetectionConnection {
mIdentity =
new HotwordDetectionServiceIdentity(uid, mVoiceInteractionServiceUid);
future.complete(null);
+ if (mUpdateStateAfterStartFinished.getAndSet(true)) {
+ Slog.w(TAG, "call callback after timeout");
+ return;
+ }
+ int status = bundle != null ? bundle.getInt(
+ KEY_INITIALIZATION_STATUS,
+ INITIALIZATION_STATUS_UNKNOWN)
+ : INITIALIZATION_STATUS_UNKNOWN;
+ // Add the protection to avoid unexpected status
+ if (status > HotwordDetectionService.getMaxCustomInitializationStatus()
+ && status != INITIALIZATION_STATUS_UNKNOWN) {
+ status = INITIALIZATION_STATUS_UNKNOWN;
+ }
try {
- if (mUpdateStateFinish.getAndSet(true)) {
- Slog.w(TAG, "call callback after timeout");
- return;
- }
- int status = bundle != null ? bundle.getInt(
- KEY_INITIALIZATION_STATUS,
- INITIALIZATION_STATUS_UNKNOWN)
- : INITIALIZATION_STATUS_UNKNOWN;
- // Add the protection to avoid unexpected status
- if (status > HotwordDetectionService.getMaxCustomInitializationStatus()
- && status != INITIALIZATION_STATUS_UNKNOWN) {
- status = INITIALIZATION_STATUS_UNKNOWN;
- }
- callback.onStatusReported(status);
+ mCallback.onStatusReported(status);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to report initialization status: " + e);
}
@@ -214,13 +205,13 @@ final class HotwordDetectionConnection {
.whenComplete((res, err) -> {
if (err instanceof TimeoutException) {
Slog.w(TAG, "updateState timed out");
+ if (mUpdateStateAfterStartFinished.getAndSet(true)) {
+ return;
+ }
try {
- if (mUpdateStateFinish.getAndSet(true)) {
- return;
- }
- callback.onStatusReported(INITIALIZATION_STATUS_UNKNOWN);
+ mCallback.onStatusReported(INITIALIZATION_STATUS_UNKNOWN);
} catch (RemoteException e) {
- Slog.w(TAG, "Failed to report initialization status: " + e);
+ Slog.w(TAG, "Failed to report initialization status UNKNOWN", e);
}
} else if (err != null) {
Slog.w(TAG, "Failed to update state: " + err);
@@ -230,27 +221,9 @@ final class HotwordDetectionConnection {
});
}
- private void updateAudioFlinger() {
- // TODO: Consider using a proxy that limits the exposed API surface.
- IBinder audioFlinger = ServiceManager.getService("media.audio_flinger");
- if (audioFlinger == null) {
- throw new IllegalStateException("Service media.audio_flinger wasn't found.");
- }
- mRemoteHotwordDetectionService.post(service -> service.updateAudioFlinger(audioFlinger));
- }
-
- private void updateContentCaptureManager() {
- IBinder b = ServiceManager
- .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
- IContentCaptureManager binderService = IContentCaptureManager.Stub.asInterface(b);
- mRemoteHotwordDetectionService.post(
- service -> service.updateContentCaptureManager(binderService,
- new ContentCaptureOptions(null)));
- }
-
private boolean isBound() {
synchronized (mLock) {
- return mBound;
+ return mRemoteHotwordDetectionService.isBound();
}
}
@@ -258,18 +231,25 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "cancelLocked");
}
- if (mBound) {
+ if (mRemoteHotwordDetectionService.isBound()) {
mRemoteHotwordDetectionService.unbind();
- mBound = false;
LocalServices.getService(PermissionManagerServiceInternal.class)
.setHotwordDetectionServiceProvider(null);
mIdentity = null;
}
+ mCancellationTaskFuture.cancel(/* may interrupt */ true);
}
void updateStateLocked(PersistableBundle options, SharedMemory sharedMemory) {
- mRemoteHotwordDetectionService.run(
- service -> service.updateState(options, sharedMemory, null /* callback */));
+ // Prevent doing the init late, so restart is handled equally to a clean process start.
+ // TODO(b/191742511): this logic needs a test
+ if (!mUpdateStateAfterStartFinished.get()
+ && Instant.now().minus(MAX_UPDATE_TIMEOUT_DURATION).isBefore(mLastRestartInstant)) {
+ updateStateAfterProcessStart(options, sharedMemory);
+ } else {
+ mRemoteHotwordDetectionService.run(
+ service -> service.updateState(options, sharedMemory, null /* callback */));
+ }
}
void startListeningFromMic(
@@ -278,7 +258,20 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "startListeningFromMic");
}
+ mSoftwareCallback = callback;
+
+ synchronized (mLock) {
+ if (mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Hotword validation is already in progress, ignoring.");
+ return;
+ }
+ mPerformingSoftwareHotwordDetection = true;
+
+ startListeningFromMicLocked();
+ }
+ }
+ private void startListeningFromMicLocked() {
// TODO: consider making this a non-anonymous class.
IDspHotwordDetectionCallback internalCallback = new IDspHotwordDetectionCallback.Stub() {
@Override
@@ -286,15 +279,22 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "onDetected");
}
- callback.onDetected(result, null, null);
+ synchronized (mLock) {
+ if (mPerformingSoftwareHotwordDetection) {
+ mSoftwareCallback.onDetected(result, null, null);
+ mPerformingSoftwareHotwordDetection = false;
+ } else {
+ Slog.i(TAG, "Hotword detection has already completed");
+ }
+ }
}
@Override
public void onRejected(HotwordRejectedResult result) throws RemoteException {
if (DEBUG) {
- Slog.d(TAG, "onRejected");
+ Slog.wtf(TAG, "onRejected");
}
- // onRejected isn't allowed here
+ // onRejected isn't allowed here, and we are not expecting it.
}
};
@@ -315,6 +315,7 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "startListeningFromExternalSource");
}
+
handleExternalSourceHotwordDetection(
audioStream,
audioFormat,
@@ -326,16 +327,25 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "stopListening");
}
+ synchronized (mLock) {
+ stopListeningLocked();
+ }
+ }
- mRemoteHotwordDetectionService.run(service -> service.stopDetection());
+ private void stopListeningLocked() {
+ if (!mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Hotword detection is not running");
+ return;
+ }
+ mPerformingSoftwareHotwordDetection = false;
- synchronized (mLock) {
- if (mCurrentAudioSink != null) {
- Slog.i(TAG, "Closing audio stream to hotword detector: stopping requested");
- bestEffortClose(mCurrentAudioSink);
- }
- mCurrentAudioSink = null;
+ mRemoteHotwordDetectionService.run(IHotwordDetectionService::stopDetection);
+
+ if (mCurrentAudioSink != null) {
+ Slog.i(TAG, "Closing audio stream to hotword detector: stopping requested");
+ bestEffortClose(mCurrentAudioSink);
}
+ mCurrentAudioSink = null;
}
void triggerHardwareRecognitionEventForTestLocked(
@@ -358,7 +368,14 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "onDetected");
}
- externalCallback.onKeyphraseDetected(recognitionEvent, result);
+ synchronized (mLock) {
+ if (mValidatingDspTrigger) {
+ mValidatingDspTrigger = false;
+ externalCallback.onKeyphraseDetected(recognitionEvent, result);
+ } else {
+ Slog.i(TAG, "Ignored hotword detected since trigger has been handled");
+ }
+ }
}
@Override
@@ -366,16 +383,26 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "onRejected");
}
- externalCallback.onRejected(result);
+ synchronized (mLock) {
+ if (mValidatingDspTrigger) {
+ mValidatingDspTrigger = false;
+ externalCallback.onRejected(result);
+ } else {
+ Slog.i(TAG, "Ignored hotword rejected since trigger has been handled");
+ }
+ }
}
};
- mRemoteHotwordDetectionService.run(
- service -> service.detectFromDspSource(
- recognitionEvent,
- recognitionEvent.getCaptureFormat(),
- VALIDATION_TIMEOUT_MILLIS,
- internalCallback));
+ synchronized (mLock) {
+ mValidatingDspTrigger = true;
+ mRemoteHotwordDetectionService.run(
+ service -> service.detectFromDspSource(
+ recognitionEvent,
+ recognitionEvent.getCaptureFormat(),
+ VALIDATION_TIMEOUT_MILLIS,
+ internalCallback));
+ }
}
private void detectFromDspSource(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
@@ -391,7 +418,14 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "onDetected");
}
- externalCallback.onKeyphraseDetected(recognitionEvent, result);
+ synchronized (mLock) {
+ if (!mValidatingDspTrigger) {
+ Slog.i(TAG, "Ignoring #onDetected due to a process restart");
+ return;
+ }
+ mValidatingDspTrigger = false;
+ externalCallback.onKeyphraseDetected(recognitionEvent, result);
+ }
}
@Override
@@ -399,16 +433,88 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "onRejected");
}
- externalCallback.onRejected(result);
+ synchronized (mLock) {
+ if (!mValidatingDspTrigger) {
+ Slog.i(TAG, "Ignoring #onRejected due to a process restart");
+ return;
+ }
+ mValidatingDspTrigger = false;
+ externalCallback.onRejected(result);
+ }
}
};
- mRemoteHotwordDetectionService.run(
- service -> service.detectFromDspSource(
- recognitionEvent,
- recognitionEvent.getCaptureFormat(),
- VALIDATION_TIMEOUT_MILLIS,
- internalCallback));
+ synchronized (mLock) {
+ mValidatingDspTrigger = true;
+ mRemoteHotwordDetectionService.run(
+ service -> service.detectFromDspSource(
+ recognitionEvent,
+ recognitionEvent.getCaptureFormat(),
+ VALIDATION_TIMEOUT_MILLIS,
+ internalCallback));
+ }
+ }
+
+ void forceRestart() {
+ if (DEBUG) {
+ Slog.i(TAG, "Requested to restart the service internally. Performing the restart");
+ }
+ synchronized (mLock) {
+ restartProcessLocked();
+ }
+ }
+
+ private void restartProcessLocked() {
+ if (DEBUG) {
+ Slog.i(TAG, "Restarting hotword detection process");
+ }
+
+ ServiceConnection oldConnection = mRemoteHotwordDetectionService;
+
+ // TODO(volnov): this can be done after connect() has been successful.
+ if (mValidatingDspTrigger) {
+ // We're restarting the process while it's processing a DSP trigger, so report a
+ // rejection. This also allows the Interactor to startReco again
+ try {
+ mCallback.onRejected(new HotwordRejectedResult.Builder().build());
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call #rejected");
+ }
+ mValidatingDspTrigger = false;
+ }
+
+ mUpdateStateAfterStartFinished.set(false);
+ mLastRestartInstant = Instant.now();
+
+ // Recreate connection to reset the cache.
+ mRemoteHotwordDetectionService = mServiceConnectionFactory.create();
+
+ if (DEBUG) {
+ Slog.i(TAG, "Started the new process, issuing #onProcessRestarted");
+ }
+ try {
+ mCallback.onProcessRestarted();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to communicate #onProcessRestarted", e);
+ }
+
+ // Restart listening from microphone if the hotword process has been restarted.
+ if (mPerformingSoftwareHotwordDetection) {
+ Slog.i(TAG, "Process restarted: calling startRecognition() again");
+ startListeningFromMicLocked();
+ }
+
+ if (mCurrentAudioSink != null) {
+ Slog.i(TAG, "Closing external audio stream to hotword detector: process restarted");
+ bestEffortClose(mCurrentAudioSink);
+ mCurrentAudioSink = null;
+ }
+
+ if (DEBUG) {
+ Slog.i(TAG, "#onProcessRestarted called, unbinding from the old process");
+ }
+ oldConnection.ignoreConnectionStatusEvents();
+ oldConnection.unbind();
}
static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub {
@@ -462,139 +568,13 @@ final class HotwordDetectionConnection {
}
}
- // TODO: figure out if we need to let the client configure some of the parameters.
- private static AudioRecord createAudioRecord(
- @NonNull SoundTrigger.KeyphraseRecognitionEvent recognitionEvent) {
- int sampleRate = recognitionEvent.getCaptureFormat().getSampleRate();
- return new AudioRecord(
- new AudioAttributes.Builder()
- .setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD).build(),
- recognitionEvent.getCaptureFormat(),
- getBufferSizeInBytes(
- sampleRate,
- MAX_STREAMING_SECONDS,
- recognitionEvent.getCaptureFormat().getChannelCount()),
- recognitionEvent.getCaptureSession());
- }
-
- @Nullable
- private AudioRecord createMicAudioRecord(AudioFormat audioFormat) {
- if (DEBUG) {
- Slog.i(TAG, "#createAudioRecord");
- }
- try {
- AudioRecord audioRecord = new AudioRecord(
- new AudioAttributes.Builder()
- .setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD).build(),
- audioFormat,
- getBufferSizeInBytes(
- audioFormat.getSampleRate(),
- MICROPHONE_BUFFER_LENGTH_SECONDS,
- audioFormat.getChannelCount()),
- AudioManager.AUDIO_SESSION_ID_GENERATE);
-
- if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
- Slog.w(TAG, "Failed to initialize AudioRecord");
- audioRecord.release();
- return null;
- }
-
- return audioRecord;
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Failed to create AudioRecord", e);
- return null;
- }
- }
-
- @Nullable
- private AudioRecord createFakeAudioRecord() {
- if (DEBUG) {
- Slog.i(TAG, "#createFakeAudioRecord");
- }
- try {
- AudioRecord audioRecord = new AudioRecord.Builder()
- .setAudioFormat(new AudioFormat.Builder()
- .setSampleRate(32000)
- .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
- .setChannelMask(AudioFormat.CHANNEL_IN_MONO).build())
- .setAudioAttributes(new AudioAttributes.Builder()
- .setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD).build())
- .setBufferSizeInBytes(
- AudioRecord.getMinBufferSize(32000,
- AudioFormat.CHANNEL_IN_MONO,
- AudioFormat.ENCODING_PCM_16BIT) * 2)
- .build();
-
- if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
- Slog.w(TAG, "Failed to initialize AudioRecord");
- audioRecord.release();
- return null;
- }
- return audioRecord;
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Failed to create AudioRecord", e);
- }
- return null;
- }
-
- /**
- * Returns the number of bytes required to store {@code bufferLengthSeconds} of audio sampled at
- * {@code sampleRate} Hz, using the format returned by DSP audio capture.
- */
- private static int getBufferSizeInBytes(
- int sampleRate, int bufferLengthSeconds, int intChannelCount) {
- return BYTES_PER_SAMPLE * sampleRate * bufferLengthSeconds * intChannelCount;
- }
-
- private static Pair<ParcelFileDescriptor, ParcelFileDescriptor> createPipe() {
- ParcelFileDescriptor[] fileDescriptors;
- try {
- fileDescriptors = ParcelFileDescriptor.createPipe();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to create audio stream pipe", e);
- return null;
- }
-
- return Pair.create(fileDescriptors[0], fileDescriptors[1]);
- }
-
public void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("mBound="); pw.println(mBound);
- }
-
- private interface AudioReader extends Closeable {
- int read(byte[] dest, int offset, int length) throws IOException;
-
- static AudioReader createFromInputStream(InputStream is) {
- return new AudioReader() {
- @Override
- public int read(byte[] dest, int offset, int length) throws IOException {
- return is.read(dest, offset, length);
- }
-
- @Override
- public void close() throws IOException {
- is.close();
- }
- };
- }
-
- static AudioReader createFromAudioRecord(AudioRecord record) {
- record.startRecording();
-
- return new AudioReader() {
- @Override
- public int read(byte[] dest, int offset, int length) throws IOException {
- return record.read(dest, offset, length);
- }
-
- @Override
- public void close() throws IOException {
- record.stop();
- record.release();
- }
- };
- }
+ pw.print(prefix);
+ pw.print("mBound=" + mRemoteHotwordDetectionService.isBound());
+ pw.print(", mValidatingDspTrigger=" + mValidatingDspTrigger);
+ pw.print(", mPerformingSoftwareHotwordDetection=" + mPerformingSoftwareHotwordDetection);
+ pw.print(", mRestartCount=" + mServiceConnectionFactory.mRestartCount);
+ pw.println(", mLastRestartInstant=" + mLastRestartInstant);
}
private void handleExternalSourceHotwordDetection(
@@ -605,8 +585,7 @@ final class HotwordDetectionConnection {
if (DEBUG) {
Slog.d(TAG, "#handleExternalSourceHotwordDetection");
}
- AudioReader audioSource = AudioReader.createFromInputStream(
- new ParcelFileDescriptor.AutoCloseInputStream(audioStream));
+ InputStream audioSource = new ParcelFileDescriptor.AutoCloseInputStream(audioStream);
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
if (clientPipe == null) {
@@ -621,7 +600,7 @@ final class HotwordDetectionConnection {
}
mAudioCopyExecutor.execute(() -> {
- try (AudioReader source = audioSource;
+ try (InputStream source = audioSource;
OutputStream fos =
new ParcelFileDescriptor.AutoCloseOutputStream(serviceAudioSink)) {
@@ -681,6 +660,150 @@ final class HotwordDetectionConnection {
}));
}
+ private class ServiceConnectionFactory {
+ private final Intent mIntent;
+ private final int mBindingFlags;
+
+ private int mRestartCount = 0;
+
+ ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed) {
+ mIntent = intent;
+ mBindingFlags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0;
+ }
+
+ ServiceConnection create() {
+ ServiceConnection connection =
+ new ServiceConnection(mContext, mIntent, mBindingFlags, mUser,
+ IHotwordDetectionService.Stub::asInterface, ++mRestartCount);
+ connection.connect();
+
+ updateAudioFlinger(connection);
+ updateContentCaptureManager(connection);
+ return connection;
+ }
+ }
+
+ private class ServiceConnection extends ServiceConnector.Impl<IHotwordDetectionService> {
+ private final Object mLock = new Object();
+
+ private final Intent mIntent;
+ private final int mBindingFlags;
+ private final int mInstanceNumber;
+
+ private boolean mRespectServiceConnectionStatusChanged = true;
+ private boolean mIsBound = false;
+
+ ServiceConnection(@NonNull Context context,
+ @NonNull Intent intent, int bindingFlags, int userId,
+ @Nullable Function<IBinder, IHotwordDetectionService> binderAsInterface,
+ int instanceNumber) {
+ super(context, intent, bindingFlags, userId, binderAsInterface);
+ this.mIntent = intent;
+ this.mBindingFlags = bindingFlags;
+ this.mInstanceNumber = instanceNumber;
+ }
+
+ @Override // from ServiceConnector.Impl
+ protected void onServiceConnectionStatusChanged(IHotwordDetectionService service,
+ boolean connected) {
+ if (DEBUG) {
+ Slog.d(TAG, "onServiceConnectionStatusChanged connected = " + connected);
+ }
+ synchronized (mLock) {
+ if (!mRespectServiceConnectionStatusChanged) {
+ if (DEBUG) {
+ Slog.d(TAG, "Ignored onServiceConnectionStatusChanged event");
+ }
+ return;
+ }
+ mIsBound = connected;
+ }
+ }
+
+ @Override
+ protected long getAutoDisconnectTimeoutMs() {
+ return -1;
+ }
+
+ @Override
+ public void binderDied() {
+ super.binderDied();
+ synchronized (mLock) {
+ if (!mRespectServiceConnectionStatusChanged) {
+ if (DEBUG) {
+ Slog.d(TAG, "Ignored #binderDied event");
+ }
+ return;
+ }
+
+ Slog.w(TAG, "binderDied");
+ try {
+ mCallback.onError(-1);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to report onError status: " + e);
+ }
+ }
+ }
+
+ @Override
+ protected boolean bindService(
+ @NonNull android.content.ServiceConnection serviceConnection) {
+ try {
+ return mContext.bindIsolatedService(
+ mIntent,
+ Context.BIND_AUTO_CREATE | mBindingFlags,
+ "hotword_detector_" + mInstanceNumber,
+ mExecutor,
+ serviceConnection);
+ } catch (IllegalArgumentException e) {
+ Slog.wtf(TAG, "Can't bind to the hotword detection service!", e);
+ return false;
+ }
+ }
+
+ boolean isBound() {
+ synchronized (mLock) {
+ return mIsBound;
+ }
+ }
+
+ void ignoreConnectionStatusEvents() {
+ synchronized (mLock) {
+ mRespectServiceConnectionStatusChanged = false;
+ }
+ }
+ }
+
+ private static Pair<ParcelFileDescriptor, ParcelFileDescriptor> createPipe() {
+ ParcelFileDescriptor[] fileDescriptors;
+ try {
+ fileDescriptors = ParcelFileDescriptor.createPipe();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to create audio stream pipe", e);
+ return null;
+ }
+
+ return Pair.create(fileDescriptors[0], fileDescriptors[1]);
+ }
+
+ private static void updateAudioFlinger(ServiceConnection connection) {
+ // TODO: Consider using a proxy that limits the exposed API surface.
+ IBinder audioFlinger = ServiceManager.getService("media.audio_flinger");
+ if (audioFlinger == null) {
+ throw new IllegalStateException("Service media.audio_flinger wasn't found.");
+ }
+ connection.post(service -> service.updateAudioFlinger(audioFlinger));
+ }
+
+ private static void updateContentCaptureManager(ServiceConnection connection) {
+ IBinder b = ServiceManager
+ .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+ IContentCaptureManager binderService = IContentCaptureManager.Stub.asInterface(b);
+ connection.post(
+ service -> service.updateContentCaptureManager(binderService,
+ new ContentCaptureOptions(null)));
+ }
+
private static void bestEffortClose(Closeable closeable) {
try {
closeable.close();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index bc812c2ae4a7..162acba8002d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -795,6 +795,10 @@ public class VoiceInteractionManagerService extends SystemService {
Settings.Secure.ASSISTANT, null, userHandle);
}
+ void forceRestartHotwordDetector() {
+ mImpl.forceRestartHotwordDetector();
+ }
+
@Override
public void showSession(Bundle args, int flags) {
synchronized (this) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index ca30bc51e046..89c5a720ee7e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -562,6 +562,14 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
&& (serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) == 0;
}
+ void forceRestartHotwordDetector() {
+ if (mHotwordDetectionConnection == null) {
+ Slog.w(TAG, "Failed to force-restart hotword detection: no hotword detection active");
+ return;
+ }
+ mHotwordDetectionConnection.forceRestart();
+ }
+
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!mValid) {
pw.print(" NOT VALID: ");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
index 2e3ca0157a3b..cdd8f7b91d9d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
@@ -54,6 +54,8 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
return requestHide(pw);
case "disable":
return requestDisable(pw);
+ case "restart-detection":
+ return requestRestartDetection(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -74,6 +76,8 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
pw.println("");
pw.println(" disable [true|false]");
pw.println(" Temporarily disable (when true) service");
+ pw.println(" restart-detection");
+ pw.println(" Force a restart of a hotword detection service");
pw.println("");
}
}
@@ -143,6 +147,16 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
return 0;
}
+ private int requestRestartDetection(PrintWriter pw) {
+ Slog.i(TAG, "requestRestartDetection()");
+ try {
+ mService.forceRestartHotwordDetector();
+ } catch (Exception e) {
+ return handleError(pw, "requestRestartDetection()", e);
+ }
+ return 0;
+ }
+
private static int handleError(PrintWriter pw, String message, Exception e) {
Slog.e(TAG, "error calling " + message, e);
pw.printf("Error calling %s: %s\n", message, e);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1953af4adee5..e000265f0a2c 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1018,6 +1018,16 @@ public class TelecomManager {
// this magic number is a bug ID
public static final long ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION = 157233955L;
+ /**
+ * Enable READ_PHONE_NUMBERS or READ_PRIVILEGED_PHONE_STATE protections on
+ * {@link TelecomManager#getPhoneAccount(PhoneAccountHandle)}.
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ // bug ID
+ public static final long ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION = 183407956L;
+
private static final String TAG = "TelecomManager";
@@ -1351,6 +1361,9 @@ public class TelecomManager {
* Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
* resources which can be used in a user interface.
*
+ * Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_NUMBERS} for applications targeting API
+ * level 31+.
* @param account The {@link PhoneAccountHandle}.
* @return The {@link PhoneAccount} object.
*/
@@ -1358,7 +1371,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getPhoneAccount(account);
+ return service.getPhoneAccount(account, mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getPhoneAccount", e);
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 18afde742abb..6f286d9f3006 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -79,7 +79,7 @@ interface ITelecomService {
/**
* @see TelecomManager#getPhoneAccount
*/
- PhoneAccount getPhoneAccount(in PhoneAccountHandle account);
+ PhoneAccount getPhoneAccount(in PhoneAccountHandle account, String callingPackage);
/**
* @see TelecomManager#getAllPhoneAccountsCount
diff --git a/tests/Internal/src/android/app/WallpaperColorsTest.java b/tests/Internal/src/android/app/WallpaperColorsTest.java
index 45d3dade82b6..9ffb236d3f59 100644
--- a/tests/Internal/src/android/app/WallpaperColorsTest.java
+++ b/tests/Internal/src/android/app/WallpaperColorsTest.java
@@ -20,6 +20,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.os.Parcel;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -106,4 +107,26 @@ public class WallpaperColorsTest {
// This would crash:
canvas.drawBitmap(image, 0, 0, new Paint());
}
+
+ /**
+ * Parcelled WallpaperColors object should equal the original.
+ */
+ @Test
+ public void testParcelUnparcel() {
+ Bitmap image = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
+ WallpaperColors colors = WallpaperColors.fromBitmap(image);
+ Parcel parcel = Parcel.obtain();
+ colors.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ WallpaperColors reconstructed = new WallpaperColors(parcel);
+ parcel.recycle();
+ Assert.assertEquals("WallpaperColors recreated from Parcel should equal original",
+ colors, reconstructed);
+ Assert.assertEquals("getAllColors() on WallpaperColors recreated from Parcel should"
+ + "return the same as the original",
+ colors.getAllColors(), reconstructed.getAllColors());
+ Assert.assertEquals("getMainColors() on WallpaperColors recreated from Parcel should"
+ + "return the same as the original",
+ colors.getMainColors(), reconstructed.getMainColors());
+ }
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index f681ee19ab12..5d2f9d748581 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -242,6 +242,27 @@ public class VcnTest {
verifyUpdateSubscriptionSnapshotNotifiesGatewayConnections(VCN_STATUS_CODE_SAFE_MODE);
}
+ @Test
+ public void testSubscriptionSnapshotUpdatesMobileDataState() {
+ final NetworkRequestListener requestListener = verifyAndGetRequestListener();
+ startVcnGatewayWithCapabilities(requestListener, TEST_CAPS[0]);
+
+ // Expect mobile data enabled from setUp()
+ assertTrue(mVcn.isMobileDataEnabled());
+
+ final TelephonySubscriptionSnapshot updatedSnapshot =
+ mock(TelephonySubscriptionSnapshot.class);
+ doReturn(TEST_SUB_IDS_IN_GROUP)
+ .when(updatedSnapshot)
+ .getAllSubIdsInGroup(eq(TEST_SUB_GROUP));
+ doReturn(false).when(mTelephonyManager).isDataEnabled();
+
+ mVcn.updateSubscriptionSnapshot(updatedSnapshot);
+ mTestLooper.dispatchAll();
+
+ assertFalse(mVcn.isMobileDataEnabled());
+ }
+
private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
for (final int[] caps : TEST_CAPS) {
startVcnGatewayWithCapabilities(requestListener, caps);