summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapi/gen_combined_removed_dex.sh2
-rw-r--r--cmds/bootanimation/BootAnimation.cpp2
-rw-r--r--cmds/idmap2/idmap2/Lookup.cpp2
-rw-r--r--cmds/incidentd/src/IncidentService.cpp2
-rw-r--r--core/api/current.txt5
-rw-r--r--core/api/system-current.txt9
-rw-r--r--core/api/test-current.txt6
-rw-r--r--core/java/android/app/ActivityThread.java14
-rw-r--r--core/java/android/app/Instrumentation.java77
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java28
-rw-r--r--core/java/android/app/admin/EnforcingAdmin.aidl19
-rw-r--r--core/java/android/app/admin/EnforcingAdmin.java28
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/java/android/content/Context.java15
-rw-r--r--core/java/android/content/Intent.java1
-rw-r--r--core/java/android/content/om/OWNERS3
-rw-r--r--core/java/android/content/pm/ArchivedActivityParcel.aidl25
-rw-r--r--core/java/android/content/pm/ArchivedPackageParcel.aidl4
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageInfo.java16
-rw-r--r--core/java/android/content/pm/PackageInstaller.java3
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java17
-rw-r--r--core/java/android/content/pm/RegisteredServicesCache.java7
-rw-r--r--core/java/android/content/pm/parsing/ApkLite.java96
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java31
-rw-r--r--core/java/android/content/pm/parsing/PackageLite.java76
-rw-r--r--core/java/android/content/res/OWNERS3
-rw-r--r--core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl3
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl3
-rw-r--r--core/java/android/hardware/usb/DisplayPortAltModeInfo.java38
-rw-r--r--core/java/android/inputmethodservice/SoftInputWindow.java3
-rw-r--r--core/java/android/nfc/NfcAntennaInfo.java4
-rw-r--r--core/java/android/os/BinderProxy.java2
-rw-r--r--core/java/android/os/ServiceManager.java2
-rw-r--r--core/java/android/security/FileIntegrityManager.java2
-rw-r--r--core/java/android/security/flags.aconfig7
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java8
-rw-r--r--core/java/android/util/FeatureFlagUtils.java18
-rw-r--r--core/java/android/view/HandwritingInitiator.java34
-rw-r--r--core/java/android/view/HapticScrollFeedbackProvider.java26
-rw-r--r--core/java/android/view/MotionEvent.java12
-rw-r--r--core/java/android/view/ScrollFeedbackProvider.java147
-rw-r--r--core/java/android/view/ViewConfiguration.java48
-rw-r--r--core/java/android/view/ViewGroup.java2
-rw-r--r--core/java/android/view/inputmethod/TEST_MAPPING3
-rw-r--r--core/java/android/widget/AbsListView.java6
-rw-r--r--core/java/android/widget/ScrollView.java6
-rw-r--r--core/java/android/widget/TextView.java3
-rw-r--r--core/java/android/widget/inline/TEST_MAPPING3
-rw-r--r--core/java/android/window/SnapshotDrawerUtils.java7
-rw-r--r--core/java/android/window/flags/large_screen_experiences_app_compat.aconfig8
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig8
-rw-r--r--core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java40
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java15
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java10
-rw-r--r--core/java/com/android/internal/app/ResolverAppPredictorCallback.java55
-rw-r--r--core/java/com/android/internal/policy/DecorView.java4
-rw-r--r--core/java/com/android/internal/policy/TransitionAnimation.java5
-rw-r--r--core/java/com/android/internal/usb/DumpUtils.java12
-rw-r--r--core/proto/android/content/package_item_info.proto1
-rw-r--r--core/proto/android/service/usb.proto6
-rw-r--r--core/res/AndroidManifest.xml13
-rw-r--r--core/res/res/values-am/strings.xml3
-rw-r--r--core/res/res/values-as/strings.xml3
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml2
-rw-r--r--core/res/res/values-be/strings.xml5
-rw-r--r--core/res/res/values-bn/strings.xml3
-rw-r--r--core/res/res/values-ca/strings.xml7
-rw-r--r--core/res/res/values-da/strings.xml7
-rw-r--r--core/res/res/values-de/strings.xml3
-rw-r--r--core/res/res/values-es-rUS/strings.xml4
-rw-r--r--core/res/res/values-es/strings.xml7
-rw-r--r--core/res/res/values-et/strings.xml2
-rw-r--r--core/res/res/values-eu/strings.xml3
-rw-r--r--core/res/res/values-fa/strings.xml3
-rw-r--r--core/res/res/values-fi/strings.xml3
-rw-r--r--core/res/res/values-fr-rCA/strings.xml10
-rw-r--r--core/res/res/values-fr/strings.xml5
-rw-r--r--core/res/res/values-gl/strings.xml3
-rw-r--r--core/res/res/values-gu/strings.xml3
-rw-r--r--core/res/res/values-hi/strings.xml7
-rw-r--r--core/res/res/values-hr/strings.xml2
-rw-r--r--core/res/res/values-hy/strings.xml3
-rw-r--r--core/res/res/values-in/strings.xml2
-rw-r--r--core/res/res/values-is/strings.xml3
-rw-r--r--core/res/res/values-it/strings.xml30
-rw-r--r--core/res/res/values-iw/strings.xml3
-rw-r--r--core/res/res/values-kk/strings.xml7
-rw-r--r--core/res/res/values-kn/strings.xml4
-rw-r--r--core/res/res/values-ko/strings.xml3
-rw-r--r--core/res/res/values-ky/strings.xml9
-rw-r--r--core/res/res/values-lo/strings.xml3
-rw-r--r--core/res/res/values-lv/strings.xml3
-rw-r--r--core/res/res/values-mn/strings.xml6
-rw-r--r--core/res/res/values-mr/strings.xml7
-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.xml9
-rw-r--r--core/res/res/values-ne/strings.xml3
-rw-r--r--core/res/res/values-nl/strings.xml10
-rw-r--r--core/res/res/values-or/strings.xml5
-rw-r--r--core/res/res/values-pa/strings.xml5
-rw-r--r--core/res/res/values-pl/strings.xml3
-rw-r--r--core/res/res/values-ro/strings.xml3
-rw-r--r--core/res/res/values-ru/strings.xml5
-rw-r--r--core/res/res/values-si/strings.xml3
-rw-r--r--core/res/res/values-sk/strings.xml5
-rw-r--r--core/res/res/values-sl/strings.xml2
-rw-r--r--core/res/res/values-sq/strings.xml27
-rw-r--r--core/res/res/values-sr/strings.xml2
-rw-r--r--core/res/res/values-sv/strings.xml3
-rw-r--r--core/res/res/values-ta/strings.xml3
-rw-r--r--core/res/res/values-te/strings.xml2
-rw-r--r--core/res/res/values-tr/strings.xml5
-rw-r--r--core/res/res/values-uk/strings.xml5
-rw-r--r--core/res/res/values-ur/strings.xml3
-rw-r--r--core/res/res/values-vi/strings.xml3
-rw-r--r--core/res/res/values-watch/config.xml5
-rw-r--r--core/res/res/values/config_telephony.xml25
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java17
-rw-r--r--core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java10
-rw-r--r--core/tests/coretests/src/android/provider/DeviceConfigTest.java1
-rw-r--r--core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java395
-rw-r--r--core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java21
-rw-r--r--core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java19
-rw-r--r--core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java45
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ResolverAppPredictorCallbackTest.java108
-rw-r--r--data/etc/privapp-permissions-platform.xml1
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java7
-rw-r--r--libs/WindowManager/Shell/Android.bp1
-rw-r--r--libs/WindowManager/Shell/aconfig/Android.bp12
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig8
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rXC/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml13
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java38
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java22
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt17
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt95
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt50
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java14
-rw-r--r--libs/androidfw/AssetManager.cpp12
-rw-r--r--libs/androidfw/AssetManager2.cpp2
-rw-r--r--libs/androidfw/OWNERS1
-rw-r--r--libs/androidfw/ResourceTypes.cpp6
-rw-r--r--libs/protoutil/include/android/util/ProtoOutputStream.h2
-rw-r--r--libs/protoutil/src/ProtoOutputStream.cpp4
-rw-r--r--media/java/android/media/AudioFormat.java3
-rw-r--r--media/java/android/media/flags/media_better_together.aconfig7
-rw-r--r--media/jni/android_media_MediaCodec.cpp12
-rw-r--r--media/jni/android_media_MediaDescrambler.cpp2
-rw-r--r--media/jni/android_media_MediaPlayer.cpp2
-rw-r--r--native/android/obb.cpp2
-rw-r--r--packages/CarrierDefaultApp/res/values-sq/strings.xml4
-rw-r--r--packages/CredentialManager/horologist/README.md3
-rw-r--r--packages/CredentialManager/res/values-b+sr+Latn/strings.xml4
-rw-r--r--packages/CredentialManager/res/values-in/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-sq/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-sr/strings.xml4
-rw-r--r--packages/CredentialManager/shared/README.md2
-rw-r--r--packages/CredentialManager/wear/README.md1
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt16
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt29
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt40
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt61
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt20
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt8
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java107
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java2
-rw-r--r--packages/Shell/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/OWNERS2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml2
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt7
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt5
-rw-r--r--packages/SystemUI/proguard_common.flags9
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml129
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml109
-rw-r--r--packages/SystemUI/res-keyguard/values-sq/strings.xml4
-rw-r--r--packages/SystemUI/res-keyguard/xml/keyguard_password_scene.xml49
-rw-r--r--packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml47
-rw-r--r--packages/SystemUI/res-product/values-sq/strings.xml2
-rw-r--r--packages/SystemUI/res/layout/battery_percentage_view.xml1
-rw-r--r--packages/SystemUI/res/layout/battery_status_chip.xml5
-rw-r--r--packages/SystemUI/res/layout/combined_qs_header.xml45
-rw-r--r--packages/SystemUI/res/layout/status_bar.xml1
-rw-r--r--packages/SystemUI/res/values-af/strings.xml14
-rw-r--r--packages/SystemUI/res/values-am/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml14
-rw-r--r--packages/SystemUI/res/values-as/strings.xml16
-rw-r--r--packages/SystemUI/res/values-az/strings.xml14
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml20
-rw-r--r--packages/SystemUI/res/values-be/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml14
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml16
-rw-r--r--packages/SystemUI/res/values-da/strings.xml26
-rw-r--r--packages/SystemUI/res/values-de/strings.xml14
-rw-r--r--packages/SystemUI/res/values-el/strings.xml14
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml4
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml4
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml14
-rw-r--r--packages/SystemUI/res/values-es/strings.xml14
-rw-r--r--packages/SystemUI/res/values-et/strings.xml14
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml18
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml22
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml18
-rw-r--r--packages/SystemUI/res/values-in/strings.xml14
-rw-r--r--packages/SystemUI/res/values-is/strings.xml14
-rw-r--r--packages/SystemUI/res/values-it/strings.xml44
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml16
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml16
-rw-r--r--packages/SystemUI/res/values-km/strings.xml14
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml22
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml18
-rw-r--r--packages/SystemUI/res/values-land/config.xml4
-rw-r--r--packages/SystemUI/res/values-land/dimens.xml3
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml18
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml16
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml10
-rw-r--r--packages/SystemUI/res/values-my/strings.xml16
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml20
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-or/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml20
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml20
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml14
-rw-r--r--packages/SystemUI/res/values-si/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml16
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml18
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml20
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/config.xml4
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml8
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml14
-rw-r--r--packages/SystemUI/res/values-te/strings.xml14
-rw-r--r--packages/SystemUI/res/values-th/strings.xml14
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml18
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml14
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml14
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml16
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml14
-rw-r--r--packages/SystemUI/res/values/config.xml5
-rw-r--r--packages/SystemUI/res/values/dimens.xml8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java31
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java68
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java16
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java98
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java12
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/dagger/UdfpsModule.kt66
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt (renamed from packages/SystemUI/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepository.kt)60
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/shared/model/DisplayRotation.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java200
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImpl.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt298
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureLayoutInflaterFactory.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PlaceHolderDrawable.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewVisibilityHelper.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt121
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepositoryTest.kt)66
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModelTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt243
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt79
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java78
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt359
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeRearDisplayStateRepository.kt)10
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt17
-rw-r--r--services/accessibility/accessibility.aconfig15
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java3
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java5
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java57
-rw-r--r--services/core/java/com/android/server/SmartStorageMaintIdler.java29
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java21
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java1
-rw-r--r--services/core/java/com/android/server/am/AnrHelper.java3
-rw-r--r--services/core/java/com/android/server/am/AnrTimer.java834
-rw-r--r--services/core/java/com/android/server/am/BroadcastProcessQueue.java20
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java85
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java17
-rw-r--r--services/core/java/com/android/server/biometrics/AuthenticationStats.java5
-rw-r--r--services/core/java/com/android/server/biometrics/AuthenticationStatsBroadcastReceiver.java70
-rw-r--r--services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java37
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricSensor.java5
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricLogger.java11
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java14
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java14
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java14
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java3
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java12
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java31
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java33
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java4
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java5
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java22
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java4
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java132
-rw-r--r--services/core/java/com/android/server/display/config/HdrBrightnessData.java98
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java85
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig8
-rw-r--r--services/core/java/com/android/server/media/BluetoothRouteController.java13
-rw-r--r--services/core/java/com/android/server/media/DeviceRouteController.java13
-rw-r--r--services/core/java/com/android/server/media/LegacyBluetoothRouteController.java6
-rw-r--r--services/core/java/com/android/server/media/MediaFeatureFlagManager.java9
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java1
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java18
-rw-r--r--services/core/java/com/android/server/pm/AppDataHelper.java16
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java3
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java1
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java144
-rw-r--r--services/core/java/com/android/server/pm/InstallRequest.java114
-rw-r--r--services/core/java/com/android/server/pm/Installer.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiver.java156
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java16
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java123
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java92
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java26
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java64
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java1
-rw-r--r--services/core/java/com/android/server/pm/Settings.java17
-rw-r--r--services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java9
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageUserState.java7
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java5
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java21
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java22
-rw-r--r--services/core/java/com/android/server/security/Android.bp17
-rw-r--r--services/core/java/com/android/server/security/FileIntegrityService.java7
-rw-r--r--services/core/java/com/android/server/security/flags.aconfig8
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java162
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartInterceptor.java29
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java2
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java100
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java12
-rw-r--r--services/core/java/com/android/server/wm/LetterboxConfiguration.java34
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java19
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java5
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd32
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt16
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerService.java16
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java3
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java89
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java3
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java4
-rw-r--r--services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt1722
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java38
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java55
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java10
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java117
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java378
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsBroadcastReceiverTest.java113
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/media/BluetoothRouteControllerTest.java73
-rw-r--r--services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java73
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java198
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java90
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java48
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java9
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java6
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java9
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteManager.java14
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt40
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt3
-rw-r--r--tools/aapt/AaptAssets.cpp32
-rw-r--r--tools/aapt/Command.cpp6
-rw-r--r--tools/aapt/Resource.cpp10
-rw-r--r--tools/aapt/StringPool.cpp6
-rw-r--r--tools/aapt/XMLNode.cpp2
-rw-r--r--tools/aapt/tests/AaptGroupEntry_test.cpp2
-rw-r--r--tools/aapt2/DominatorTree_test.cpp4
-rw-r--r--tools/aapt2/OWNERS4
-rw-r--r--tools/validatekeymaps/Main.cpp2
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_landscape_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 38859 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_portrait_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 42551 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_landscape_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 38645 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_portrait_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 42281 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_landscape_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 30421 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_portrait_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 32160 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_landscape_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 30225 bytes
-rw-r--r--vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_portrait_credential_view_pin_or_password_emergency_call_button.pngbin0 -> 31900 bytes
-rw-r--r--wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java53
724 files changed, 11046 insertions, 4195 deletions
diff --git a/api/gen_combined_removed_dex.sh b/api/gen_combined_removed_dex.sh
index 9225fe8dfe85..71f366a6aae2 100755
--- a/api/gen_combined_removed_dex.sh
+++ b/api/gen_combined_removed_dex.sh
@@ -6,6 +6,6 @@ shift 2
# Convert each removed.txt to the "dex format" equivalent, and print all output.
for f in "$@"; do
- "$metalava_path" --no-banner "$f" --dex-api "${tmp_dir}/tmp"
+ "$metalava_path" "$f" --dex-api "${tmp_dir}/tmp"
cat "${tmp_dir}/tmp"
done
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index f2d0efe4bb94..89776dba7878 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -1834,7 +1834,7 @@ BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn) {
fn.c_str());
return nullptr;
}
- ZipFileRO *zip = ZipFileRO::open(fn);
+ ZipFileRO *zip = ZipFileRO::open(fn.c_str());
if (zip == nullptr) {
SLOGE("Failed to open animation zip \"%s\": %s",
fn.c_str(), strerror(errno));
diff --git a/cmds/idmap2/idmap2/Lookup.cpp b/cmds/idmap2/idmap2/Lookup.cpp
index 3704b4aff6c7..34d91795fc29 100644
--- a/cmds/idmap2/idmap2/Lookup.cpp
+++ b/cmds/idmap2/idmap2/Lookup.cpp
@@ -94,7 +94,7 @@ void PrintValue(AssetManager2* const am, const AssetManager2::SelectedValue& val
const ResStringPool* pool = am->GetStringPoolForCookie(value.cookie);
out->append("\"");
if (auto str = pool->string8ObjectAt(value.data); str.ok()) {
- out->append(*str);
+ out->append(str->c_str());
}
} break;
default:
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index e70748e8909f..5ebf3e2c3047 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -567,7 +567,7 @@ status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8
fprintf(out, "Not enough arguments for section\n");
return NO_ERROR;
}
- int id = atoi(args[1]);
+ int id = atoi(args[1].c_str());
int idx = 0;
while (SECTION_LIST[idx] != NULL) {
const Section* section = SECTION_LIST[idx];
diff --git a/core/api/current.txt b/core/api/current.txt
index 1879da534377..f488c82a2a60 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -38658,7 +38658,7 @@ package android.security {
public final class FileIntegrityManager {
method @FlaggedApi(Flags.FLAG_FSVERITY_API) @Nullable public byte[] getFsVerityDigest(@NonNull java.io.File) throws java.io.IOException;
method public boolean isApkVeritySupported();
- method @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public boolean isAppSourceCertificateTrusted(@NonNull java.security.cert.X509Certificate) throws java.security.cert.CertificateEncodingException;
+ method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public boolean isAppSourceCertificateTrusted(@NonNull java.security.cert.X509Certificate) throws java.security.cert.CertificateEncodingException;
method @FlaggedApi(Flags.FLAG_FSVERITY_API) public void setupFsVerity(@NonNull java.io.File) throws java.io.IOException;
}
@@ -51231,11 +51231,8 @@ package android.view {
@FlaggedApi(Flags.FLAG_SCROLL_FEEDBACK_API) public interface ScrollFeedbackProvider {
method public void onScrollLimit(int, int, int, boolean);
- method public default void onScrollLimit(@NonNull android.view.MotionEvent, int, boolean);
method public void onScrollProgress(int, int, int, int);
- method public default void onScrollProgress(@NonNull android.view.MotionEvent, int, int);
method public void onSnapToItem(int, int, int);
- method public default void onSnapToItem(@NonNull android.view.MotionEvent, int);
}
public class SearchEvent {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index fcfa41a6efff..5c48b21ad35e 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -95,6 +95,7 @@ package android {
field public static final String BYPASS_ROLE_QUALIFICATION = "android.permission.BYPASS_ROLE_QUALIFICATION";
field public static final String CALL_AUDIO_INTERCEPTION = "android.permission.CALL_AUDIO_INTERCEPTION";
field public static final String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
+ field public static final String CAMERA_HEADLESS_SYSTEM_USER = "android.permission.CAMERA_HEADLESS_SYSTEM_USER";
field public static final String CAMERA_OPEN_CLOSE_LISTENER = "android.permission.CAMERA_OPEN_CLOSE_LISTENER";
field public static final String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD";
field public static final String CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD = "android.permission.CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD";
@@ -3483,6 +3484,7 @@ package android.content {
field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
field public static final String TETHERING_SERVICE = "tethering";
+ field public static final String THREAD_NETWORK_SERVICE = "thread_network";
field public static final String TIME_MANAGER_SERVICE = "time_manager";
field public static final String TRANSLATION_MANAGER_SERVICE = "translation";
field public static final String UI_TRANSLATION_SERVICE = "ui_translation";
@@ -3798,10 +3800,6 @@ package android.content.pm {
field @RequiresPermission(android.Manifest.permission.ACCESS_SHORTCUTS) public static final int FLAG_GET_PERSONS_DATA = 2048; // 0x800
}
- public class PackageInfo implements android.os.Parcelable {
- field public boolean isArchived;
- }
-
public class PackageInstaller {
method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
@@ -3879,6 +3877,7 @@ package android.content.pm {
method public static void forceSafeLabels();
method @Deprecated @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager);
method @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager, @FloatRange(from=0) float, int);
+ field @FlaggedApi(Flags.FLAG_ARCHIVING) public boolean isArchived;
}
public abstract class PackageManager {
@@ -16707,10 +16706,12 @@ package android.telephony.satellite {
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED = 3; // 0x3
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS = 2; // 0x2
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN = -1; // 0xffffffff
+ field @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public static final int SATELLITE_MODEM_STATE_CONNECTED = 7; // 0x7
field public static final int SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3; // 0x3
field public static final int SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2; // 0x2
field public static final int SATELLITE_MODEM_STATE_IDLE = 0; // 0x0
field public static final int SATELLITE_MODEM_STATE_LISTENING = 1; // 0x1
+ field @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public static final int SATELLITE_MODEM_STATE_NOT_CONNECTED = 6; // 0x6
field public static final int SATELLITE_MODEM_STATE_OFF = 4; // 0x4
field public static final int SATELLITE_MODEM_STATE_UNAVAILABLE = 5; // 0x5
field public static final int SATELLITE_MODEM_STATE_UNKNOWN = -1; // 0xffffffff
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 642813f36a58..a4cc44646341 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -50,6 +50,7 @@ package android {
field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS";
field public static final String SET_GAME_SERVICE = "android.permission.SET_GAME_SERVICE";
field public static final String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT";
+ field public static final String START_ACTIVITIES_FROM_SDK_SANDBOX = "android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX";
field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC";
field public static final String TEST_INPUT_METHOD = "android.permission.TEST_INPUT_METHOD";
@@ -2115,6 +2116,7 @@ package android.net.wifi.sharedconnectivity.app {
public class SharedConnectivityManager {
method @Nullable public static android.net.wifi.sharedconnectivity.app.SharedConnectivityManager create(@NonNull android.content.Context, @NonNull String, @NonNull String);
+ method @NonNull public android.content.BroadcastReceiver getBroadcastReceiver();
method @Nullable public android.content.ServiceConnection getServiceConnection();
method public void setService(@Nullable android.os.IInterface);
}
@@ -3504,6 +3506,10 @@ package android.view {
field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
}
+ public static final class MotionEvent.PointerCoords {
+ method public boolean isResampled();
+ }
+
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface RemotableViewMethod {
method public abstract String asyncImpl() default "";
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 00e546ad25b0..01912012f04a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3720,7 +3720,19 @@ public final class ActivityThread extends ClientTransactionHandler
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
- if (r.packageInfo == null) {
+
+ if (getInstrumentation() != null
+ && getInstrumentation().getContext() != null
+ && getInstrumentation().getContext().getApplicationInfo() != null
+ && getInstrumentation().isSdkSandboxAllowedToStartActivities()) {
+ // Activities launched from CTS-in-sandbox tests use a customized ApplicationInfo. See
+ // also {@link SdkSandboxManagerLocal#getSdkSandboxApplicationInfoForInstrumentation}.
+ r.packageInfo =
+ getPackageInfo(
+ getInstrumentation().getContext().getApplicationInfo(),
+ mCompatibilityInfo,
+ Context.CONTEXT_INCLUDE_CODE);
+ } else if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo,
Context.CONTEXT_INCLUDE_CODE);
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index e31486f18dbf..10747bb0e57e 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerGlobal;
@@ -474,6 +475,56 @@ public class Instrumentation {
sr.waitForComplete();
}
+ boolean isSdkSandboxAllowedToStartActivities() {
+ return Process.isSdkSandbox()
+ && mThread != null
+ && mThread.mBoundApplication != null
+ && mThread.mBoundApplication.isSdkInSandbox
+ && getContext() != null
+ && (getContext()
+ .checkSelfPermission(
+ android.Manifest.permission
+ .START_ACTIVITIES_FROM_SDK_SANDBOX)
+ == PackageManager.PERMISSION_GRANTED);
+ }
+
+ /**
+ * Activity name resolution for CTS-in-SdkSandbox tests requires some adjustments. Intents
+ * generated using {@link Context#getPackageName()} use the SDK sandbox package name in the
+ * component field instead of the test package name. An SDK-in-sandbox test attempting to launch
+ * an activity in the test package will encounter name resolution errors when resolving the
+ * activity name in the SDK sandbox package.
+ *
+ * <p>This function replaces the package name of the input intent component to allow activities
+ * belonging to a CTS-in-sandbox test to resolve correctly.
+ *
+ * @param intent the intent to modify to allow CTS-in-sandbox activity resolution.
+ */
+ private void adjustIntentForCtsInSdkSandboxInstrumentation(@NonNull Intent intent) {
+ if (mComponent != null
+ && intent.getComponent() != null
+ && getContext()
+ .getPackageManager()
+ .getSdkSandboxPackageName()
+ .equals(intent.getComponent().getPackageName())) {
+ // Resolve the intent target for the test package, not for the sandbox package.
+ intent.setComponent(
+ new ComponentName(
+ mComponent.getPackageName(), intent.getComponent().getClassName()));
+ }
+ // We match the intent identifier against the running instrumentations for the sandbox.
+ intent.setIdentifier(mComponent.getPackageName());
+ }
+
+ private ActivityInfo resolveActivityInfoForCtsInSandbox(@NonNull Intent intent) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ ActivityInfo ai = intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0);
+ if (ai != null) {
+ ai.processName = mThread.getProcessName();
+ }
+ return ai;
+ }
+
/**
* Start a new activity and wait for it to begin running before returning.
* In addition to being synchronous, this method as some semantic
@@ -531,8 +582,10 @@ public class Instrumentation {
synchronized (mSync) {
intent = new Intent(intent);
- ActivityInfo ai = intent.resolveActivityInfo(
- getTargetContext().getPackageManager(), 0);
+ ActivityInfo ai =
+ isSdkSandboxAllowedToStartActivities()
+ ? resolveActivityInfoForCtsInSandbox(intent)
+ : intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0);
if (ai == null) {
throw new RuntimeException("Unable to resolve activity for: " + intent);
}
@@ -1842,6 +1895,9 @@ public class Instrumentation {
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
+ if (isSdkSandboxAllowedToStartActivities()) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ }
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
@@ -1914,6 +1970,11 @@ public class Instrumentation {
IBinder token, Activity target, Intent[] intents, Bundle options,
int userId) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
+ if (isSdkSandboxAllowedToStartActivities()) {
+ for (Intent intent : intents) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ }
+ }
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
@@ -1989,6 +2050,9 @@ public class Instrumentation {
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
+ if (isSdkSandboxAllowedToStartActivities()) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ }
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
@@ -2060,6 +2124,9 @@ public class Instrumentation {
Context who, IBinder contextThread, IBinder token, String resultWho,
Intent intent, int requestCode, Bundle options, UserHandle user) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
+ if (isSdkSandboxAllowedToStartActivities()) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ }
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
@@ -2110,6 +2177,9 @@ public class Instrumentation {
Intent intent, int requestCode, Bundle options,
boolean ignoreTargetSecurity, int userId) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
+ if (isSdkSandboxAllowedToStartActivities()) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ }
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
@@ -2161,6 +2231,9 @@ public class Instrumentation {
Context who, IBinder contextThread, IAppTask appTask,
Intent intent, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
+ if (isSdkSandboxAllowedToStartActivities()) {
+ adjustIntentForCtsInSdkSandboxInstrumentation(intent);
+ }
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 715edc5161b7..213e5cb4ad64 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -11806,6 +11806,34 @@ public class DevicePolicyManager {
}
/**
+ * Returns the list of {@link EnforcingAdmin}s who have set this restriction.
+ *
+ * <p>Note that for {@link #POLICY_SUSPEND_PACKAGES} it returns the PO or DO to keep the
+ * behavior the same as before the bug fix for b/192245204.
+ *
+ * <p>This API is only callable by the system UID
+ *
+ * @param userId The user for whom to retrieve the information.
+ * @param restriction The restriction enforced by admins. It could be any user restriction or
+ * policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA} and
+ * {@link DevicePolicyManager#POLICY_DISABLE_SCREEN_CAPTURE}.
+ *
+ * @hide
+ */
+ public @NonNull Set<EnforcingAdmin> getEnforcingAdminsForRestriction(int userId,
+ @NonNull String restriction) {
+ if (mService != null) {
+ try {
+ return new HashSet<>(mService.getEnforcingAdminsForRestriction(
+ userId, restriction));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return null;
+ }
+
+ /**
* Hide or unhide packages. When a package is hidden it is unavailable for use, but the data and
* actual package file remain. This function can be called by a device owner, profile owner, or
* by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via
diff --git a/core/java/android/app/admin/EnforcingAdmin.aidl b/core/java/android/app/admin/EnforcingAdmin.aidl
new file mode 100644
index 000000000000..bfbfdbeaf9aa
--- /dev/null
+++ b/core/java/android/app/admin/EnforcingAdmin.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+parcelable EnforcingAdmin; \ No newline at end of file
diff --git a/core/java/android/app/admin/EnforcingAdmin.java b/core/java/android/app/admin/EnforcingAdmin.java
index 771794dbe0fb..7c718f6651a2 100644
--- a/core/java/android/app/admin/EnforcingAdmin.java
+++ b/core/java/android/app/admin/EnforcingAdmin.java
@@ -19,6 +19,7 @@ package android.app.admin;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
@@ -38,6 +39,11 @@ public final class EnforcingAdmin implements Parcelable {
private final UserHandle mUserHandle;
/**
+ * @hide
+ */
+ private final ComponentName mComponentName;
+
+ /**
* Creates an enforcing admin with the given params.
*/
public EnforcingAdmin(
@@ -46,6 +52,21 @@ public final class EnforcingAdmin implements Parcelable {
mPackageName = Objects.requireNonNull(packageName);
mAuthority = Objects.requireNonNull(authority);
mUserHandle = Objects.requireNonNull(userHandle);
+ mComponentName = null;
+ }
+
+ /**
+ * Creates an enforcing admin with the given params.
+ *
+ * @hide
+ */
+ public EnforcingAdmin(
+ @NonNull String packageName, @NonNull Authority authority,
+ @NonNull UserHandle userHandle, @Nullable ComponentName componentName) {
+ mPackageName = Objects.requireNonNull(packageName);
+ mAuthority = Objects.requireNonNull(authority);
+ mUserHandle = Objects.requireNonNull(userHandle);
+ mComponentName = componentName;
}
private EnforcingAdmin(Parcel source) {
@@ -53,6 +74,7 @@ public final class EnforcingAdmin implements Parcelable {
mUserHandle = new UserHandle(source.readInt());
mAuthority = Objects.requireNonNull(
source.readParcelable(Authority.class.getClassLoader()));
+ mComponentName = source.readParcelable(ComponentName.class.getClassLoader());
}
/**
@@ -86,7 +108,8 @@ public final class EnforcingAdmin implements Parcelable {
EnforcingAdmin other = (EnforcingAdmin) o;
return Objects.equals(mPackageName, other.mPackageName)
&& Objects.equals(mAuthority, other.mAuthority)
- && Objects.equals(mUserHandle, other.mUserHandle);
+ && Objects.equals(mUserHandle, other.mUserHandle)
+ && Objects.equals(mComponentName, other.mComponentName);
}
@Override
@@ -97,7 +120,7 @@ public final class EnforcingAdmin implements Parcelable {
@Override
public String toString() {
return "EnforcingAdmin { mPackageName= " + mPackageName + ", mAuthority= " + mAuthority
- + ", mUserHandle= " + mUserHandle + " }";
+ + ", mUserHandle= " + mUserHandle + ", mComponentName= " + mComponentName + " }";
}
@Override
@@ -110,6 +133,7 @@ public final class EnforcingAdmin implements Parcelable {
dest.writeString(mPackageName);
dest.writeInt(mUserHandle.getIdentifier());
dest.writeParcelable(mAuthority, flags);
+ dest.writeParcelable(mComponentName, flags);
}
@NonNull
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 95ec89e5f444..c49b820b9e37 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -54,6 +54,7 @@ import android.security.keystore.ParcelableKeyGenParameterSpec;
import android.telephony.data.ApnSetting;
import com.android.internal.infra.AndroidFuture;
import android.app.admin.DevicePolicyState;
+import android.app.admin.EnforcingAdmin;
import java.util.List;
@@ -274,6 +275,7 @@ interface IDevicePolicyManager {
Intent createAdminSupportIntent(in String restriction);
Bundle getEnforcingAdminAndUserDetails(int userId,String restriction);
+ List<EnforcingAdmin> getEnforcingAdminsForRestriction(int userId,String restriction);
boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden, boolean parent);
boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean parent);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d6dee9389c8e..b6a98a5b8f83 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4089,6 +4089,7 @@ public abstract class Context {
VIBRATOR_MANAGER_SERVICE,
VIBRATOR_SERVICE,
//@hide: STATUS_BAR_SERVICE,
+ THREAD_NETWORK_SERVICE,
CONNECTIVITY_SERVICE,
PAC_PROXY_SERVICE,
VCN_MANAGEMENT_SERVICE,
@@ -4764,6 +4765,20 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.net.thread.ThreadNetworkManager}.
+ *
+ * <p>On devices without {@link PackageManager#FEATURE_THREAD_NETWORK} system feature
+ * the {@link #getSystemService(String)} will return {@code null}.
+ *
+ * @see #getSystemService(String)
+ * @see android.net.thread.ThreadNetworkManager
+ * @hide
+ */
+ @SystemApi
+ public static final String THREAD_NETWORK_SERVICE = "thread_network";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.net.IpSecManager} for encrypting Sockets or Networks with
* IPSec.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e9bbed340800..7579d99f4927 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -12516,6 +12516,7 @@ public class Intent implements Parcelable, Cloneable {
return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT;
}
+ // TODO(b/299109198): Refactor into the {@link SdkSandboxManagerLocal}
/** @hide */
public boolean isSandboxActivity(@NonNull Context context) {
if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) {
diff --git a/core/java/android/content/om/OWNERS b/core/java/android/content/om/OWNERS
index 3669817e9844..72aed2d3fdaf 100644
--- a/core/java/android/content/om/OWNERS
+++ b/core/java/android/content/om/OWNERS
@@ -1,6 +1,5 @@
# Bug component: 568631
-toddke@android.com
-toddke@google.com
patb@google.com
zyy@google.com
+jakmcbane@google.com \ No newline at end of file
diff --git a/core/java/android/content/pm/ArchivedActivityParcel.aidl b/core/java/android/content/pm/ArchivedActivityParcel.aidl
new file mode 100644
index 000000000000..7ab7ed1cc5df
--- /dev/null
+++ b/core/java/android/content/pm/ArchivedActivityParcel.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+/** @hide */
+parcelable ArchivedActivityParcel {
+ String title;
+ // PNG compressed bitmaps.
+ byte[] iconBitmap;
+ byte[] monochromeIconBitmap;
+}
diff --git a/core/java/android/content/pm/ArchivedPackageParcel.aidl b/core/java/android/content/pm/ArchivedPackageParcel.aidl
index 573e69094e35..d3cd79efc3b5 100644
--- a/core/java/android/content/pm/ArchivedPackageParcel.aidl
+++ b/core/java/android/content/pm/ArchivedPackageParcel.aidl
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.content.pm.ArchivedActivityParcel;
import android.content.pm.SigningDetails;
/**
@@ -29,9 +30,8 @@ parcelable ArchivedPackageParcel {
int versionCode;
int versionCodeMajor;
int targetSdkVersion;
- String backupAllowed;
String defaultToDeviceProtectedStorage;
String requestLegacyExternalStorage;
String userDataFragile;
- String clearUserDataOnFailedRestoreAllowed;
+ ArchivedActivityParcel[] archivedActivities;
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 556c794b6139..94c3b5229e32 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -832,5 +832,5 @@ interface IPackageManager {
void unregisterPackageMonitorCallback(IRemoteCallback callback);
- ArchivedPackageParcel getArchivedPackage(in String apkPath);
+ ArchivedPackageParcel getArchivedPackage(in String packageName, int userId);
}
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 1fe19231e4b4..63c11b779641 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -18,9 +18,7 @@ package android.content.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.IntentSender;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -490,18 +488,6 @@ public class PackageInfo implements Parcelable {
*/
public boolean isActiveApex;
- /**
- * Whether the package is currently in an archived state.
- *
- * <p>Packages can be archived through
- * {@link PackageInstaller#requestArchive(String, IntentSender)} and do not have any APKs stored
- * on the device, but do keep the data directory.
- * @hide
- */
- // TODO(b/278553670) Unhide and update @links before launch.
- @SystemApi
- public boolean isArchived;
-
public PackageInfo() {
}
@@ -589,7 +575,6 @@ public class PackageInfo implements Parcelable {
}
dest.writeBoolean(isApex);
dest.writeBoolean(isActiveApex);
- dest.writeBoolean(isArchived);
dest.restoreAllowSquashing(prevAllowSquashing);
}
@@ -655,6 +640,5 @@ public class PackageInfo implements Parcelable {
}
isApex = source.readBoolean();
isActiveApex = source.readBoolean();
- isArchived = source.readBoolean();
}
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 390efd44be85..673a8a5edcba 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1518,8 +1518,7 @@ public class PackageInstaller {
* This returns all names which have been previously written through
* {@link #openWrite(String, long, long)} as part of this session.
*
- * @throws SecurityException if called after the session has been
- * committed or abandoned.
+ * @throws SecurityException if called after the session has been abandoned.
*/
public @NonNull String[] getNames() throws IOException {
try {
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index bb978e05dd16..c7091ad99199 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -21,6 +21,7 @@ import static android.text.TextUtils.SAFE_STRING_FLAG_SINGLE_LINE;
import static android.text.TextUtils.SAFE_STRING_FLAG_TRIM;
import static android.text.TextUtils.makeSafeForPresentation;
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
@@ -173,6 +174,18 @@ public class PackageItemInfo {
*/
public int showUserIcon;
+ /**
+ * Whether the package is currently in an archived state.
+ *
+ * <p>Packages can be archived through {@link PackageArchiver} and do not have any APKs stored
+ * on the device, but do keep the data directory.
+ * @hide
+ */
+ // TODO(b/278553670) Unhide and update @links before launch.
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ARCHIVING)
+ public boolean isArchived;
+
public PackageItemInfo() {
showUserIcon = UserHandle.USER_NULL;
}
@@ -189,6 +202,7 @@ public class PackageItemInfo {
logo = orig.logo;
metaData = orig.metaData;
showUserIcon = orig.showUserIcon;
+ isArchived = orig.isArchived;
}
/**
@@ -442,6 +456,7 @@ public class PackageItemInfo {
dest.writeBundle(metaData);
dest.writeInt(banner);
dest.writeInt(showUserIcon);
+ dest.writeBoolean(isArchived);
}
/**
@@ -459,6 +474,7 @@ public class PackageItemInfo {
}
proto.write(PackageItemInfoProto.ICON, icon);
proto.write(PackageItemInfoProto.BANNER, banner);
+ proto.write(PackageItemInfoProto.IS_ARCHIVED, isArchived);
proto.end(token);
}
@@ -473,6 +489,7 @@ public class PackageItemInfo {
metaData = source.readBundle();
banner = source.readInt();
showUserIcon = source.readInt();
+ isArchived = source.readBoolean();
}
/**
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 149de7efc861..0333942b7f3e 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -834,4 +834,11 @@ public abstract class RegisteredServicesCache<V> {
public abstract V parseServiceAttributes(Resources res,
String packageName, AttributeSet attrs);
+
+ @VisibleForTesting
+ public void unregisterReceivers() {
+ mContext.unregisterReceiver(mPackageReceiver);
+ mContext.unregisterReceiver(mExternalReceiver);
+ mContext.unregisterReceiver(mUserRemovedReceiver);
+ }
}
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index 159b789fc4a0..f3194be81b0d 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -23,11 +23,9 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.SigningDetails;
import android.content.pm.VerifierInfo;
-import android.os.Build;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DataClass;
-import com.android.internal.util.XmlUtils;
import java.util.List;
import java.util.Set;
@@ -142,32 +140,9 @@ public class ApkLite {
private final boolean mIsSdkLibrary;
/**
- * Set to <code>false</code> if the application does not wish to permit any OS-driven
- * backups of its data; <code>true</code> otherwise.
+ * Archival install info.
*/
- private final boolean mBackupAllowed;
-
- /**
- * When set, the default data storage directory for this app is pointed at
- * the device-protected location.
- */
- private final boolean mDefaultToDeviceProtectedStorage;
-
- /**
- * If {@code true} this app requests full external storage access.
- */
- private final boolean mRequestLegacyExternalStorage;
-
- /**
- * Indicates whether this application has declared its user data as fragile, causing the
- * system to prompt the user on whether to keep the user data on uninstall.
- */
- private final boolean mUserDataFragile;
-
- /**
- * Indicates whether this application's data will be cleared on a failed restore.
- */
- private final boolean mClearUserDataOnFailedRestoreAllowed;
+ private final @Nullable ArchivedPackageParcel mArchivedPackage;
public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit,
String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode,
@@ -179,10 +154,7 @@ public class ApkLite {
String requiredSystemPropertyName, String requiredSystemPropertyValue,
int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
Set<String> requiredSplitTypes, Set<String> splitTypes,
- boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean clearUserDataAllowed,
- boolean backupAllowed, boolean defaultToDeviceProtectedStorage,
- boolean requestLegacyExternalStorage, boolean userDataFragile,
- boolean clearUserDataOnFailedRestoreAllowed) {
+ boolean hasDeviceAdminReceiver, boolean isSdkLibrary) {
mPath = path;
mPackageName = packageName;
mSplitName = splitName;
@@ -216,11 +188,7 @@ public class ApkLite {
mRollbackDataPolicy = rollbackDataPolicy;
mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
mIsSdkLibrary = isSdkLibrary;
- mBackupAllowed = backupAllowed;
- mDefaultToDeviceProtectedStorage = defaultToDeviceProtectedStorage;
- mRequestLegacyExternalStorage = requestLegacyExternalStorage;
- mUserDataFragile = userDataFragile;
- mClearUserDataOnFailedRestoreAllowed = clearUserDataOnFailedRestoreAllowed;
+ mArchivedPackage = null;
}
public ApkLite(String path, ArchivedPackageParcel archivedPackage) {
@@ -257,16 +225,7 @@ public class ApkLite {
mRollbackDataPolicy = 0;
mHasDeviceAdminReceiver = false;
mIsSdkLibrary = false;
- // @see ParsingPackageUtils#parseBaseAppBasicFlags
- mBackupAllowed = XmlUtils.convertValueToBoolean(archivedPackage.backupAllowed, true);
- mDefaultToDeviceProtectedStorage = XmlUtils.convertValueToBoolean(
- archivedPackage.defaultToDeviceProtectedStorage, false);
- mRequestLegacyExternalStorage = XmlUtils.convertValueToBoolean(
- archivedPackage.requestLegacyExternalStorage,
- mTargetSdkVersion < Build.VERSION_CODES.Q);
- mUserDataFragile = XmlUtils.convertValueToBoolean(archivedPackage.userDataFragile, false);
- mClearUserDataOnFailedRestoreAllowed = XmlUtils.convertValueToBoolean(
- archivedPackage.clearUserDataOnFailedRestoreAllowed, true);
+ mArchivedPackage = archivedPackage;
}
/**
@@ -576,53 +535,18 @@ public class ApkLite {
}
/**
- * Set to <code>false</code> if the application does not wish to permit any OS-driven
- * backups of its data; <code>true</code> otherwise.
- */
- @DataClass.Generated.Member
- public boolean isBackupAllowed() {
- return mBackupAllowed;
- }
-
- /**
- * When set, the default data storage directory for this app is pointed at
- * the device-protected location.
- */
- @DataClass.Generated.Member
- public boolean isDefaultToDeviceProtectedStorage() {
- return mDefaultToDeviceProtectedStorage;
- }
-
- /**
- * If {@code true} this app requests full external storage access.
- */
- @DataClass.Generated.Member
- public boolean isRequestLegacyExternalStorage() {
- return mRequestLegacyExternalStorage;
- }
-
- /**
- * Indicates whether this application has declared its user data as fragile, causing the
- * system to prompt the user on whether to keep the user data on uninstall.
- */
- @DataClass.Generated.Member
- public boolean isUserDataFragile() {
- return mUserDataFragile;
- }
-
- /**
- * Indicates whether this application's data will be cleared on a failed restore.
+ * Archival install info.
*/
@DataClass.Generated.Member
- public boolean isClearUserDataOnFailedRestoreAllowed() {
- return mClearUserDataOnFailedRestoreAllowed;
+ public @Nullable ArchivedPackageParcel getArchivedPackage() {
+ return mArchivedPackage;
}
@DataClass.Generated(
- time = 1693513509013L,
+ time = 1694792109463L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mBackupAllowed\nprivate final boolean mDefaultToDeviceProtectedStorage\nprivate final boolean mRequestLegacyExternalStorage\nprivate final boolean mUserDataFragile\nprivate final boolean mClearUserDataOnFailedRestoreAllowed\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 066ff6896ac8..5f86742fc562 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -40,7 +40,6 @@ import android.util.Pair;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.XmlUtils;
import libcore.io.IoUtils;
@@ -447,13 +446,6 @@ public class ApkLiteParseUtils {
int overlayPriority = 0;
int rollbackDataPolicy = 0;
- boolean clearUserDataAllowed = true;
- boolean backupAllowed = true;
- boolean defaultToDeviceProtectedStorage = false;
- String requestLegacyExternalStorage = null;
- boolean userDataFragile = false;
- boolean clearUserDataOnFailedRestoreAllowed = true;
-
String requiredSystemPropertyName = null;
String requiredSystemPropertyValue = null;
@@ -493,22 +485,6 @@ public class ApkLiteParseUtils {
useEmbeddedDex = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
"useEmbeddedDex", false);
- clearUserDataAllowed = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
- "allowClearUserDataOnFailedRestore", true);
- backupAllowed = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
- "allowBackup", true);
- defaultToDeviceProtectedStorage = parser.getAttributeBooleanValue(
- ANDROID_RES_NAMESPACE,
- "defaultToDeviceProtectedStorage", false);
- userDataFragile = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
- "hasFragileUserData", false);
- clearUserDataOnFailedRestoreAllowed = parser.getAttributeBooleanValue(
- ANDROID_RES_NAMESPACE,
- "allowClearUserDataOnFailedRestore", true);
-
- requestLegacyExternalStorage = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
- "requestLegacyExternalStorage");
-
rollbackDataPolicy = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE,
"rollbackDataPolicy", 0);
String permission = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
@@ -629,9 +605,6 @@ public class ApkLiteParseUtils {
return input.skip(message);
}
- boolean isRequestLegacyExternalStorage = XmlUtils.convertValueToBoolean(
- requestLegacyExternalStorage, targetSdkVersion < Build.VERSION_CODES.Q);
-
return input.success(
new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
configForSplit, usesSplitName, isSplitRequired, versionCode,
@@ -641,9 +614,7 @@ public class ApkLiteParseUtils {
overlayIsStatic, overlayPriority, requiredSystemPropertyName,
requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
- hasDeviceAdminReceiver, isSdkLibrary, clearUserDataAllowed, backupAllowed,
- defaultToDeviceProtectedStorage, isRequestLegacyExternalStorage,
- userDataFragile, clearUserDataOnFailedRestoreAllowed));
+ hasDeviceAdminReceiver, isSdkLibrary));
}
private static boolean isDeviceAdminReceiver(
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index ccef9def609e..116dd1fc9a42 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -18,6 +18,7 @@ package android.content.pm.parsing;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.ArchivedPackageParcel;
import android.content.pm.PackageInfo;
import android.content.pm.SigningDetails;
import android.content.pm.VerifierInfo;
@@ -112,29 +113,11 @@ public class PackageLite {
* Indicates if this package is a sdk.
*/
private final boolean mIsSdkLibrary;
+
/**
- * Set to <code>false</code> if the application does not wish to permit any OS-driven
- * backups of its data; <code>true</code> otherwise.
- */
- private final boolean mBackupAllowed;
- /**
- * When set, the default data storage directory for this app is pointed at
- * the device-protected location.
- */
- private final boolean mDefaultToDeviceProtectedStorage;
- /**
- * If {@code true} this app requests full external storage access.
- */
- private final boolean mRequestLegacyExternalStorage;
- /**
- * Indicates whether this application has declared its user data as fragile, causing the
- * system to prompt the user on whether to keep the user data on uninstall.
- */
- private final boolean mUserDataFragile;
- /**
- * Indicates whether this application's data will be cleared on a failed restore.
+ * Archival install info.
*/
- private final boolean mClearUserDataOnFailedRestoreAllowed;
+ private final @Nullable ArchivedPackageParcel mArchivedPackage;
public PackageLite(String path, String baseApkPath, ApkLite baseApk,
String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
@@ -171,11 +154,7 @@ public class PackageLite {
mSplitApkPaths = splitApkPaths;
mSplitRevisionCodes = splitRevisionCodes;
mTargetSdk = targetSdk;
- mBackupAllowed = baseApk.isBackupAllowed();
- mDefaultToDeviceProtectedStorage = baseApk.isDefaultToDeviceProtectedStorage();
- mRequestLegacyExternalStorage = baseApk.isRequestLegacyExternalStorage();
- mUserDataFragile = baseApk.isUserDataFragile();
- mClearUserDataOnFailedRestoreAllowed = baseApk.isClearUserDataOnFailedRestoreAllowed();
+ mArchivedPackage = baseApk.getArchivedPackage();
}
/**
@@ -455,53 +434,18 @@ public class PackageLite {
}
/**
- * Set to <code>false</code> if the application does not wish to permit any OS-driven
- * backups of its data; <code>true</code> otherwise.
- */
- @DataClass.Generated.Member
- public boolean isBackupAllowed() {
- return mBackupAllowed;
- }
-
- /**
- * When set, the default data storage directory for this app is pointed at
- * the device-protected location.
- */
- @DataClass.Generated.Member
- public boolean isDefaultToDeviceProtectedStorage() {
- return mDefaultToDeviceProtectedStorage;
- }
-
- /**
- * If {@code true} this app requests full external storage access.
- */
- @DataClass.Generated.Member
- public boolean isRequestLegacyExternalStorage() {
- return mRequestLegacyExternalStorage;
- }
-
- /**
- * Indicates whether this application has declared its user data as fragile, causing the
- * system to prompt the user on whether to keep the user data on uninstall.
- */
- @DataClass.Generated.Member
- public boolean isUserDataFragile() {
- return mUserDataFragile;
- }
-
- /**
- * Indicates whether this application's data will be cleared on a failed restore.
+ * Archival install info.
*/
@DataClass.Generated.Member
- public boolean isClearUserDataOnFailedRestoreAllowed() {
- return mClearUserDataOnFailedRestoreAllowed;
+ public @Nullable ArchivedPackageParcel getArchivedPackage() {
+ return mArchivedPackage;
}
@DataClass.Generated(
- time = 1693513525097L,
+ time = 1694792176268L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final boolean mBackupAllowed\nprivate final boolean mDefaultToDeviceProtectedStorage\nprivate final boolean mRequestLegacyExternalStorage\nprivate final boolean mUserDataFragile\nprivate final boolean mClearUserDataOnFailedRestoreAllowed\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/res/OWNERS b/core/java/android/content/res/OWNERS
index a7bce122eb35..141d58d51353 100644
--- a/core/java/android/content/res/OWNERS
+++ b/core/java/android/content/res/OWNERS
@@ -1,8 +1,7 @@
# Bug component: 568761
-toddke@android.com
-toddke@google.com
patb@google.com
zyy@google.com
+branliu@google.com
per-file FontScaleConverter*=fuego@google.com \ No newline at end of file
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index addd622eef35..17cd18cc4182 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -48,7 +48,8 @@ interface IBiometricAuthenticator {
// startPreparedClient().
void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- long requestId, int cookie, boolean allowBackgroundAuthentication);
+ long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager);
// Starts authentication with the previously prepared client.
void startPreparedClient(int cookie);
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index e2840ec20ff9..0100660669e9 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -74,7 +74,8 @@ interface IFingerprintService {
@EnforcePermission("MANAGE_BIOMETRIC")
void prepareForAuthentication(IBinder token, long operationId,
IBiometricSensorReceiver sensorReceiver, in FingerprintAuthenticateOptions options, long requestId,
- int cookie, boolean allowBackgroundAuthentication);
+ int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager);
// Starts authentication with the previously prepared client.
@EnforcePermission("MANAGE_BIOMETRIC")
diff --git a/core/java/android/hardware/usb/DisplayPortAltModeInfo.java b/core/java/android/hardware/usb/DisplayPortAltModeInfo.java
index 9da2f4c12977..36c4a2ac09e4 100644
--- a/core/java/android/hardware/usb/DisplayPortAltModeInfo.java
+++ b/core/java/android/hardware/usb/DisplayPortAltModeInfo.java
@@ -200,19 +200,43 @@ public final class DisplayPortAltModeInfo implements Parcelable {
dest.writeInt(mLinkTrainingStatus);
}
+ private String displayPortAltModeStatusToString(@DisplayPortAltModeStatus int status) {
+ switch (status) {
+ case DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE:
+ return "not capable";
+ case DISPLAYPORT_ALT_MODE_STATUS_CAPABLE_DISABLED:
+ return "capable disabled";
+ case DISPLAYPORT_ALT_MODE_STATUS_ENABLED:
+ return "enabled";
+ default:
+ return "unknown";
+ }
+ }
+
+ private String linkTrainingStatusToString(@LinkTrainingStatus int status) {
+ switch (status) {
+ case LINK_TRAINING_STATUS_SUCCESS:
+ return "success";
+ case LINK_TRAINING_STATUS_FAILURE:
+ return "failure";
+ default:
+ return "unknown";
+ }
+ }
+
@NonNull
@Override
public String toString() {
return "DisplayPortAltModeInfo{partnerSink="
- + mPartnerSinkStatus
- + " cable="
- + mCableStatus
- + " numLanes="
+ + displayPortAltModeStatusToString(mPartnerSinkStatus)
+ + ", cable="
+ + displayPortAltModeStatusToString(mCableStatus)
+ + ", numLanes="
+ mNumLanes
- + " hotPlugDetect="
+ + ", hotPlugDetect="
+ mHotPlugDetect
- + " linkTrainingStatus="
- + mLinkTrainingStatus
+ + ", linkTrainingStatus="
+ + linkTrainingStatusToString(mLinkTrainingStatus)
+ "}";
}
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index e4a09a651ae1..7f6ec5821cb4 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -176,7 +176,8 @@ final class SoftInputWindow extends Dialog {
try {
super.show();
updateWindowState(WindowState.SHOWN_AT_LEAST_ONCE);
- } catch (WindowManager.BadTokenException e) {
+ } catch (WindowManager.BadTokenException
+ | WindowManager.InvalidDisplayException e) {
// Just ignore this exception. Since show() can be requested from other
// components such as the system and there could be multiple event queues before
// the request finally arrives here, the system may have already invalidated the
diff --git a/core/java/android/nfc/NfcAntennaInfo.java b/core/java/android/nfc/NfcAntennaInfo.java
index d54fcd2ed5b3..b002ca21e8e3 100644
--- a/core/java/android/nfc/NfcAntennaInfo.java
+++ b/core/java/android/nfc/NfcAntennaInfo.java
@@ -85,8 +85,8 @@ public final class NfcAntennaInfo implements Parcelable {
this.mDeviceHeight = in.readInt();
this.mDeviceFoldable = in.readByte() != 0;
this.mAvailableNfcAntennas = new ArrayList<>();
- in.readParcelableList(this.mAvailableNfcAntennas,
- AvailableNfcAntenna.class.getClassLoader());
+ in.readTypedList(this.mAvailableNfcAntennas,
+ AvailableNfcAntenna.CREATOR);
}
public static final @NonNull Parcelable.Creator<NfcAntennaInfo> CREATOR =
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 1929a4d562d4..ada55325aded 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -227,7 +227,7 @@ public final class BinderProxy implements IBinder {
Log.v(Binder.TAG, "BinderProxy map growth! bucket size = " + size
+ " total = " + totalSize);
mWarnBucketSize += WARN_INCREMENT;
- if (Build.IS_DEBUGGABLE && totalSize >= CRASH_AT_SIZE) {
+ if (totalSize >= CRASH_AT_SIZE) {
// Use the number of uncleared entries to determine whether we should
// really report a histogram and crash. We don't want to fundamentally
// change behavior for a debuggable process, so we GC only if we are
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index b210c4644d7d..e96c24d677f1 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -245,7 +245,7 @@ public final class ServiceManager {
public static boolean isDeclared(@NonNull String name) {
try {
return getIServiceManager().isDeclared(name);
- } catch (RemoteException e) {
+ } catch (RemoteException | SecurityException e) {
Log.e(TAG, "error in isDeclared", e);
return false;
}
diff --git a/core/java/android/security/FileIntegrityManager.java b/core/java/android/security/FileIntegrityManager.java
index 132700d289b8..d6f3bf334456 100644
--- a/core/java/android/security/FileIntegrityManager.java
+++ b/core/java/android/security/FileIntegrityManager.java
@@ -133,11 +133,13 @@ public final class FileIntegrityManager {
* also use this API to download the best signature on the running device.
*
* @return whether the certificate is trusted in the system
+ * @deprecated The feature is no longer supported, and this API now always returns false.
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.INSTALL_PACKAGES,
android.Manifest.permission.REQUEST_INSTALL_PACKAGES
})
+ @Deprecated
public boolean isAppSourceCertificateTrusted(@NonNull X509Certificate certificate)
throws CertificateEncodingException {
try {
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index b6c2b83f0daa..cfc6f483e4ae 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -13,3 +13,10 @@ flag {
description: "Fix bugs in behavior of UnlockedDeviceRequired keystore keys"
bug: "296464083"
}
+
+flag {
+ name: "deprecate_fsv_sig"
+ namespace: "hardware_backed_security"
+ description: "Feature flag for deprecating .fsv_sig"
+ bug: "277916185"
+}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index b48b7ecd73a2..3f41c56ac7f1 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -46,6 +46,7 @@ import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SharedMemory;
+import android.os.SystemProperties;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Log;
@@ -131,6 +132,9 @@ public class VoiceInteractionService extends Service {
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
static final long MULTIPLE_ACTIVE_HOTWORD_DETECTORS = 193232191L;
+ private static final boolean SYSPROP_VISUAL_QUERY_SERVICE_ENABLED =
+ SystemProperties.getBoolean("ro.hotword.visual_query_service_enabled", false);
+
IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
@Override
public void ready() {
@@ -947,6 +951,10 @@ public class VoiceInteractionService extends Service {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
+ if (!SYSPROP_VISUAL_QUERY_SERVICE_ENABLED) {
+ throw new IllegalStateException("VisualQueryDetectionService is not enabled on this "
+ + "system. Please set ro.hotword.visual_query_service_enabled to true.");
+ }
if (mSystemService == null) {
throw new IllegalStateException("Not available until onReady() is called");
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 0ed275c7821d..2906d86f803d 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -187,14 +187,6 @@ public class FeatureFlagUtils {
public static final String SETTINGS_FLASH_NOTIFICATIONS = "settings_flash_notifications";
/**
- * Flag to disable/enable showing udfps enroll view in settings. If it's disabled, udfps enroll
- * view is shown in system ui.
- * @hide
- */
- public static final String SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS =
- "settings_show_udfps_enroll_in_settings";
-
- /**
* Flag to enable lock screen credentials transfer API in Android U.
* @hide
*/
@@ -208,14 +200,6 @@ public class FeatureFlagUtils {
public static final String SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION =
"settings_remote_device_credential_validation";
- // TODO(b/295516544): Remove this when trunk stable feature flag is available.
- /**
- * Flag to enable / disable the Private Space Settings. It's disabled by default.
- * @hide
- */
- public static final String SETTINGS_PRIVATE_SPACE_SETTINGS =
- "settings_private_space_settings";
-
private static final Map<String, String> DEFAULT_FLAGS;
@@ -258,13 +242,11 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false");
DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
DEFAULT_FLAGS.put(SETTINGS_FLASH_NOTIFICATIONS, "true");
- DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "true");
DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "true");
DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_FINGERPRINT_SETTINGS, "false");
// TODO: b/298454866 Replace with Trunk Stable Feature Flag
DEFAULT_FLAGS.put(SETTINGS_REMOTEAUTH_ENROLLMENT_SETTINGS, "false");
- DEFAULT_FLAGS.put(SETTINGS_PRIVATE_SPACE_SETTINGS, "false");
}
private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index a208d1f1a558..0ce1d4711c6d 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -24,6 +24,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
@@ -81,6 +82,8 @@ public class HandwritingInitiator {
private int mConnectionCount = 0;
private final InputMethodManager mImm;
+ private final int[] mTempLocation = new int[2];
+
private final Rect mTempRect = new Rect();
private final RectF mTempRectF = new RectF();
@@ -424,7 +427,19 @@ public class HandwritingInitiator {
return null;
}
- private static void requestFocusWithoutReveal(View view) {
+ private void requestFocusWithoutReveal(View view) {
+ if (view instanceof EditText editText && !mState.mStylusDownWithinEditorBounds) {
+ // If the stylus down point was inside the EditText's bounds, then the EditText will
+ // automatically set its cursor position nearest to the stylus down point when it
+ // gains focus. If the stylus down point was outside the EditText's bounds (within
+ // the extended handwriting bounds), then we must calculate and set the cursor
+ // position manually.
+ view.getLocationInWindow(mTempLocation);
+ int offset = editText.getOffsetForPosition(
+ mState.mStylusDownX - mTempLocation[0],
+ mState.mStylusDownY - mTempLocation[1]);
+ editText.setSelection(offset);
+ }
if (view.getRevealOnFocusHint()) {
view.setRevealOnFocusHint(false);
view.requestFocus();
@@ -452,6 +467,10 @@ public class HandwritingInitiator {
if (getViewHandwritingArea(connectedView, handwritingArea)
&& isInHandwritingArea(handwritingArea, x, y, connectedView, isHover)
&& shouldTriggerStylusHandwritingForView(connectedView)) {
+ if (!isHover && mState != null) {
+ mState.mStylusDownWithinEditorBounds =
+ contains(handwritingArea, x, y, 0f, 0f, 0f, 0f);
+ }
return connectedView;
}
}
@@ -470,7 +489,12 @@ public class HandwritingInitiator {
}
final float distance = distance(handwritingArea, x, y);
- if (distance == 0f) return view;
+ if (distance == 0f) {
+ if (!isHover && mState != null) {
+ mState.mStylusDownWithinEditorBounds = true;
+ }
+ return view;
+ }
if (distance < minDistance) {
minDistance = distance;
bestCandidate = view;
@@ -653,6 +677,12 @@ public class HandwritingInitiator {
private boolean mExceedHandwritingSlop;
/**
+ * Whether the stylus down point of the MotionEvent sequence was within the editor's bounds
+ * (not including the extended handwriting bounds).
+ */
+ private boolean mStylusDownWithinEditorBounds;
+
+ /**
* A view which has requested focus and is pending input connection creation. When an input
* connection is created for the view, a handwriting session should be started for the view.
*/
diff --git a/core/java/android/view/HapticScrollFeedbackProvider.java b/core/java/android/view/HapticScrollFeedbackProvider.java
index fba23ba8369f..a2f1d37c2c11 100644
--- a/core/java/android/view/HapticScrollFeedbackProvider.java
+++ b/core/java/android/view/HapticScrollFeedbackProvider.java
@@ -17,21 +17,35 @@
package android.view;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.view.flags.Flags;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* {@link ScrollFeedbackProvider} that performs haptic feedback when scrolling.
*
* <p>Each scrolling widget should have its own instance of this class to ensure that scroll state
* is isolated.
+ *
+ * <p>Check {@link ScrollFeedbackProvider} for details on the arguments that should be passed to the
+ * methods in this class. To check if your input device ID, source, and motion axis are valid for
+ * haptic feedback, you can use the
+ * {@link ViewConfiguration#isHapticScrollFeedbackEnabled(int, int, int)} API.
*/
@FlaggedApi(Flags.FLAG_SCROLL_FEEDBACK_API)
public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
private static final String TAG = "HapticScrollFeedbackProvider";
+ /** @hide */
+ @IntDef(value = {MotionEvent.AXIS_SCROLL})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface HapticScrollFeedbackAxis {}
+
private static final int TICK_INTERVAL_NO_TICK = 0;
private final View mView;
@@ -46,10 +60,6 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
/** The {@link InputDevice} source from which the latest scroll event happened. */
private int mSource = -1;
- /**
- * Cache for tick interval for scroll tick caused by a {@link InputDevice#SOURCE_ROTARY_ENCODER}
- * on {@link MotionEvent#AXIS_SCROLL}. Set to -1 if the value has not been fetched and cached.
- */
/** The tick interval corresponding to the current InputDevice/source/axis. */
private int mTickIntervalPixels = TICK_INTERVAL_NO_TICK;
private int mTotalScrollPixels = 0;
@@ -68,7 +78,8 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
}
@Override
- public void onScrollProgress(int inputDeviceId, int source, int axis, int deltaInPixels) {
+ public void onScrollProgress(
+ int inputDeviceId, int source, @HapticScrollFeedbackAxis int axis, int deltaInPixels) {
maybeUpdateCurrentConfig(inputDeviceId, source, axis);
if (!mHapticScrollFeedbackEnabled) {
return;
@@ -95,7 +106,8 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
}
@Override
- public void onScrollLimit(int inputDeviceId, int source, int axis, boolean isStart) {
+ public void onScrollLimit(
+ int inputDeviceId, int source, @HapticScrollFeedbackAxis int axis, boolean isStart) {
maybeUpdateCurrentConfig(inputDeviceId, source, axis);
if (!mHapticScrollFeedbackEnabled) {
return;
@@ -112,7 +124,7 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {
}
@Override
- public void onSnapToItem(int inputDeviceId, int source, int axis) {
+ public void onSnapToItem(int inputDeviceId, int source, @HapticScrollFeedbackAxis int axis) {
maybeUpdateCurrentConfig(inputDeviceId, source, axis);
if (!mHapticScrollFeedbackEnabled) {
return;
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index cdf5eec32fec..776eeda7484e 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -18,7 +18,6 @@ package android.view;
import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
import static android.view.Display.DEFAULT_DISPLAY;
-
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
@@ -4361,6 +4360,17 @@ public final class MotionEvent extends InputEvent implements Parcelable {
public boolean isResampled;
/**
+ * Returns true if this pointer coords object was generated by resampling, rather than from
+ * an actual input event from the device at this time.
+ *
+ * @hide
+ */
+ @TestApi
+ public boolean isResampled() {
+ return isResampled;
+ }
+
+ /**
* Clears the contents of this object.
* Resets all axes to zero.
*/
diff --git a/core/java/android/view/ScrollFeedbackProvider.java b/core/java/android/view/ScrollFeedbackProvider.java
index 6f760c56e11a..78716f5646f6 100644
--- a/core/java/android/view/ScrollFeedbackProvider.java
+++ b/core/java/android/view/ScrollFeedbackProvider.java
@@ -24,120 +24,103 @@ import android.view.flags.Flags;
* Interface to represent an entity giving consistent feedback for different events surrounding view
* scroll.
*
- * <p>When you have access to the {@link MotionEvent}s that triggered the different scroll events,
- * use the {@link MotionEvent} based APIs in this class. If you do not have access to the motion
- * events, you can use the methods that accept the {@link InputDevice} ID (which can be obtained by
- * APIs like {@link MotionEvent#getDeviceId()} and {@link InputDevice#getId()}) and source (which
- * can be obtained by APIs like {@link MotionEvent#getSource()}) of the motion that caused the
- * scroll events.
+ * <p>The interface provides methods for the client to report different scroll events. The client
+ * should report all scroll events that they want to be considered for scroll feedback using the
+ * respective methods. The interface will process these events and provide scroll feedback based on
+ * its specific feedback implementation.
+ *
+ * <h3>Obtaining the correct arguments for methods in this interface</h3>
+ *
+ * <p>Methods in this interface rely on the provision of valid {@link InputDevice} ID and source, as
+ * well as the {@link MotionEvent} axis that generated a specific scroll event. The
+ * {@link InputDevice} represented by the provided ID must have a {@link InputDevice.MotionRange}
+ * with the provided source and axis. See below for more details on obtaining the right arguments
+ * for your method call.
+ *
+ * <ul>
+ *
+ * <li><p><b>inputDeviceId</b>: should always be the ID of the {@link InputDevice} that generated
+ * the scroll event. If calling this method in response to a {@link MotionEvent}, use the device ID
+ * that is reported by the event, which can be obtained using {@link MotionEvent#getDeviceId()}.
+ * Otherwise, use a valid ID that is obtained from {@link InputDevice#getId()}, or from an
+ * {@link InputManager} instance ({@link InputManager#getInputDeviceIds()} gives all the valid input
+ * device IDs).
+ *
+ * <li><p><b>source</b>: should always be the {@link InputDevice} source that generated the scroll
+ * event. Use {@link MotionEvent#getSource()} if calling this method in response to a
+ * {@link MotionEvent}. Otherwise, use a valid source for the {@link InputDevice}. You can use
+ * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
+ * {@link InputDevice}, from which you can derive all the valid sources for the device.
+ *
+ * <li><p><b>axis</b>: should always be the axis whose axis value produced the scroll event.
+ * A {@link MotionEvent} may report data for multiple axes, and each axis may have multiple data
+ * points for different pointers. Use the axis whose movement produced the specific scroll event.
+ * The motion value for an axis can be obtained using {@link MotionEvent#getAxisValue(int)}.
+ * You can use {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s
+ * for the {@link InputDevice}, from which you can derive all the valid axes for the device.
+ *
+ * </ul>
+ *
+ * <b>Note</b> that not all valid input device source and motion axis inputs are necessarily
+ * supported for scroll feedback. If you are implementing this interface, provide clear
+ * documentation in your implementation class about which input device source and motion axis are
+ * supported for your specific implementation. If you are using one of the implementations of this
+ * interface, please refer to the documentation of the implementation for details on which input
+ * device source and axis are supported.
*/
@FlaggedApi(Flags.FLAG_SCROLL_FEEDBACK_API)
public interface ScrollFeedbackProvider {
/**
- * Call this when the view has snapped to an item, with a motion generated by an
- * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on
- * a given motion event {@code axis}.
+ * Call this when the view has snapped to an item.
*
- * <p>This method has the same purpose as {@link #onSnapToItem(MotionEvent, int)}. When a scroll
- * snap happens, call either this method or {@link #onSnapToItem(MotionEvent, int)}, not both.
- * This method is useful when you have no direct access to the {@link MotionEvent} that
- * caused the snap event.
*
* @param inputDeviceId the ID of the {@link InputDevice} that generated the motion triggering
* the snap.
* @param source the input source of the motion causing the snap.
* @param axis the axis of {@code event} that caused the item to snap.
- *
- * @see #onSnapToItem(MotionEvent, int)
*/
void onSnapToItem(int inputDeviceId, int source, int axis);
/**
- * Call this when the view has snapped to an item, with a motion from a given
- * {@link MotionEvent} on a given {@code axis}.
+ * Call this when the view has reached the scroll limit.
*
- * <p>The interface is not aware of the internal scroll states of the view for which scroll
- * feedback is played. As such, the client should call
- * {@link #onScrollLimit(MotionEvent, int, int)} when scrolling has reached limit.
- *
- * @param event the {@link MotionEvent} that caused the item to snap.
- * @param axis the axis of {@code event} that caused the item to snap.
- *
- * @see #onSnapToItem(int, int, int)
- */
- default void onSnapToItem(@NonNull MotionEvent event, int axis) {
- onSnapToItem(event.getDeviceId(), event.getSource(), axis);
- }
-
- /**
- * Call this when the view has reached the scroll limit when scrolled by a motion generated by
- * an {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and
- * on a given motion event {@code axis}.
- *
- * <p>This method has the same purpose as {@link #onScrollLimit(MotionEvent, int, boolean)}.
- * When a scroll limit happens, call either this method or
- * {@link #onScrollLimit(MotionEvent, int, boolean)}, not both. This method is useful when you
- * have no direct access to the {@link MotionEvent} that caused the scroll limit.
+ * <p>Note that a feedback may not be provided on every call to this method. This interface, for
+ * instance, may provide feedback on every `N`th scroll limit event. For the interface to
+ * properly provide feedback when needed, call this method for each scroll limit event that you
+ * want to be accounted to scroll limit feedback.
*
* @param inputDeviceId the ID of the {@link InputDevice} that caused scrolling to hit limit.
* @param source the input source of the motion that caused scrolling to hit the limit.
* @param axis the axis of {@code event} that caused scrolling to hit the limit.
* @param isStart {@code true} if scrolling hit limit at the start of the scrolling list, and
* {@code false} if the scrolling hit limit at the end of the scrolling list.
- *
- * @see #onScrollLimit(MotionEvent, int, boolean)
+ * <i>start</i> and <i>end<i> in this context are not geometrical references.
+ * Instead, they refer to the start and end of a scrolling experience. As such,
+ * "start" for some views may be at the bottom of a scrolling list, while it may
+ * be at the top of scrolling list for others.
*/
void onScrollLimit(int inputDeviceId, int source, int axis, boolean isStart);
/**
- * Call this when the view has reached the scroll limit when scrolled by the motion from a given
- * {@link MotionEvent} on a given {@code axis}.
+ * Call this when the view has scrolled.
*
- * @param event the {@link MotionEvent} that caused scrolling to hit the limit.
- * @param axis the axis of {@code event} that caused scrolling to hit the limit.
- * @param isStart {@code true} if scrolling hit limit at the start of the scrolling list, and
- * {@code false} if the scrolling hit limit at the end of the scrolling list.
- *
- * @see #onScrollLimit(int, int, int, boolean)
- */
- default void onScrollLimit(@NonNull MotionEvent event, int axis, boolean isStart) {
- onScrollLimit(event.getDeviceId(), event.getSource(), axis, isStart);
- }
-
- /**
- * Call this when the view has scrolled by {@code deltaInPixels} due to the motion generated by
- * an {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and
- * on a given motion event {@code axis}.
+ * <p>Different axes have different ways to map their raw axis values to pixels for scrolling.
+ * When calling this method, use the scroll values in pixels by which the view was scrolled; do
+ * not use the raw axis values. That is, use whatever value is passed to one of View's scrolling
+ * methods (example: {@link View#scrollBy(int, int)}). For example, for vertical scrolling on
+ * {@link MotionEvent#AXIS_SCROLL}, convert the raw axis value to the equivalent pixels by using
+ * {@link ViewConfiguration#getScaledVerticalScrollFactor()}, and use that value for this method
+ * call.
*
- * <p>This method has the same purpose as {@link #onScrollProgress(MotionEvent, int, int)}.
- * When a scroll progress happens, call either this method or
- * {@link #onScrollProgress(MotionEvent, int, int)}, not both. This method is useful when you
- * have no direct access to the {@link MotionEvent} that caused the scroll progress.
+ * <p>Note that a feedback may not be provided on every call to this method. This interface, for
+ * instance, may provide feedback for every `x` pixels scrolled. For the interface to properly
+ * track scroll progress and provide feedback when needed, call this method for each scroll
+ * event that you want to be accounted to scroll feedback.
*
* @param inputDeviceId the ID of the {@link InputDevice} that caused scroll progress.
* @param source the input source of the motion that caused scroll progress.
* @param axis the axis of {@code event} that caused scroll progress.
* @param deltaInPixels the amount of scroll progress, in pixels.
- *
- * @see #onScrollProgress(MotionEvent, int, int)
*/
void onScrollProgress(int inputDeviceId, int source, int axis, int deltaInPixels);
-
- /**
- * Call this when the view has scrolled by {@code deltaInPixels} due to the motion from a given
- * {@link MotionEvent} on a given {@code axis}.
- *
- * <p>The interface is not aware of the internal scroll states of the view for which scroll
- * feedback is played. As such, the client should call
- * {@link #onScrollLimit(MotionEvent, int, int)} when scrolling has reached limit.
- *
- * @param event the {@link MotionEvent} that caused scroll progress.
- * @param axis the axis of {@code event} that caused scroll progress.
- * @param deltaInPixels the amount of scroll progress, in pixels.
- *
- * @see #onScrollProgress(int, int, int, int)
- */
- default void onScrollProgress(@NonNull MotionEvent event, int axis, int deltaInPixels) {
- onScrollProgress(event.getDeviceId(), event.getSource(), axis, deltaInPixels);
- }
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 0244d462473b..a3ae6cf20725 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -1220,36 +1220,39 @@ public class ViewConfiguration {
* Checks if any kind of scroll haptic feedback is enabled for a motion generated by a specific
* input device configuration and motion axis.
*
- * <h3>Obtaining the correct arguments for this method call</h3>
- * <p><b>inputDeviceId</b>: if calling this method in response to a {@link MotionEvent}, use
- * the device ID that is reported by the event, which can be obtained using
- * {@link MotionEvent#getDeviceId()}. Otherwise, use a valid ID that is obtained from
- * {@link InputDevice#getId()}, or from an {@link InputManager} instance
- * ({@link InputManager#getInputDeviceIds()} gives all the valid input device IDs).
+ * <p>See {@link ScrollFeedbackProvider} for details on the arguments that should be passed to
+ * the methods in this class.
*
- * <p><b>axis</b>: a {@link MotionEvent} may report data for multiple axes, and each axis may
- * have multiple data points for different pointers. Use the axis whose movement produced the
- * scrolls that would generate the scroll haptics. You can use
- * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
- * {@link InputDevice}, from which you can derive all the valid axes for the device.
+ * <p>If the provided input device ID, source, and motion axis are not supported by this Android
+ * device, this method returns {@code false}. In other words, if the {@link InputDevice}
+ * represented by the provided {code inputDeviceId} does not have a
+ * {@link InputDevice.MotionRange} with the provided {@code axis} and {@code source}, the method
+ * returns {@code false}.
*
- * <p><b>source</b>: use {@link MotionEvent#getSource()} if calling this method in response to a
- * {@link MotionEvent}. Otherwise, use a valid source for the {@link InputDevice}. You can use
- * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
- * {@link InputDevice}, from which you can derive all the valid sources for the device.
+ * <p>If the provided input device ID, source, and motion axis are supported by this Android
+ * device, this method returns {@code true} only if the provided arguments are supported for
+ * scroll haptics. Otherwise, this method returns {@code false}.
*
* @param inputDeviceId the ID of the {@link InputDevice} that generated the motion that may
* produce scroll haptics.
* @param source the input source of the motion that may produce scroll haptics.
* @param axis the axis of the motion that may produce scroll haptics.
* @return {@code true} if motions generated by the provided input and motion configuration
- * should produce scroll haptics. {@code false} otherwise.
+ * can produce scroll haptics. {@code false} otherwise.
+ *
+ * @see #getHapticScrollFeedbackTickInterval(int, int, int)
+ * @see InputDevice#getMotionRanges()
+ * @see InputDevice#getMotionRange(int)
+ * @see InputDevice#getMotionRange(int, int)
*/
@FlaggedApi(Flags.FLAG_SCROLL_FEEDBACK_API)
- public boolean isHapticScrollFeedbackEnabled(int inputDeviceId, int axis, int source) {
+ public boolean isHapticScrollFeedbackEnabled(
+ int inputDeviceId,
+ @HapticScrollFeedbackProvider.HapticScrollFeedbackAxis int axis,
+ int source) {
if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) return false;
- if (source == InputDevice.SOURCE_ROTARY_ENCODER) {
+ if (source == InputDevice.SOURCE_ROTARY_ENCODER && axis == MotionEvent.AXIS_SCROLL) {
return mRotaryEncoderHapticScrollFeedbackEnabled;
}
@@ -1285,9 +1288,14 @@ public class ViewConfiguration {
* configuration. If scroll haptics is disabled for the given configuration, or if the
* device does not support scroll tick haptics for the given configuration, this method
* returns {@code Integer.MAX_VALUE}.
+ *
+ * @see #isHapticScrollFeedbackEnabled(int, int, int)
*/
@FlaggedApi(Flags.FLAG_SCROLL_FEEDBACK_API)
- public int getHapticScrollFeedbackTickInterval(int inputDeviceId, int axis, int source) {
+ public int getHapticScrollFeedbackTickInterval(
+ int inputDeviceId,
+ @HapticScrollFeedbackProvider.HapticScrollFeedbackAxis int axis,
+ int source) {
if (!mRotaryEncoderHapticScrollFeedbackEnabled) {
return NO_HAPTIC_SCROLL_TICK_INTERVAL;
}
@@ -1296,7 +1304,7 @@ public class ViewConfiguration {
return NO_HAPTIC_SCROLL_TICK_INTERVAL;
}
- if (source == InputDevice.SOURCE_ROTARY_ENCODER) {
+ if (source == InputDevice.SOURCE_ROTARY_ENCODER && axis == MotionEvent.AXIS_SCROLL) {
return mRotaryEncoderHapticScrollFeedbackTickIntervalPixels;
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 85d7c10ef91e..fe515cd3091a 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4437,7 +4437,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @param drawingPosition the drawing order position.
* @return the container position of a child for this drawing order position.
*
- * @see #getChildDrawingOrder(int, int)}
+ * @see #getChildDrawingOrder(int, int)
*/
public final int getChildDrawingOrder(int drawingPosition) {
return getChildDrawingOrder(getChildCount(), drawingPosition);
diff --git a/core/java/android/view/inputmethod/TEST_MAPPING b/core/java/android/view/inputmethod/TEST_MAPPING
index 4b2ea1a096c8..ad59463ea1f1 100644
--- a/core/java/android/view/inputmethod/TEST_MAPPING
+++ b/core/java/android/view/inputmethod/TEST_MAPPING
@@ -11,6 +11,9 @@
},
{
"exclude-annotation": "android.platform.test.annotations.AppModeFull"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
}
]
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a1165423be8e..26ceea6d1e4c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4520,7 +4520,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (!trackMotionScroll(delta, delta)) {
if (Flags.platformWidgetHapticScrollFeedback()) {
initHapticScrollFeedbackProviderIfNotExists();
- mHapticScrollFeedbackProvider.onScrollProgress(event, axis, delta);
+ mHapticScrollFeedbackProvider.onScrollProgress(
+ event.getDeviceId(), event.getSource(), axis, delta);
}
initDifferentialFlingHelperIfNotExists();
mDifferentialMotionFlingHelper.onMotionEvent(event, axis);
@@ -4536,7 +4537,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (Flags.platformWidgetHapticScrollFeedback()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(
- event, axis, /* isStart= */ hitTopLimit);
+ event.getDeviceId(), event.getSource(), axis,
+ /* isStart= */ hitTopLimit);
}
if (hitTopLimit) {
mEdgeGlowTop.onPullDistance(overscroll, 0.5f);
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 90b077b21d85..e0e72ba1b9db 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1014,12 +1014,14 @@ public class ScrollView extends FrameLayout {
if (Flags.platformWidgetHapticScrollFeedback()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(
- event, axis, /* isStart= */ newScrollY == 0);
+ event.getDeviceId(), event.getSource(), axis,
+ /* isStart= */ newScrollY == 0);
}
} else {
if (Flags.platformWidgetHapticScrollFeedback()) {
initHapticScrollFeedbackProviderIfNotExists();
- mHapticScrollFeedbackProvider.onScrollProgress(event, axis, delta);
+ mHapticScrollFeedbackProvider.onScrollProgress(
+ event.getDeviceId(), event.getSource(), axis, delta);
}
initDifferentialFlingHelperIfNotExists();
mDifferentialMotionFlingHelper.onMotionEvent(event, axis);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 59344b00e79a..05063365561f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -15143,6 +15143,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final ClipDescription description =
getClipboardManagerForUser().getPrimaryClipDescription();
+ if (description == null) {
+ return false;
+ }
final boolean isPlainType = description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
return (isPlainType && description.isStyledText())
|| description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML);
diff --git a/core/java/android/widget/inline/TEST_MAPPING b/core/java/android/widget/inline/TEST_MAPPING
index 26a556906dd1..82c6f61c3486 100644
--- a/core/java/android/widget/inline/TEST_MAPPING
+++ b/core/java/android/widget/inline/TEST_MAPPING
@@ -8,6 +8,9 @@
},
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
}
]
}
diff --git a/core/java/android/window/SnapshotDrawerUtils.java b/core/java/android/window/SnapshotDrawerUtils.java
index f40874b77536..758582615a46 100644
--- a/core/java/android/window/SnapshotDrawerUtils.java
+++ b/core/java/android/window/SnapshotDrawerUtils.java
@@ -237,13 +237,14 @@ public class SnapshotDrawerUtils {
PixelFormat.RGBA_8888,
GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER
| GraphicBuffer.USAGE_SW_WRITE_RARELY);
- if (background == null) {
+ final Canvas c = background != null ? background.lockCanvas() : null;
+ if (c == null) {
Log.e(TAG, "Unable to draw snapshot: failed to allocate graphic buffer for "
+ mTitle);
+ mTransaction.clear();
+ childSurfaceControl.release();
return;
}
- // TODO: Support this on HardwareBuffer
- final Canvas c = background.lockCanvas();
drawBackgroundAndBars(c, frame);
background.unlockCanvasAndPost(c);
mTransaction.setBuffer(mRootSurface,
diff --git a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
deleted file mode 100644
index f1d981ac5b4b..000000000000
--- a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-package: "com.android.window.flags"
-
-flag {
- name: "letterbox_background_wallpaper_flag"
- namespace: "large_screen_experiences_app_compat"
- description: "Whether the letterbox wallpaper style is enabled by default"
- bug: "297195682"
-}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
new file mode 100644
index 000000000000..7a4c5bc669fc
--- /dev/null
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.window.flags"
+
+flag {
+ name: "nav_bar_transparent_by_default"
+ namespace: "windowing_frontend"
+ description: "Make nav bar color transparent by default when targeting SDK 35 or greater"
+ bug: "232195501"
+}
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index b9f02365bbe7..d2fdc65b2c36 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -61,6 +61,8 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
private final ModelBuilder mModelBuilder;
private ResolverComparatorModel mComparatorModel;
+ private ResolverAppPredictorCallback mSortingCallback;
+
// If this is non-null (and this is not destroyed), it means APS is disabled and we should fall
// back to using the ResolverRankerService.
// TODO: responsibility for this fallback behavior can live outside of the AppPrediction client.
@@ -94,6 +96,9 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
// TODO: may not be necessary to build a new model, since we're destroying anyways.
mComparatorModel = mModelBuilder.buildFallbackModel(mResolverRankerService);
}
+ if (mSortingCallback != null) {
+ mSortingCallback.destroy();
+ }
}
@Override
@@ -140,22 +145,27 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
.setClassName(target.name.getClassName())
.build());
}
+
+ if (mSortingCallback != null) {
+ mSortingCallback.destroy();
+ }
+ mSortingCallback = new ResolverAppPredictorCallback(sortedAppTargets -> {
+ if (sortedAppTargets.isEmpty()) {
+ Log.i(TAG, "AppPredictionService disabled. Using resolver.");
+ setupFallbackModel(targets);
+ } else {
+ Log.i(TAG, "AppPredictionService response received");
+ // Skip sending to Handler which takes extra time to dispatch messages.
+ // TODO: the Handler guards some concurrency conditions, so this could
+ // probably result in a race (we're not currently on the Handler thread?).
+ // We'll leave this as-is since we intend to remove the Handler design
+ // shortly, but this is still an unsound shortcut.
+ handleResult(sortedAppTargets);
+ }
+ });
+
mAppPredictor.sortTargets(appTargets, Executors.newSingleThreadExecutor(),
- sortedAppTargets -> {
- if (sortedAppTargets.isEmpty()) {
- Log.i(TAG, "AppPredictionService disabled. Using resolver.");
- setupFallbackModel(targets);
- } else {
- Log.i(TAG, "AppPredictionService response received");
- // Skip sending to Handler which takes extra time to dispatch messages.
- // TODO: the Handler guards some concurrency conditions, so this could
- // probably result in a race (we're not currently on the Handler thread?).
- // We'll leave this as-is since we intend to remove the Handler design
- // shortly, but this is still an unsound shortcut.
- handleResult(sortedAppTargets);
- }
- }
- );
+ mSortingCallback.asConsumer());
}
private void setupFallbackModel(List<ResolvedComponentInfo> targets) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 2b39bb4eb7a5..6d8512c9d07c 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -24,9 +24,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROS
import static android.content.ContentProvider.getUserIdFromUri;
import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL;
import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK;
-
import static com.android.internal.util.LatencyTracker.ACTION_LOAD_SHARE_SHEET;
-
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.animation.Animator;
@@ -777,9 +775,9 @@ public class ChooserActivity extends ResolverActivity implements
return appPredictor;
}
- private AppPredictor.Callback createAppPredictorCallback(
+ private ResolverAppPredictorCallback createAppPredictorCallback(
ChooserListAdapter chooserListAdapter) {
- return resultList -> {
+ return new ResolverAppPredictorCallback(resultList -> {
if (isFinishing() || isDestroyed()) {
return;
}
@@ -811,7 +809,7 @@ public class ChooserActivity extends ResolverActivity implements
}
sendShareShortcutInfoList(shareShortcutInfos, chooserListAdapter, resultList,
chooserListAdapter.getUserHandle());
- };
+ });
}
static SharedPreferences getPinnedSharedPrefs(Context context) {
@@ -2559,10 +2557,13 @@ public class ChooserActivity extends ResolverActivity implements
boolean filterLastUsed, UserHandle userHandle) {
ChooserListAdapter chooserListAdapter = createChooserListAdapter(context, payloadIntents,
initialIntents, rList, filterLastUsed, userHandle);
- AppPredictor.Callback appPredictorCallback = createAppPredictorCallback(chooserListAdapter);
+ ResolverAppPredictorCallback appPredictorCallbackWrapper =
+ createAppPredictorCallback(chooserListAdapter);
+ AppPredictor.Callback appPredictorCallback = appPredictorCallbackWrapper.asCallback();
AppPredictor appPredictor = setupAppPredictorForUser(userHandle, appPredictorCallback);
chooserListAdapter.setAppPredictor(appPredictor);
- chooserListAdapter.setAppPredictorCallback(appPredictorCallback);
+ chooserListAdapter.setAppPredictorCallback(
+ appPredictorCallback, appPredictorCallbackWrapper);
return new ChooserGridAdapter(chooserListAdapter);
}
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index 1eecb413adcb..f77e71863125 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -103,6 +103,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
// Sorted list of DisplayResolveInfos for the alphabetical app section.
private List<DisplayResolveInfo> mSortedList = new ArrayList<>();
private AppPredictor mAppPredictor;
+ private ResolverAppPredictorCallback mAppPredictorCallbackWrapper;
private AppPredictor.Callback mAppPredictorCallback;
// Represents the UserSpace in which the Initial Intents should be resolved.
@@ -747,8 +748,11 @@ public class ChooserListAdapter extends ResolverListAdapter {
mAppPredictor = appPredictor;
}
- public void setAppPredictorCallback(AppPredictor.Callback appPredictorCallback) {
+ public void setAppPredictorCallback(
+ AppPredictor.Callback appPredictorCallback,
+ ResolverAppPredictorCallback appPredictorCallbackWrapper) {
mAppPredictorCallback = appPredictorCallback;
+ mAppPredictorCallbackWrapper = appPredictorCallbackWrapper;
}
public void destroyAppPredictor() {
@@ -757,6 +761,10 @@ public class ChooserListAdapter extends ResolverListAdapter {
getAppPredictor().destroy();
setAppPredictor(null);
}
+
+ if (mAppPredictorCallbackWrapper != null) {
+ mAppPredictorCallbackWrapper.destroy();
+ }
}
/**
diff --git a/core/java/com/android/internal/app/ResolverAppPredictorCallback.java b/core/java/com/android/internal/app/ResolverAppPredictorCallback.java
new file mode 100644
index 000000000000..c35e536275f0
--- /dev/null
+++ b/core/java/com/android/internal/app/ResolverAppPredictorCallback.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.app;
+
+import android.app.prediction.AppPredictor;
+import android.app.prediction.AppTarget;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+/**
+ * Callback wrapper that works around potential memory leaks in app predictor.
+ *
+ * Nulls the callback itself when destroyed, so at worst you'll leak just this object.
+ */
+public class ResolverAppPredictorCallback {
+ private volatile Consumer<List<AppTarget>> mCallback;
+
+ public ResolverAppPredictorCallback(Consumer<List<AppTarget>> callback) {
+ mCallback = callback;
+ }
+
+ private void notifyCallback(List<AppTarget> list) {
+ Consumer<List<AppTarget>> callback = mCallback;
+ if (callback != null) {
+ callback.accept(Objects.requireNonNullElseGet(list, List::of));
+ }
+ }
+
+ public Consumer<List<AppTarget>> asConsumer() {
+ return this::notifyCallback;
+ }
+
+ public AppPredictor.Callback asCallback() {
+ return this::notifyCallback;
+ }
+
+ public void destroy() {
+ mCallback = null;
+ }
+}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 3e16df4d7f67..1be916f44f5b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1160,7 +1160,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
mForceWindowDrawsBarBackgrounds, requestedVisibleTypes);
boolean oldDrawLegacy = mDrawLegacyNavigationBarBackground;
mDrawLegacyNavigationBarBackground =
- (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
+ ((requestedVisibleTypes | mLastForceConsumingTypes)
+ & WindowInsets.Type.navigationBars()) != 0
+ && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
if (oldDrawLegacy != mDrawLegacyNavigationBarBackground) {
mDrawLegacyNavigationBarBackgroundHandled =
mWindow.onDrawLegacyNavigationBarBackgroundChanged(
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 483a184a7ba2..8f4df806296e 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -1304,8 +1304,9 @@ public class TransitionAnimation {
t.setBuffer(layer, buffer.getHardwareBuffer());
t.setDataSpace(layer, buffer.getColorSpace().getDataSpace());
// Avoid showing dimming effect for HDR content when running animations.
- // TODO(b/298219334): Only do this if we know we already dimmed in the screenshot
- t.setDimmingEnabled(layer, false);
+ if (buffer.containsHdrLayers()) {
+ t.setDimmingEnabled(layer, false);
+ }
}
/** Returns whether the hardware buffer passed in is marked as protected. */
diff --git a/core/java/com/android/internal/usb/DumpUtils.java b/core/java/com/android/internal/usb/DumpUtils.java
index f974d9d10efd..21c3e7b5c6b8 100644
--- a/core/java/com/android/internal/usb/DumpUtils.java
+++ b/core/java/com/android/internal/usb/DumpUtils.java
@@ -16,6 +16,7 @@
package com.android.internal.usb;
+import static android.hardware.usb.UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT;
import static android.hardware.usb.UsbPortStatus.MODE_AUDIO_ACCESSORY;
import static android.hardware.usb.UsbPortStatus.MODE_DEBUG_ACCESSORY;
import static android.hardware.usb.UsbPortStatus.MODE_DFP;
@@ -26,6 +27,7 @@ import static android.hardware.usb.UsbPortStatus.MODE_UFP;
import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull;
import android.annotation.NonNull;
+import android.hardware.usb.DisplayPortAltModeInfo;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbConfiguration;
import android.hardware.usb.UsbDevice;
@@ -177,6 +179,10 @@ public class DumpUtils {
dump.write("supports_compliance_warnings",
UsbPortProto.SUPPORTS_COMPLIANCE_WARNINGS,
port.supportsComplianceWarnings());
+ if (port.isAltModeSupported(FLAG_ALT_MODE_TYPE_DISPLAYPORT)) {
+ dump.write("supported_alt_modes", UsbPortProto.SUPPORTED_ALT_MODES,
+ FLAG_ALT_MODE_TYPE_DISPLAYPORT);
+ }
dump.end(token);
}
@@ -255,6 +261,12 @@ public class DumpUtils {
UsbPort.powerBrickConnectionStatusToString(status.getPowerBrickConnectionStatus()));
dump.write("compliance_warning_status", UsbPortStatusProto.COMPLIANCE_WARNINGS_STRING,
UsbPort.complianceWarningsToString(status.getComplianceWarnings()));
+ DisplayPortAltModeInfo displayPortAltModeInfo = status.getDisplayPortAltModeInfo();
+ if (displayPortAltModeInfo != null) {
+ dump.write("displayport_alt_mode_status",
+ UsbPortStatusProto.DISPLAYPORT_ALT_MODE_STATUS,
+ status.getDisplayPortAltModeInfo().toString());
+ }
dump.end(token);
}
}
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
index 279a5d0c17f8..b9905e8cf446 100644
--- a/core/proto/android/content/package_item_info.proto
+++ b/core/proto/android/content/package_item_info.proto
@@ -30,6 +30,7 @@ message PackageItemInfoProto {
optional string non_localized_label = 4;
optional int32 icon = 5;
optional int32 banner = 6;
+ optional bool is_archived = 7;
}
// Proto of android.content.pm.ApplicationInfo which extends PackageItemInfo
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index 88893205c79e..49b8450fcc67 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -238,10 +238,15 @@ message UsbPortProto {
MODE_DEBUG_ACCESSORY = 8;
}
+ enum AltMode {
+ ALT_MODE_DISPLAYPORT = 1;
+ }
+
// ID of the port. A device (eg: Chromebooks) might have multiple ports.
optional string id = 1;
repeated Mode supported_modes = 2;
optional bool supports_compliance_warnings = 3;
+ repeated AltMode supported_alt_modes = 4;
}
message UsbPortStatusProto {
@@ -271,6 +276,7 @@ message UsbPortStatusProto {
optional bool is_power_transfer_limited = 8;
optional string usb_power_brick_status = 9;
optional string compliance_warnings_string = 10;
+ optional string displayport_alt_mode_status = 11;
}
message UsbPortStatusRoleCombinationProto {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3180ffbef79d..c09f0a3ed624 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1699,6 +1699,15 @@
android:description="@string/permdesc_cameraOpenCloseListener"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows camera access by Headless System User 0 when device is running in
+ HSUM Mode.
+ @hide -->
+ <permission android:name="android.permission.CAMERA_HEADLESS_SYSTEM_USER"
+ android:permissionGroup="android.permission-group.UNDEFINED"
+ android:label="@string/permlab_cameraHeadlessSystemUser"
+ android:description="@string/permdesc_cameraHeadlessSystemUser"
+ android:protectionLevel="signature" />
+
<!-- ====================================================================== -->
<!-- Permissions for accessing the device sensors -->
<!-- ====================================================================== -->
@@ -7654,6 +7663,10 @@
<permission android:name="android.permission.DELETE_STAGED_HEALTH_CONNECT_REMOTE_DATA"
android:protectionLevel="signature" />
+ <!-- @hide @TestApi Allows tests running in CTS-in-sandbox mode to launch activities -->
+ <permission android:name="android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Allows the holder to call health connect migration APIs.
@hide -->
<permission android:name="android.permission.MIGRATE_HEALTH_CONNECT_DATA"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8109e9ab4cae..8ffdba3e3f92 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2ኛ ሥራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3ኛ ሥራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ን አባዛ"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"የግል <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ከመንቀል በፊት ፒን ጠይቅ"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ስርዓተ-ጥለት ጠይቅ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index f2aee4063cc9..0ca9ea235be8 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"২য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"৩য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"ক্ল’ন <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"ব্যক্তিগত <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"আনপিন কৰাৰ পূৰ্বে পিন দিবলৈ কওক"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন কৰাৰ পূৰ্বে আনলক আৰ্হি দিবলৈ কওক"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন কৰাৰ পূৰ্বে পাছৱৰ্ড দিবলৈ কওক"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 592c3440c7e1..74ba52da3518 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -807,7 +807,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Dozvoljava vlasniku da ažurira aplikaciju koju je prethodno instalirala bez radnji korisnika"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Podešavanje pravila za lozinku"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadgledajte pokušaje otključavanja ekrana"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadzor pokušaja otključavanja ekrana"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke sa Android TV uređaja ako se unese previše netačnih lozinki."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netačno unetih lozinki pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke sa sistema za info-zabavu ako je netačna lozinka uneta previše puta."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4cd8aa589d65..3a79090ebf1c 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -812,7 +812,7 @@
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць планшэт або сціраць усе дадзеныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і заблакіраваць прыладу Android TV або сцерці ўсе даныя на прыладзе, калі няправільны пароль набраны занадта шмат разоў."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Падчас разблакіроўкі экрана сачыць за колькасцю няправільна набраных пароляў і, калі няправільны пароль набраны занадта шмат разоў, заблакіраваць інфармацыйна-забаўляльную сістэму ці сцерці ў ёй усе даныя."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць тяэлефон або сціраць усе дадзеныя на ім, калі набрана занадта шмат няправільных пароляў."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і блакіраваць тэлефон або сціраць усе даныя на ім, калі набрана занадта шмат няправільных пароляў."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і блакіраваць планшэт або сцерці ўсе даныя гэтага карыстальніка, калі няправільны пароль набраны занадта шмат разоў."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Сачыць за колькасцю няправільна набраных пароляў падчас разблакіроўкі экрана і заблакіраваць прыладу Android TV або сцерці ўсе даныя карыстальніка, калі няправільны пароль набраны занадта шмат разоў."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Падчас разблакіроўкі экрана сачыць за колькасцю няправільна набраных пароляў і, калі няправільны пароль набраны занадта шмат разоў, заблакіраваць інфармацыйна-забаўляльную сістэму ці сцерці ўсе даныя гэтага профілю."</string>
@@ -1869,8 +1869,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Другая праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трэцяя праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Кланіраваць \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> (прыватны профіль)"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запытваць PIN-код перад адмацаваннем"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запытваць пароль перад адмацаваннем"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 1d1e29c9d517..f6f5b0eb38ad 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"দ্বিতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"তৃতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ক্লোন"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"ব্যক্তিগত <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"আনপিন করার আগে পিন চান"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 5ec91f5ebce8..010e22ce781d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1868,8 +1868,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2n <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3r <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privat"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sol·licita el PIN per deixar de fixar"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string>
@@ -1891,8 +1890,8 @@
<string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Durant 1 hora}many{Durant # hores}other{Durant # hores}}"</string>
<string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Durant 1 h}many{Durant # h}other{Durant # h}}"</string>
<string name="zen_mode_until_next_day" msgid="1403042784161725038">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <string name="zen_mode_until" msgid="2250286190237669079">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <string name="zen_mode_alarm" msgid="7046911727540499275">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string>
+ <string name="zen_mode_until" msgid="2250286190237669079">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="7046911727540499275">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string>
<string name="zen_mode_forever" msgid="740585666364912448">"Fins que no el desactivis"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Fins que desactivis el mode No molestis"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ca2206c9be1d..e816391f44b4 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -672,12 +672,12 @@
<string name="device_unlock_notification_name" msgid="2632928999862915709">"Enhedsoplåsning"</string>
<string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Prøv en anden metode til oplåsning"</string>
<string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Brug ansigtsoplåsning, hvis dit fingeraftryk ikke genkendes, f.eks. når du har våde fingre"</string>
- <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Brug oplåsning med fingeraftryk, hvis dit ansigt ikke genkendes, f.eks. når der ikke er nok lys"</string>
+ <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Brug fingeroplåsning, hvis dit ansigt ikke genkendes, f.eks. når der ikke er nok lys"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ansigtsoplåsning"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Der er et problem med Ansigtsoplåsning"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tryk for at slette din ansigtsmodel, og tilføj derefter dit ansigt igen"</string>
<string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Hvis du vil bruge ansigtsoplåsning, skal du aktivere "<b>"Kameraadgang"</b>" under Indstillinger &gt; Privatliv"</string>
- <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Oplåsning med fingeraftryk"</string>
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingeroplåsning"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Fingeraftrykssensoren kan ikke bruges"</string>
<string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Få den repareret."</string>
<string name="face_acquired_insufficient" msgid="6889245852748492218">"Din ansigtsmodel kan ikke oprettes. Prøv igen."</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> til arbejde"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> til arbejde"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon af <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> (privat)"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Bed om pinkode inden frigørelse"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Bed om oplåsningsmønster ved deaktivering"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bed om adgangskode inden frigørelse"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index be511e8a7c32..3f960f70a800 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> (privat)"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vor dem Beenden nach PIN fragen"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vor dem Beenden nach Entsperrungsmuster fragen"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vor dem Beenden nach Passwort fragen"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index e0aeb31e721d..e61fe1a36211 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -672,8 +672,8 @@
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícono de huella dactilar"</string>
<string name="device_unlock_notification_name" msgid="2632928999862915709">"Desbloqueo del dispositivo"</string>
<string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Prueba otra forma para desbloquear el dispositivo"</string>
- <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Usa la función de Desbloqueo facial cuando no se reconoce tu huella dactilar (por ejemplo cuando tienes los dedos mojados)"</string>
- <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Usa la función de Desbloqueo facial cuando no se reconoce tu rostro (por ejemplo cuando no hay suficiente luz)"</string>
+ <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Usa el Desbloqueo facial si no se reconoce tu huella dactilar (p. ej., si tienes los dedos mojados)"</string>
+ <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Usa el Desbloqueo con huellas dactilares si no se reconoce tu rostro (p. ej., si hay poca luz)"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueo facial"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con el Desbloqueo facial"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Presiona para borrar el modelo de rostro y, luego, vuelve a agregar tu rostro"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 3bcc0f432a88..cbcf40306bd6 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -672,8 +672,8 @@
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icono de huella digital"</string>
<string name="device_unlock_notification_name" msgid="2632928999862915709">"Desbloqueo del dispositivo"</string>
<string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Prueba otro método de desbloqueo"</string>
- <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Usa Desbloqueo facial cuando no se reconozca tu huella digital (por ejemplo, cuando tus dedos estén húmedos)"</string>
- <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Usa Desbloqueo con huella digital cuando no se reconozca tu cara (por ejemplo, cuando no haya suficiente luz)"</string>
+ <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Usa Desbloqueo facial cuando no se reconozca tu huella (p. ej., si tienes los dedos mojados)"</string>
+ <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Usa Desbloqueo con huella digital cuando no se reconozca tu cara (p. ej., si hay poca luz)"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueo facial"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con Desbloqueo facial"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toca para eliminar tu modelo facial y luego añade de nuevo tu cara"</string>
@@ -1868,8 +1868,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 2"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 3"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privado"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicitar PIN para desactivar"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir patrón de desbloqueo para dejar de fijar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para desactivar"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index d212946da95e..22600e527270 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -823,7 +823,7 @@
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Kustutage tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Kustutatakse teie Android TV seadme andmed ilma hoiatamata, lähtestades seadme tehase andmetele."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Teabe ja meelelahutuse süsteemi andmete hoiatamata kustutamine tehase andmetele lähtestamise abil."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Telefoniandmete hoiatuseta kustutamine, lähtestades telefoni tehaseseadetele."</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Kustutab telefoniandmed hoiatuseta, lähtestades telefoni tehaseseadetele."</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Profiili andmete kustutamine"</string>
<string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Kasutaja andmete kustutamine"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Kustutatakse selle kasutaja andmed sellest tahvelarvutist ilma hoiatamata."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 302acb04d085..019296d2bec0 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Laneko 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Laneko 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> aplikazioaren klona"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> pribatua"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Eskatu PINa aingura kendu aurretik"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Eskatu pasahitza aingura kendu aurretik"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7947b6ea6e8b..6210b62a2915 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"کار دوم <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"کار سوم <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"همسانه <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"«<xliff:g id="LABEL">%1$s</xliff:g>» خصوصی"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"درخواست کد پین قبل از برداشتن پین"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"درخواست الگوی بازگشایی قفل قبل‌از برداشتن سنجاق"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"درخواست گذرواژه قبل از برداشتن سنجاق"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3b5c86e9f37d..ef09aee19b31 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Toinen <xliff:g id="LABEL">%1$s</xliff:g>, työ"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Kolmas <xliff:g id="LABEL">%1$s</xliff:g>, työ"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloonaa <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Yksityinen <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pyydä PIN ennen irrotusta"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 782ccd0e45ce..d38f65651bba 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -319,7 +319,7 @@
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accéder à vos activités physiques"</string>
- <string name="permgrouplab_camera" msgid="9090413408963547706">"appareil photo"</string>
+ <string name="permgrouplab_camera" msgid="9090413408963547706">"Appareil photo"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"prendre des photos et filmer des vidéos"</string>
<string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Appareils à proximité"</string>
<string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"découvrir les appareils à proximité et s\'y connecter"</string>
@@ -672,8 +672,8 @@
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string>
<string name="device_unlock_notification_name" msgid="2632928999862915709">"Déverrouillage de l\'appareil"</string>
<string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Essayez une autre façon de déverrouiller"</string>
- <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Utilisez Déverrouillage par reconnaissance faciale lorsque votre empreinte digitale n\'est pas reconnue, par exemple lorsque vos doigts sont mouillés"</string>
- <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Utilisez Déverrouillage par empreinte digitale lorsque votre visage n\'est pas reconnu, par exemple lorsque la luminosité est insuffisante"</string>
+ <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Utilisez le Déverrouillage par reconnaissance faciale lorsque votre empreinte digitale n\'est pas reconnue, par exemple lorsque vos doigts sont mouillés"</string>
+ <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Utilisez le Déverrouillage par empreinte digitale lorsque votre visage n\'est pas reconnu, par exemple lorsque la luminosité est insuffisante"</string>
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Déverrouillage par reconnaissance faciale"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problème avec la fonctionnalité de déverrouillage par reconnaissance faciale"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Touchez pour supprimer votre modèle facial, puis ajoutez votre visage de nouveau"</string>
@@ -811,7 +811,7 @@
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouiller la tablette ou effacer toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Surveillez le nombre de mots de passe incorrects entrés lors du déverrouillage de l\'écran et verrouillez votre appareil Android TV ou effacez toutes les données qu\'il contient en cas d\'un nombre trop élevé de tentatives."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Surveillez le nombre de mots de passe incorrects entrés lors du déverrouillage de l\'écran et verrouillez le système d\'infodivertissement ou effacez toutes ses données en cas d\'un nombre trop élevé de tentatives."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouille le téléphone ou efface toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran est contrôlé. Si le nombre maximal de tentatives de saisie du mot de passe est atteint, le téléphone est verrouillé ou toutes ses données sont effacées."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Surveille le nombre de mots de passe incorrects entrés lors du déverrouillage de l\'écran et verrouille la tablette ou efface toutes les données de l\'utilisateur en cas d\'un nombre trop élevé de tentatives."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Surveillez le nombre de mots de passe incorrects entrés lors du déverrouillage de l\'écran et verrouillez votre appareil Android TV ou effacez toutes les données de l\'utilisateur en cas d\'un nombre trop élevé de tentatives."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Surveillez le nombre de mots de passe incorrects entrés lors du déverrouillage de l\'écran et verrouillez le système d\'infodivertissement ou effacez toutes les données de ce profil en cas d\'un nombre trop élevé de tentatives."</string>
@@ -824,7 +824,7 @@
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Effacer les données de la tablette sans avertissement, en rétablissant les paramètres par défaut"</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Effacez les données de votre appareil Android TV sans avertissement en effectuant une réinitialisation des paramètres d\'usine."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Effacez les données du système d\'infodivertissement sans avertissement en rétablissant les paramètres par défaut."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Effacer les données du téléphone sans avertissement en rétablissant les paramètres par défaut."</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Les données du téléphone sont effacées sans avertissement en rétablissant les paramètres par défaut."</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Effacer les données de profil"</string>
<string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Effacer les données de l\'utilisateur"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Effacer les données de l\'utilisateur sur cette tablette sans avertissement."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index b5ea2e2d8681..1049d49468f4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1868,8 +1868,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g> professionnelle"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g> professionnelle"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Cloner <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privé"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le code avant de retirer l\'épingle"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string>
@@ -2132,7 +2131,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Le Bluetooth restera activé en mode Avion"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Chargement…"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fichier}one{{file_name} + # fichier}many{{file_name} + # fichiers}other{{file_name} + # fichiers}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucun destinataire recommandé"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applications"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette application n\'a pas reçu l\'autorisation d\'enregistrer des contenus audio, mais peut le faire via ce périphérique USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Accueil"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ea3f104d0d12..1b8a8fd9ec58 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2.º <xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3.º <xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonar <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privado"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de soltar a fixación"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrón de desbloqueo antes de soltar a fixación"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir contrasinal antes de soltar a fixación"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 0a42b241e255..9ad7ff19b712 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ની ક્લોન"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"ખાનગી <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"અનપિન કરતા પહેલાં પિન માટે પૂછો"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 8a383a1bd5e2..2cd150963695 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -806,11 +806,11 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"इससे होल्डर उस ऐप्लिकेशन को अपने-आप अपडेट कर पाएगा जो उसने पहले इंस्टॉल किया था"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करना"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"स्‍क्रीन लॉक पासवर्ड और पिन की लंबाई और उनमें स्वीकृत वर्णों को नियंत्रित करना."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"स्‍क्रीन अनलॉक करने के की कोशिशों पर नज़र रखना"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"स्‍क्रीन अनलॉक करने की कोशिशों पर नज़र रखना"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"स्‍क्रीन को अनलॉक करते समय गलत लिखे गए पासवर्ड की संख्‍या पर निगरानी करें, और बहुत ज़्यादा बार गलत पासवर्ड लिखे जाने पर टैबलेट लॉक करें या टैबलेट का संपूर्ण डेटा मिटाएं."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रीन को अनलॉक करते समय ध्यान रखें कि कितनी बार गलत पासवर्ड डाला गया है. अगर बहुत ज़्यादा बार गलत पासवर्ड डाला गया है, तो अपने Android TV डिवाइस को तुरंत लॉक करें या इसका सभी डेटा मिटाएं."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"स्क्रीन को अनलॉक करते समय ध्यान रखें कि कितनी बार गलत पासवर्ड डाला गया है. अगर बहुत ज़्यादा बार गलत पासवर्ड डाला गया है, तो सूचना और मनोरंजन की सुविधा देने वाले डिवाइस को लॉक करें या इस डिवाइस का सारा डेटा मिटाएं."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"स्क्रीन को अनलॉक करते समय जितनी बार गलत पासवर्ड लिखा गया है, उसकी संख्या पर नज़र रखना और अगर बहुत बार गलत पासवर्ड डाले गए हैं, तो फ़ोन को लॉक कर देना या फ़ोन का सारा डेटा मिटा देना."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"स्क्रीन को अनलॉक करते समय ध्यान रखें कि कितनी बार गलत पासवर्ड डाला गया है. अगर बहुत ज़्यादा बार गलत पासवर्ड डाला गया है, तो अपने फ़ोन को तुरंत लॉक करें या फ़ोन का सारा डेटा मिटा दें."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"स्‍क्रीन का लॉक खोलते समय गलत तरीके से लिखे गए पासवर्ड पर नज़र रखें, और अगर बार-बार ज़्यादा पासवर्ड लिखे जाते हैं तो टैबलेट को लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटा दें."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"स्क्रीन को अनलॉक करते समय ध्यान रखें कि कितनी बार गलत पासवर्ड डाला गया है. अगर बहुत ज़्यादा बार गलत पासवर्ड डाला गया है, तो अपने Android TV डिवाइस को तुरंत लॉक करें या इस उपयोगकर्ता का सभी डेटा मिटाएं."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"स्क्रीन को अनलॉक करते समय ध्यान रखें कि कितनी बार गलत पासवर्ड डाला गया है. अगर बहुत ज़्यादा बार गलत पासवर्ड डाला गया है, तो सूचना और मनोरंजन की सुविधा देने वाले डिवाइस को लॉक करें या इस प्रोफ़ाइल का सारा डेटा मिटाएं."</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"दूसरा काम <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"तीसरा काम <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> का क्लोन"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"निजी <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करने से पहले पिन के लिए पूछें"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index d7f5b4ac1b00..4a9dbf534771 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -807,7 +807,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Nositelju omogućuje ažuriranje aplikacije koju je prethodno instalirao bez radnje korisnika"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Postavi pravila zaporke"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Upravlja duljinom i znakovima koji su dopušteni u zaporkama i PIN-ovima zaključavanja zaslona."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadziri pokušaje otključavanja zaslona"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadzor pokušaja otključavanja zaslona"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Nadziri broj netočnih zaporki unesenih pri otključavanju zaslona i zaključaj tabletno računalo ili izbriši sve podatke na njemu ako je uneseno previše netočnih zaporki."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Prati broj netočnih zaporki unesenih prilikom otključavanja zaslona i zaključava Android TV uređaj ili s njega briše sve podatke ako se unese previše netočnih zaporki."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netočnih zaporki unesenih prilikom otključavanja zaslona i zaključava sustav za informiranje i zabavu ili briše sve njegove podatke ako se unese previše netočnih zaporki."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 59827cb558b8..9190a6382c4b 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>-ի կլոն"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Անձնական <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Հարցնել PIN կոդը"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Հարցնել ապակողպող նախշը"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Հարցնել գաղտնաբառը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 8603809903ae..3417c2af249f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -806,7 +806,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Mengizinkan pemegang mengupdate aplikasi yang sebelumnya diinstal tanpa tindakan pengguna"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Setel aturan sandi"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Pantau upaya pembukaan kunci layar"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Memantau upaya pembukaan kunci layar"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci tablet atau menghapus semua data tablet jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Memantau banyaknya sandi salah yang diketikkan saat membuka kunci layar, dan mengunci perangkat Android TV atau menghapus semua data perangkat Android TV jika terlalu banyak sandi salah diketikkan."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci sistem infotainmen atau menghapus semua data sistem infotainmen jika terlalu banyak kesalahan memasukkan sandi."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 7420a2511960..7b2bf029a23a 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu (2)"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu (3)"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Afrit af <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Lokað: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Biðja um PIN-númer til að losa"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Biðja um opnunarmynstur til að losa"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Biðja um aðgangsorð til að losa"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 168a1613fde6..b0bde08f0b42 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -672,13 +672,13 @@
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona dell\'impronta"</string>
<string name="device_unlock_notification_name" msgid="2632928999862915709">"Sblocco dispositivo"</string>
<string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Prova un\'altra modalità di sblocco"</string>
- <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Usa lo sblocco con il volto se la tua impronta non viene riconosciuta, ad esempio quando hai le dita bagnate"</string>
- <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Usa lo sblocco con l\'impronta se il tuo volto non viene riconosciuto, ad esempio quando non c\'è abbastanza luce"</string>
- <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Sblocco con il volto"</string>
- <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con Sblocco con il volto"</string>
+ <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Usa lo Sblocco con il Volto se la tua impronta non viene riconosciuta, ad esempio se hai le dita bagnate"</string>
+ <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Usa lo Sblocco con l\'Impronta se il tuo volto non viene riconosciuto, ad esempio se non c\'è abbastanza luce"</string>
+ <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Sblocco con il Volto"</string>
+ <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con Sblocco con il Volto"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tocca per eliminare il tuo modello del volto e poi riaggiungi il tuo volto"</string>
- <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Per utilizzare lo sblocco con il volto, attiva "<b>"l\'accesso alla fotocamera"</b>" in Impostazioni &gt; Privacy"</string>
- <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Sblocco con l\'impronta"</string>
+ <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Per utilizzare lo Sblocco con il Volto, attiva "<b>"l\'accesso alla fotocamera"</b>" in Impostazioni &gt; Privacy"</string>
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Sblocco con l\'Impronta"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Impossibile utilizzare il sensore di impronte digitali"</string>
<string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Contatta un fornitore di servizi di riparazione."</string>
<string name="face_acquired_insufficient" msgid="6889245852748492218">"Impossibile creare il modello del volto. Riprova."</string>
@@ -711,20 +711,20 @@
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Imposs. verificare volto. Hardware non disponibile."</string>
- <string name="face_error_timeout" msgid="2598544068593889762">"Riprova lo sblocco con il volto"</string>
+ <string name="face_error_timeout" msgid="2598544068593889762">"Riprova lo Sblocco con il Volto"</string>
<string name="face_error_no_space" msgid="5649264057026021723">"Imposs. salvare dati nuovi volti. Elimina un volto vecchio."</string>
<string name="face_error_canceled" msgid="2164434737103802131">"Operazione associata al volto annullata."</string>
- <string name="face_error_user_canceled" msgid="5766472033202928373">"Sblocco con il volto annullato dall\'utente"</string>
+ <string name="face_error_user_canceled" msgid="5766472033202928373">"Sblocco con il Volto annullato dall\'utente"</string>
<string name="face_error_lockout" msgid="7864408714994529437">"Troppi tentativi. Riprova più tardi."</string>
- <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Troppi tentativi. Sblocco con il volto non disponibile."</string>
+ <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Troppi tentativi. Sblocco con il Volto non disponibile."</string>
<string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Troppi tentativi. Inserisci il blocco schermo."</string>
<string name="face_error_unable_to_process" msgid="5723292697366130070">"Impossibile verificare il volto. Riprova."</string>
- <string name="face_error_not_enrolled" msgid="1134739108536328412">"Non hai configurato lo sblocco con il volto"</string>
- <string name="face_error_hw_not_present" msgid="7940978724978763011">"Sblocco con il volto non è supportato su questo dispositivo"</string>
+ <string name="face_error_not_enrolled" msgid="1134739108536328412">"Non hai configurato lo Sblocco con il Volto"</string>
+ <string name="face_error_hw_not_present" msgid="7940978724978763011">"Sblocco con il Volto non è supportato su questo dispositivo"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensore temporaneamente disattivato."</string>
<string name="face_name_template" msgid="3877037340223318119">"Volto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <string name="face_app_setting_name" msgid="5854024256907828015">"Usa lo sblocco con il volto"</string>
- <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usa lo sblocco con il volto o il blocco schermo"</string>
+ <string name="face_app_setting_name" msgid="5854024256907828015">"Usa lo Sblocco con il Volto"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usa lo Sblocco con il Volto o il blocco schermo"</string>
<string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Usa il tuo volto per continuare"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Per continuare devi usare il tuo volto o il tuo blocco schermo"</string>
<string-array name="face_error_vendor">
@@ -976,7 +976,7 @@
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Riprova"</string>
<string name="lockscreen_password_wrong" msgid="8605355913868947490">"Riprova"</string>
<string name="lockscreen_storage_locked" msgid="634993789186443380">"Sblocca per accedere a funzioni e dati"</string>
- <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Numero massimo di tentativi di sblocco con il volto superato"</string>
+ <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Numero massimo di tentativi di Sblocco con il Volto superato"</string>
<string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Nessuna SIM presente"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"Nessuna SIM presente nel tablet."</string>
<string name="lockscreen_missing_sim_message" product="tv" msgid="3903140876952198273">"Nessuna SIM presente nel dispositivo Android TV."</string>
@@ -1046,7 +1046,7 @@
<string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Espandi area di sblocco."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Sblocco con scorrimento."</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Sblocco con sequenza."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Sblocco con il volto."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Sblocco con il Volto."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Sblocco con PIN."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Sblocco tramite PIN della SIM."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Sblocco tramite PUK della SIM."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1f909945c79a..000adcef9df6 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1868,8 +1868,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> שני בעבודה"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> שלישי בעבודה"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"שכפול של <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> בפרופיל הפרטי"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"יש לבקש קוד אימות לפני ביטול הצמדה"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 1d93a71f14c5..bddd15c809fd 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -806,7 +806,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Бұған дейін орнатылған қолданбаның автоматты түрде жаңартылуына мүмкіндік береді."</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Құпия сөз ережелерін тағайындау"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Экран бекітпесінің құпия сөздерінің және PIN кодтарының ұзындығын және оларда рұқсат етілген таңбаларды басқару."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Экран құлпын ашу әркеттерін бақылау"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Экран құлпын ашу әрекеттерін бақылау"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Экран бекітпесін ашқан кезде терілген қате құпия сөздердің санын бақылау және планшетті бекіту немесе тым көп қате құпия сөздер терілген болса, планшеттің бүкіл деректерін өшіру."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Экранның құлпын ашу кезінде қате енгізілген құпия сөздердің санын бақылау, құпия сөз тым көп қате енгізілген жағдайда, Android TV құрылғысын құлыптау және Android TV құрылғыңыздың барлық деректерінен тазарту."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Экран құлпын ашқан кезде, терілген қате құпия сөздердің саны бақыланады, сондай-ақ құпия сөздер бірнеше рет қате терілсе, ақпараттық-сауықтық жүйе құлыпталады немесе оның барлық дерегі жойылады."</string>
@@ -819,7 +819,7 @@
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Экран құлпын өзгерте алады."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Экранды құлыптау"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Экранның қашан және қалай құлыпталатынын басқара алады."</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"Барлық деректерді өшіру"</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"Барлық деректі өшіру"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Планшет дерекқорын ескертусіз, зауыттық дерекқорын қайта реттеу арқылы өшіру."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Зауыттық деректерді қалпына келтіру арқылы Android TV құрылғыңыздың деректерін ескертусіз тазартыңыз."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Зауыттық деректерді қалпына келтіру арқылы ақпараттық-сауықтық жүйе дерегі ескертусіз өшіріледі."</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ші жұмыс профилі (<xliff:g id="LABEL">%1$s</xliff:g>)"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-ші жұмыс профилі (<xliff:g id="LABEL">%1$s</xliff:g>)"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> клондау"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Жеке <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Босату алдында PIN кодын сұрау"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Босату алдында бекітпесін ашу өрнегін сұрау"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Босату алдында құпия сөзді сұрау"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 19c6f5d20491..aa543d851322 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -328,7 +328,7 @@
<string name="permgroupdesc_phone" msgid="270048070781478204">"ಫೋನ್ ಕರೆ ಮಾಡಲು ಹಾಗೂ ನಿರ್ವಹಿಸಲು"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"ಬಾಡಿ ಸೆನ್ಸರ್‌"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"ನಿಮ್ಮ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಕುರಿತು ಸೆನ್ಸಾರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permgrouplab_notifications" msgid="5472972361980668884">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="permgrouplab_notifications" msgid="5472972361980668884">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳು"</string>
<string name="permgroupdesc_notifications" msgid="4608679556801506580">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆಯುತ್ತದೆ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ನೀವು ಬಳಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯ ಪರೀಕ್ಷಿಸುತ್ತದೆ."</string>
@@ -2136,7 +2136,7 @@
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"ಹೋಮ್"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"ಹಿಂದಕ್ಕೆ"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳು"</string>
- <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳು"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"ಪವರ್ ಡೈಲಾಗ್"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 335a9572a866..2b50395da43f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"두 번째 업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"세 번째 업무용<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> 복사"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"비공개 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"고정 해제 이전에 PIN 요청"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"고정 해제 시 잠금 해제 패턴 요청"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"고정 해제 이전에 비밀번호 요청"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index df4929fac5b8..63e4b273ca58 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -765,7 +765,7 @@
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"тармактын колдонулуш таржымалын окуу"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Колдонмого белгилүү бир тармактарга жана колдонмолорго байланыштуу тармактын колдонулушу жөнүндө таржымалды окуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"тармак саясатын башкаруу"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Колдонмого тармак саясаттарын башкаруу жана колдонмого мүнөздүү эрежелерди белгилөө мүмкүнчүлүгүн берет."</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Колдонмого тармак эрежелерин башкаруу жана колдонмого мүнөздүү эрежелерди белгилөө мүмкүнчүлүгүн берет."</string>
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"тармактын колдонулуш эсеп-кысабын өзгөртүү"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Колдонмого желени башка колдонмолордун пайдалануусун башкарган тууралоолорду киргизүү уруксатын берет. Жөнөкөй колдонмолор үчүн эмес."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"эскертүүлөр менен иштөө"</string>
@@ -810,7 +810,7 @@
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, планшетти кулпулаңыз же планшеттеги бардык маалыматтарды тазалап салыңыз."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же Android TV түзмөгүңүздөгү бардык дайын-даректериңизди тазалап салуу."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн саны текшерилип, эгер алардын саны өтө эле көп болсо, инфозоок тутуму кулпуланып же инфозоок тутумундагы бардык маалыматтар өчүрүлөт."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, телефонду кулпулаңыз же телефондогу бардык маалыматтарды тазалап салыңыз."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экрандын кулпусун ачуу аракеттерине көз салып, сырсөз өтө көп жолу туура эмес терилсе, телефонду кулпулайт же андагы бардык нерселерди өчүрүп салат."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, планшетти кулпулап же бул колдонуучунун бардык дайындарын тазалап салуу."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же колдонуучунун бардык дайындарын тазалап салуу."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, инфозоок тутуму кулпуланып же бул профилдин бардык дайындары өчүрүлөт."</string>
@@ -1718,7 +1718,7 @@
<string name="color_inversion_feature_name" msgid="2672824491933264951">"Түстөрдү инверсиялоо"</string>
<string name="color_correction_feature_name" msgid="7975133554160979214">"Түстөрдү тууралоо"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бир кол режими"</string>
- <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дагы караңгы"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Кошумча караңгылатуу"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Угуу түзмөктөрү"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> клону"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Купуя <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бошотуудан мурун PIN суралсын"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бошотуудан мурун графикалык ачкыч суралсын"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Бошотуудан мурун сырсөз суралсын"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index cddabaf3afa6..0f8ccf5ee1e4 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ບ່ອນເຮັດວຽກທີ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ບ່ອນເຮັດວຽກທີ 3 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"ໂຄລນ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> ສ່ວນຕົວ"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"​ຖາມ​ຫາ PIN ກ່ອນ​ຍົກ​ເລີກ​ການປັກ​ໝຸດ"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"​ຖາມ​ຫາ​ຮູບ​ແບບ​ປົດ​ລັອກ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"​ຖາມ​ຫາ​ລະ​ຫັດ​ຜ່ານ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index fb1b7b9d5aef..ab6998cc552f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1868,8 +1868,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. darba profils: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. darba profils: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (klons)"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Privātais <xliff:g id="LABEL">%1$s</xliff:g> profils"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Prasīt PIN kodu pirms atspraušanas"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pirms atspraušanas pieprasīt atbloķēšanas kombināciju"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pirms atspraušanas pieprasīt paroli"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index d2bdb4d431af..7906fc1e255f 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -810,7 +810,7 @@
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал таблетыг түгжих болон таблетын бүх датаг арилгана"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Дэлгэцийн түгжээг тайлахаар буруу оруулсан нууц үгийн тоог хянаж, нууц үгийг хэт олон удаа буруу оруулсан тохиолдолд таны Android TV төхөөрөмжийг түгжиж эсвэл үүний бүх өгөгдлийг устгана."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Дэлгэцийн түгжээг тайлахад буруу бичиж оруулсан нууц үгний тоог хянаж, инфотэйнмент системийг түгжих эсвэл хэт олон удаа нууц үгийг буруу бичиж оруулсан тохиолдолд инфотэйнмент системийн бүх өгөгдлийг устгана."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах, ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал утсыг түгжих болон утасны бүх датаг арилгана"</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах, ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал утсыг түгжиж эсвэл утасны бүх өгөгдлийг арилгана"</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Дэлгэцийн түгжээг тайлахад оруулсан буруу нууц үгийн давтамжийг хянаж таблетыг түгжих эсвэл буруу нууц үгийг хэт олон удаа оруулсан тохиолдолд энэ хэрэглэгчийн мэдээллийг устгах."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Дэлгэцийн түгжээг тайлахаар буруу оруулсан нууц үгийн тоог хянаж, нууц үгийг хэт олон удаа буруу оруулсан тохиолдолд таны Android TV төхөөрөмжийг түгжиж эсвэл энэ хэрэглэгчийн бүх өгөгдлийг устгана."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Дэлгэцийн түгжээг тайлахад буруу бичиж оруулсан нууц үгний тоог хянаж, инфотэйнмент системийг түгжих эсвэл хэт олон удаа нууц үгийг буруу бичиж оруулсан тохиолдолд энэ профайлын бүх өгөгдлийг устгана."</string>
@@ -819,11 +819,11 @@
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Дэлгэцийн түгжээг өөрчлөх."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Дэлгэц түгжих"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Дэлгэц хэзээ яаж түгжихийг удирдах"</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"Бүх датаг арилгах"</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"Бүх өгөгдлийг арилгах"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Үйлдвэрийн дата утгыг өгсөнөөр таблетын дата шууд арилгагдана."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Таны Android TV төхөөрөмжийн өгөгдлийг танд анхааруулалгүйгээр үйлдвэрээс гарсан төлөвт шилжүүлэн устгана."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Үйлдвэрийн өгөгдлийн төлөвт үйлдлийг гүйцэтгэснээр инфотэйнмент системийн өгөгдлийг сануулгагүйгээр устгана."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Сануулахгүйгээр утасны бүх мэдээллийг устгаж, үйлдвэрийн өгөгдмөл байдалд шилжүүлнэ"</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Сануулахгүйгээр утасны бүх өгөгдлийг арилгаж, үйлдвэрийн өгөгдлийн тохиргоонд шинэчилнэ"</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Профайлын өгөгдлийг устгах"</string>
<string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Хэрэглэгчийн мэдээллийг арилгах"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Анхааруулга өгөхгүйгээр энэ хэрэглэгчийн энэ таблет дээрх мэдээллийг устгах."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 5f7a5c14e984..74990485c63e 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -806,11 +806,11 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"होल्डरला वापरकर्त्याच्या कृतीशिवाय पूर्वी इंस्टॉल केलेले अ‍ॅप अपडेट करण्याची अनुमती देते"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करा"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रीन लॉक पासवर्ड आणि पिन मध्ये अनुमती दिलेले लांबी आणि वर्ण नियंत्रित करा."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"स्क्रीन अनलॉक प्रयत्नांचे परीक्षण करा"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"स्क्रीन अनलॉक प्रयत्नांवर लक्ष ठेवा"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"टाइप केलेल्या अयोग्य पासवर्डांच्या अंकांचे परीक्षण करा. स्क्रीन अनलॉक केली जाते, तेव्हा टॅबलेट लॉक करा किंवा बरेच पासवर्ड टाइप केले असल्यास टॅबलेटचा सर्व डेटा मिटवा."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रीन अनलॉक करताना टाइप केलेल्या चुकीच्या पासवर्ड संख्येचे परीक्षण करते आणि Android TV डिव्हाइस लॉक करते किंवा अनेक चुकीचे पासवर्ड टाइप केले असल्यास Android TV डिव्हाइसचा सर्व डेटा मिटवते."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"टाइप केलेल्या चुकीच्या पासवर्डच्या संख्येचे निरीक्षण करा. स्क्रीन अनलॉक करताना, इंफोटेनमेंट सिस्टीम लॉक करा किंवा अनेक चुकीचे पासवर्ड टाइप केले असल्यास, इंफोटेनमेंट सिस्टीमचा सर्व डेटा मिटवा."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"टाइप केलेल्या अयोग्य पासवर्डांच्या अंकांचे परीक्षण करा. स्क्रीन अनलॉक केली जाते, तेव्हा फोन लॉक करा किंवा बरेच पासवर्ड टाइप केले असल्यास फोनचा सर्व डेटा मिटवा."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"स्क्रीन अनलॉक करताना टाइप केलेल्या अयोग्य पासवर्डच्या संख्येवर लक्ष ठेवा. बरेच पासवर्ड टाइप केले असल्यास फोन लॉक करा किंवा फोनचा सर्व डेटा मिटवा."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"स्क्रीन अनलॉक करताना टाइप केलेल्या चुकीच्या पासवर्डांच्या संख्येचे परीक्षण करा आणि टॅबलेट लॉक करा किंवा अनेक चुकीचे पासवर्ड टाइप केले असल्यास या वापरकर्त्याचा सर्व डेटा मिटवा."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"स्क्रीन अनलॉक करताना टाइप केलेल्या चुकीच्या पासवर्ड संख्येचे परीक्षण करते आणि Android TV डिव्हाइस लॉक करते किंवा अनेक चुकीचे पासवर्ड टाइप केले असल्यास वापरकर्त्याचा सर्व डेटा मिटवते."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"स्क्रीन अनलॉक करताना टाइप केलेल्या चुकीच्या पासवर्डच्या संख्येचे निरीक्षण करा आणि इंफोटेनमेंट सिस्टीम लॉक करा किंवा अनेक चुकीचे पासवर्ड टाइप केले असल्यास, या प्रोफाइलचा सर्व डेटा मिटवा."</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> क्लोन केलेले"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"खाजगी <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करण्‍यापूर्वी पिन विचारा"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करण्‍यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करण्‍यापूर्वी संकेतशब्दासाठी विचारा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 74e904dab535..3faeb7f65b39 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -2130,7 +2130,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth akan kekal hidup semasa dalam mod pesawat"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Memuatkan"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fail}other{{file_name} + # fail}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Tiada orang yang disyorkan untuk berkongsi"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Tiada orang yang disyorkan untuk membuat perkongsian"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Senarai apl"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Apl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Skrin Utama"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 394a74e64752..5752fa3870da 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -810,7 +810,7 @@
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် တက်ဘလက်ကို သော့ခတ်ရန် သို့မဟုတ် တက်ဘလက် ဒေတာ အားလုံးကို ဖျက်ရန်။"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"မျက်နှာပြင်ကို လော့ခ်ဖွင့်သည့်အခါ စကားဝှက်မှားယွင်းစွာ ရိုက်သွင်းသည့်အကြိမ်ရေကို စောင့်ကြည့်ပြီး မှားယွင်းသည့်အကြိမ်ရေ အလွန်များလာပါက သင့် Android TV စက်ပစ္စည်းကို လော့ခ်ချခြင်း သို့မဟုတ် သင့် Android TV ရှိ အသုံးပြုသူဒေတာများအားလုံးကို ဖျက်ခြင်းတို့ ပြုလုပ်သွားပါမည်။"</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ဖန်သားပြင်လော့ခ်ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက် စကားဝှက် မမှန်မကန် ရိုက်ထည့်မှု များနေလျှင် သတင်းနှင့်ဖျော်ဖြေရေး စနစ်ကို လော့ခ်ချသည် (သို့) ၎င်း၏ ဒေတာအားလုံးကို ဖျက်သည်။"</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် ဖုန်းကို သော့ခတ်ရန် သို့မဟုတ် ဖုန်း ဒေတာ အားလုံးကို ဖျက်ရန်။"</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"မျက်နှာပြင်ကို လောခ်ဖွင့်ရန်အတွက် ရိုက်ထည့်သည့် မှားယွင်းသောစကားဝှက် အကြိမ်ရေကို စောင့်ကြည့်ပြီး မမှန်သောစကားဝှက် ရိုက်ထည့်မှု အလွန်များနေလျှင် ဖုန်းကိုလော့ခ်ချသည် (သို့) ဖုန်း ဒေတာအားလုံးကို ဖျက်သည်။"</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"ဖန်မျက်နှာပြင်အား သော့ဖွင့်စဉ် လျှို့ဝှက်ကုဒ်အမှားများ ရိုက်သွင်းမှုအား စောင့်ကြည့်ရန်နှင့်၊ လျှို့ဝှက်ကုဒ်အမှားများ များစွာ ရိုက်သွင်းပါက တက်ဘလက်အား သော့ချခြင်း သို့မဟုတ် တက်ဘလက်၏ အချက်အလက်များအား ဖျက်ပစ်ခြင်းများ ပြုလုပ်မည်။"</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"မျက်နှာပြင်ကို လော့ခ်ဖွင့်သည့်အခါ စကားဝှက်မှားယွင်းစွာ ရိုက်သွင်းသည့်အကြိမ်ရေကို စောင့်ကြည့်ပြီး မှားယွင်းသည့်အကြိမ်ရေ အလွန်များလာပါက သင့် Android TV စက်ပစ္စည်းကို လော့ခ်ချခြင်း သို့မဟုတ် ဤအသုံးပြုသူဒေတာများအားလုံးကို ဖျက်ခြင်းတို့ ပြုလုပ်သွားပါမည်။"</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"ဖန်သားပြင်လော့ခ်ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက် စကားဝှက် မမှန်မကန် ရိုက်ထည့်မှု များနေလျှင် သတင်းနှင့်ဖျော်ဖြေရေး စနစ်ကို လော့ခ်ချသည် (သို့) ဤပရိုဖိုင်၏ ဒေတာအားလုံးကို ဖျက်သည်။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ffc8bea2894b..0cc55e48873f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -806,7 +806,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Lar innehaveren oppdatere appen hen tidligere installerte, uten brukerhandling"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Angi passordregler"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontrollerer tillatt lengde og tillatte tegn i passord og PIN-koder for opplåsing av skjermen."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Overvåk forsøk på å låse opp skjermen"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Overvåking av forsøk på å låse opp skjermen"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Overvåk antall feil passordforsøk ved opplåsing av skjerm, og lås nettbrettet eller slett alle data fra nettbrettet ved for mange feil passordforsøk."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Følg med på hvor mange ganger feil passord skrives inn når skjermen skal låses opp, og lås Android TV-enheten eller tøm alle dataene når feil passord skrives inn for mange ganger."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Overvåk antall feil passord som er skrevet inn ved opplåsing av skjermen, og lås infotainment-systemet eller tøm alle dataene i infotainment-systemet hvis feil passord skrives inn for mange ganger."</string>
@@ -1288,13 +1288,13 @@
<string name="volume_call" msgid="7625321655265747433">"Samtalevolum"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Bluetooth-samtalevolum"</string>
<string name="volume_alarm" msgid="4486241060751798448">"Alarmvolum"</string>
- <string name="volume_notification" msgid="6864412249031660057">"Varslingsvolum"</string>
+ <string name="volume_notification" msgid="6864412249031660057">"Varselvolum"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Volum"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Bluetooth-volum"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"Ringetonevolum"</string>
<string name="volume_icon_description_incall" msgid="4491255105381227919">"Samtalevolum"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"Medievolum"</string>
- <string name="volume_icon_description_notification" msgid="579091344110747279">"Varslingsvolum"</string>
+ <string name="volume_icon_description_notification" msgid="579091344110747279">"Varselvolum"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Standard ringetone"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Standard (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="397111123930141876">"Ingen"</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Andre <xliff:g id="LABEL">%1$s</xliff:g> for jobben"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Tredje <xliff:g id="LABEL">%1$s</xliff:g> for jobben"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Privat <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Krev PIN-kode for å løsne app"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Krev opplåsingsmønster for å løsne apper"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Krev passord for å løsne apper"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 672cfbc8a633..e38898eb468b 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"कार्यालयको दोस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"कार्यालयको तेस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> क्लोन गर्नुहोस्"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"निजी <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन गर्नुअघि PIN मागियोस्"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन गर्नअघि अनलक प्याटर्न माग्नुहोस्"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 2846b6a115b0..7d48a017b1be 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -329,7 +329,7 @@
<string name="permgrouplab_sensors" msgid="9134046949784064495">"Lichaamssensoren"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"toegang krijgen tot sensorgegevens over je vitale functies"</string>
<string name="permgrouplab_notifications" msgid="5472972361980668884">"Meldingen"</string>
- <string name="permgroupdesc_notifications" msgid="4608679556801506580">"meldingen laten zien"</string>
+ <string name="permgroupdesc_notifications" msgid="4608679556801506580">"meldingen tonen"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Content van vensters ophalen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"De content inspecteren van een venster waarmee je interactie hebt."</string>
<string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Verkennen via aanraking aanzetten"</string>
@@ -596,8 +596,8 @@
<string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Hiermee kan de app de toetsenblokkering en bijbehorende wachtwoordbeveiliging uitzetten. Zo kan de telefoon de toetsenblokkering uitzetten als je wordt gebeld en de toetsenblokkering weer aanzetten als het gesprek is beëindigd."</string>
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"complexiteit van schermvergrendeling opvragen"</string>
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Hiermee krijgt de app toestemming om het complexiteitsniveau van de schermvergrendeling te achterhalen (hoog, midden, laag of geen). Dat geeft een indicatie van het mogelijke lengtebereik en type van de schermvergrendeling. De app kan gebruikers ook voorstellen de schermvergrendeling naar een bepaald niveau te updaten, maar gebruikers kunnen dit altijd negeren en de app verlaten. De schermvergrendeling wordt niet opgeslagen als platte tekst, zodat de app het precieze wachtwoord niet weet."</string>
- <string name="permlab_postNotification" msgid="4875401198597803658">"meldingen laten zien"</string>
- <string name="permdesc_postNotification" msgid="5974977162462877075">"Hiermee kan de app meldingen laten zien"</string>
+ <string name="permlab_postNotification" msgid="4875401198597803658">"meldingen tonen"</string>
+ <string name="permdesc_postNotification" msgid="5974977162462877075">"Hiermee kan de app meldingen tonen"</string>
<string name="permlab_turnScreenOn" msgid="219344053664171492">"het scherm aanzetten"</string>
<string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Hiermee kan de app het scherm aanzetten."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"biometrische hardware gebruiken"</string>
@@ -2100,7 +2100,7 @@
<string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Uitzetten"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Meer informatie"</string>
- <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"In Android 12 hebben verbeterde meldingen aanpasbare Android-meldingen vervangen. Deze functie laat voorgestelde acties en antwoorden zien en ordent je meldingen.\n\nVerbeterde meldingen hebben toegang tot meldingscontent, waaronder persoonlijke informatie zoals contactnamen en berichten. Deze functie kan ook meldingen sluiten of erop reageren, zoals telefoongesprekken aannemen, en Niet storen beheren."</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"In Android 12 hebben verbeterde meldingen aanpasbare Android-meldingen vervangen. Deze functie toont voorgestelde acties en antwoorden en ordent je meldingen.\n\nVerbeterde meldingen hebben toegang tot meldingscontent, waaronder persoonlijke informatie zoals contactnamen en berichten. Deze functie kan ook meldingen sluiten of erop reageren, zoals telefoongesprekken aannemen, en Niet storen beheren."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatiemelding voor routinemodus"</string>
<string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Batterijbesparing staat aan"</string>
<string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Het batterijgebruik wordt beperkt om de batterijduur te verlengen"</string>
@@ -2301,7 +2301,7 @@
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Blokkeren van apparaatmicrofoon opheffen"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Blokkeren van apparaatcamera opheffen"</string>
<string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Voor &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; en alle andere apps en services"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Blokkeren opheffen"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Niet meer blokkeren"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivacy"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"App-icoon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Merkafbeelding voor app"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 41d8b509b1fa..64736e556fbb 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2ୟ କାର୍ଯ୍ୟ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3ୟ କାର୍ଯ୍ୟ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> କ୍ଲୋନ"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"ପ୍ରାଇଭେଟ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ PIN ପଚାରନ୍ତୁ"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ଲକ୍‌ ଖୋଲିବା ପାଟର୍ନ ପଚାରନ୍ତୁ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ପାସ୍‌ୱର୍ଡ ପଚାରନ୍ତୁ"</string>
@@ -2131,7 +2130,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"ଏୟାରପ୍ଲେନ୍ ମୋଡରେ ବ୍ଲୁଟୁଥ୍ ଚାଲୁ ରହିବ"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"ଲୋଡ୍ ହେଉଛି"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + #ଟି ଫାଇଲ}other{{file_name} + #ଟି ଫାଇଲ}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ଏହାକୁ ସେୟାର୍ କରିବା ପାଇଁ କୌଣସି ସୁପାରିଶ କରାଯାଇଥିବା ଲୋକ ନାହାଁନ୍ତି"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ଏହାକୁ ସେୟାର କରିବା ପାଇଁ କୌଣସି ସୁପାରିଶ କରାଯାଇଥିବା ଲୋକ ନାହାଁନ୍ତି"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"ଆପ୍ସ ତାଲିକା"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"ଏହି ଆପ୍‌କୁ ରେକର୍ଡ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ କିନ୍ତୁ ଏହି USB ଡିଭାଇସ୍ ଜରିଆରେ ଅଡିଓ କ୍ୟାପ୍‍ଚର୍‍ କରିପାରିବ।"</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"ହୋମ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 8b9934fe860b..8cfc0e4279d1 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ਦੂਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ਤੀਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ਦਾ ਕਲੋਨ"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"ਨਿੱਜੀ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
@@ -2131,7 +2130,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵੇਲੇ ਬਲੂਟੁੱਥ ਹਾਲੇ ਵੀ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ਫ਼ਾਈਲ}one{{file_name} + # ਫ਼ਾਈਲ}other{{file_name} + # ਫ਼ਾਈਲਾਂ}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ਸਾਂਝਾ ਕਰਨ ਲਈ ਕੋਈ ਸਿਫ਼ਾਰਸ਼ ਕੀਤੇ ਲੋਕ ਨਹੀਂ"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ਸਾਂਝਾ ਕਰਨ ਲਈ ਕੋਈ ਸਿਫ਼ਾਰਸ਼ ਕੀਤਾ ਵਿਅਕਤੀ ਨਹੀਂ ਹੈ"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"ਐਪ ਸੂਚੀ"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"ਇਸ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਪਰ ਇਹ USB ਡੀਵਾਈਸ ਰਾਹੀਂ ਆਡੀਓ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"ਹੋਮ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 880892f9e786..a40fae86a5f3 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1869,8 +1869,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 2"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 3"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon aplikacji <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Prywatna aplikacja <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Podaj PIN, aby odpiąć"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Aby odpiąć, poproś o wzór odblokowania"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Aby odpiąć, poproś o hasło"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5dc54639d14c..cf428b70b7c9 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1868,8 +1868,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (2)"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (3)"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonă pentru <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privat"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicită codul PIN înainte de a anula fixarea"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicită mai întâi modelul pentru deblocare"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicită parola înainte de a anula fixarea"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e09593ee95c3..4986c10f7522 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1865,12 +1865,11 @@
<string name="select_day" msgid="2060371240117403147">"Выберите месяц и число"</string>
<string name="select_year" msgid="1868350712095595393">"Выберите год"</string>
<string name="deleted_key" msgid="9130083334943364001">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</string>
- <string name="managed_profile_label_badge" msgid="6762559569999499495">"Рабочий <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (рабочий профиль)"</string>
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Задача 2: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Задача 3: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонировать <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> (личный профиль)"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запрашивать PIN-код"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запрашивать графический ключ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запрашивать пароль"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 99d90bee006b..1b6230d3d340 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2වන වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3වන වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ක්ලෝන කරන්න"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"පෞද්ගලික <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ගැලවීමට පෙර PIN විමසන්න"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index a3ca1a6562f3..9784308ca57f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -808,7 +808,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Povolí vlastníkovi aktualizovať aplikáciu, ktorá bola nainštalovaná bez akcie používateľa"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Nastaviť pravidlá pre heslo"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Nastavte dĺžku hesiel na odomknutie obrazovky aj kódov PIN a v nich používané znaky."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Sledovanie pokusov o odomknutie obrazovky"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Sledovať pokusy o odomknutie obrazovky"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Sledovať počet nesprávnych hesiel zadaných pri odomykaní obrazovky a zamknúť tablet alebo vymazať všetky údaje tabletu v prípade príliš veľkého počtu neplatných pokusov o zadanie hesla."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Sledovanie počtu nesprávnych hesiel zadaných pri odomykaní obrazovky a v prípade, že ich je zadaných príliš mnoho, uzamknutie zariadenia Android TV alebo vymazanie všetkých jeho údajov."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Sledujte počet nesprávnych hesiel zadaných pri odomykaní obrazovky a uzamknite palubný systém alebo vymažte všetky údaje v palubnom systéme v prípade príliš veľkého počtu neplatných pokusov o zadanie hesla."</string>
@@ -1869,8 +1869,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klonovať <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Súkromná aplikácia <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pred odopnutím požiadať o číslo PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odopnutím požiadať o heslo"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5292fc328640..16ea77f1b0c6 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -812,7 +812,7 @@
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Nadzoruje število nepravilno vnesenih gesel pri odklepanju zaslona in zaklene tablični računalnik ali izbriše vse podatke v njem, če je vnesenih preveč nepravilnih gesel."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Nadzira število vnesenih nepravilnih gesel pri odklepanju zaslona in zaklene napravo Android TV ali izbriše vse podatke v napravi Android TV, če je vnesenih preveč nepravilnih gesel."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Spremljanje števila nepravilno vnesenih gesel pri odklepanju zaslona in zaklenitev informativno-razvedrilnega sistema ali izbris vseh podatkov v njem v primeru preveč vnosov nepravilnih gesel"</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Spremljajte število vnesenih napačnih gesel, s katerimi želite odkleniti zaslon. Če je teh vnosov preveč, zaklenite telefon ali izbrišite vse podatke v njem."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Spremljanje števila vnosov napačnih gesel za odklepanje zaslona ter zaklenitev telefona ali izbris vseh podatkov v njem v primeru prevelikega števila vnosov napačnih gesel."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Nadzira število vnesenih nepravilnih gesel pri odklepanju zaslona in zaklene tablični računalnik ali izbriše vse podatke lastnika, če je vnesenih preveč nepravilnih gesel."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Nadzira število vnesenih nepravilnih gesel pri odklepanju zaslona in zaklene napravo Android TV ali izbriše vse podatke tega uporabnika, če je vnesenih preveč nepravilnih gesel."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Spremljanje števila nepravilno vnesenih gesel pri odklepanju zaslona in zaklenitev informativno-razvedrilnega sistema ali izbris vseh podatkov tega profila v primeru preveč vnosov nepravilnih gesel"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index fd7453426231..a3d648f204fa 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -983,7 +983,7 @@
<string name="lockscreen_missing_sim_instructions" msgid="5823469004536805423">"Shto një kartë SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="4403843937236648032">"Karta SIM mungon ose është e palexueshme. Shto një kartë SIM."</string>
<string name="lockscreen_permanent_disabled_sim_message_short" msgid="1925200607820809677">"Kartë SIM e papërdorshme."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"Karta jote SIM është çaktivizuar përgjithmonë.\n Kontakto me ofruesin e shërbimit me valë për një kartë tjetër SIM."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"Karta jote SIM është çaktivizuar përgjithmonë.\n Kontakto me ofruesin e shërbimit wireless për një tjetër kartë SIM."</string>
<string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Kënga e mëparshme"</string>
<string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Kënga tjetër"</string>
<string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pauzë"</string>
@@ -1198,7 +1198,7 @@
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Redakto me %1$s"</string>
<string name="whichEditApplicationLabel" msgid="1463288652070140285">"Redakto"</string>
<string name="whichSendApplication" msgid="4143847974460792029">"Ndaj"</string>
- <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Shpërndaj me %1$s"</string>
+ <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Ndaj me %1$s"</string>
<string name="whichSendApplicationLabel" msgid="7467813004769188515">"Ndaj"</string>
<string name="whichSendToApplication" msgid="77101541959464018">"Dërgo me"</string>
<string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Dërgo me %1$s"</string>
@@ -1523,7 +1523,7 @@
<string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# përputhje}other{# nga {total}}}"</string>
<string name="action_mode_done" msgid="2536182504764803222">"U krye"</string>
<string name="progress_erasing" msgid="6891435992721028004">"Po fshin hapësirën ruajtëse të brendshme…"</string>
- <string name="share" msgid="4157615043345227321">"Shpërndaj"</string>
+ <string name="share" msgid="4157615043345227321">"Ndaj"</string>
<string name="find" msgid="5015737188624767706">"Gjej"</string>
<string name="websearch" msgid="5624340204512793290">"Kërkim në internet"</string>
<string name="find_next" msgid="5341217051549648153">"Gjej tjetrën"</string>
@@ -1568,8 +1568,8 @@
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
<string name="activitychooserview_choose_application" msgid="3500574466367891463">"Zgjidh një aplikacion"</string>
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Nuk mundi ta hapte <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Shpërndaj me"</string>
- <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Shpërndaj me <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Ndaj me"</string>
+ <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Ndaj me <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="982510275422590757">"Dorezë me rrëshqitje. Preke dhe mbaje të shtypur."</string>
<string name="description_target_unlock_tablet" msgid="7431571180065859551">"Rrëshqit për të shkyçur."</string>
<string name="action_bar_home_description" msgid="1501655419158631974">"Orientohu për në shtëpi"</string>
@@ -1613,7 +1613,7 @@
<string name="sha1_fingerprint" msgid="2339915142825390774">"Gjurma e gishtit SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Shikoji të gjitha"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Zgjidh aktivitetin"</string>
- <string name="share_action_provider_share_with" msgid="1904096863622941880">"Shpërndaj me"</string>
+ <string name="share_action_provider_share_with" msgid="1904096863622941880">"Ndaj me"</string>
<string name="sending" msgid="206925243621664438">"Po dërgon…"</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"Të hapet shfletuesi?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"Dëshiron ta pranosh telefonatën?"</string>
@@ -1629,7 +1629,7 @@
<string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
<string name="default_audio_route_category_name" msgid="5241740395748134483">"Sistemi"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Audioja e \"bluetooth-it\""</string>
- <string name="wireless_display_route_description" msgid="8297563323032966831">"Ekran pa tel"</string>
+ <string name="wireless_display_route_description" msgid="8297563323032966831">"Ekran wireless"</string>
<string name="media_route_button_content_description" msgid="2299223698196869956">"Transmeto"</string>
<string name="media_route_chooser_title" msgid="6646594924991269208">"Lidhu me pajisjen"</string>
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Transmeto ekranin në pajisje"</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> i dytë i punës"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> i tretë i punës"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klonim i <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privat"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Zhgozhdimi kërkon PIN-in"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Kërko motivin e shkyçjes para heqjes së gozhdimit"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
@@ -1889,9 +1888,9 @@
<string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Për 1 min.}other{Për # min.}}"</string>
<string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Për 1 orë}other{Për # orë}}"</string>
<string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Për 1 orë}other{Për # orë}}"</string>
- <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <string name="zen_mode_until" msgid="2250286190237669079">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <string name="zen_mode_alarm" msgid="7046911727540499275">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarmi tjetër)"</string>
+ <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Deri: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_until" msgid="2250286190237669079">"Deri: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="7046911727540499275">"Deri: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarmi tjetër)"</string>
<string name="zen_mode_forever" msgid="740585666364912448">"Derisa ta çaktivizosh"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Deri sa të çaktivizosh gjendjen \"Mos shqetëso\""</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
@@ -2164,9 +2163,9 @@
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Pamja personale"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Pamja e punës"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Bllokuar nga administratori yt i teknologjisë së informacionit"</string>
- <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Kjo përmbajtje nuk mund të shpërndahet me aplikacione pune"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Kjo përmbajtje nuk mund të ndahet me aplikacione pune"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Kjo përmbajtje nuk mund të hapet me aplikacione pune"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Kjo përmbajtje nuk mund të shpërndahet me aplikacione personale"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Kjo përmbajtje nuk mund të ndahet me aplikacione personale"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Kjo përmbajtje nuk mund të hapet me aplikacione personale"</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Aplikacionet e punës janë vendosur në pauzë"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"Hiq nga pauza"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 81c19152f0fb..712aeb99dd98 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -807,7 +807,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Дозвољава власнику да ажурира апликацију коју је претходно инсталирала без радњи корисника"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Подешавање правила за лозинку"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за закључавање екрана."</string>
- <string name="policylab_watchLogin" msgid="7599669460083719504">"Надгледајте покушаје откључавања екрана"</string>
+ <string name="policylab_watchLogin" msgid="7599669460083719504">"Надзор покушаја откључавања екрана"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Прати број нетачно унетих лозинки приликом откључавања екрана и закључава таблет или брише податке са таблета ако је нетачна лозинка унета превише пута."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке са Android TV уређаја ако се унесе превише нетачних лозинки."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Прати број нетачно унетих лозинки при откључавању екрана и закључава систем за инфо-забаву или брише све податке са система за инфо-забаву ако је нетачна лозинка унета превише пута."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 1ca3e08abb53..3624f71d1e7e 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Andra <xliff:g id="LABEL">%1$s</xliff:g> för jobbet"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Tredje <xliff:g id="LABEL">%1$s</xliff:g> för jobbet"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Klona <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Privat <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Be om pinkod innan skärmen slutar fästas"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Be om upplåsningsmönster innan skärmen slutar fästas"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Be om lösenord innan skärmen slutar fästas"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 5b2b2b2d522a..8c2ddb0cf395 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"குளோன் <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"தனிப்பட்ட <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"அகற்றும் முன் PINஐக் கேள்"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 5b9e737b7d63..4c7835f66b41 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -322,7 +322,7 @@
<string name="permgroupdesc_camera" msgid="7585150538459320326">"చిత్రాలను తీయడానికి మరియు వీడియోను రికార్డ్ చేయడానికి"</string>
<string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"సమీపంలోని పరికరాలు"</string>
<string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"సమీప పరికరాలను కనుగొనండి అలాగే కనెక్ట్ చేయండి"</string>
- <string name="permgrouplab_calllog" msgid="7926834372073550288">"కాల్ లాగ్‌లు"</string>
+ <string name="permgrouplab_calllog" msgid="7926834372073550288">"కాల్ లాగ్స్‌"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ఫోన్ కాల్ లాగ్‌ని చదవండి మరియు రాయండి"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ఫోన్"</string>
<string name="permgroupdesc_phone" msgid="270048070781478204">"ఫోన్ కాల్స్‌ చేయడం మరియు నిర్వహించడం"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 33b050aa2cef..ee45ede2df89 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -819,7 +819,7 @@
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Ekran kilidini değiştirir."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Ekranı kilitleme"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Ekranın nasıl ve ne zaman kilitleneceğini denetler."</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"Tüm verileri silme"</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"Tüm verileri sil"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Fabrika verilerine sıfırlama işlemi gerçekleştirerek tabletteki verileri uyarıda bulunmadan siler."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Fabrika verilerine sıfırlama işlemi gerçekleştirerek Android TV cihazınızdaki verileri uyarıda bulunmadan siler."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Fabrika verilerine sıfırlama işlemi gerçekleştirerek bilgi-eğlence sistemindeki veriler uyarıda bulunmadan silinir."</string>
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"İş için 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"İş için 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> klonu"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"Gizli <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sabitlemeyi kaldırmadan önce PIN\'i sor"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index f6d426d53b28..63b7560140e7 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -821,7 +821,7 @@
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Змінити спосіб розблокування екрана."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Блокувати екран"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Контролювати, як і коли блокується екран."</string>
- <string name="policylab_wipeData" msgid="1359485247727537311">"Видалити всі дані"</string>
+ <string name="policylab_wipeData" msgid="1359485247727537311">"Видаляти всі дані"</string>
<string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Стирати дані планшетного ПК без попередження, відновлюючи заводські налаштування."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Видаляйте дані пристрою Android TV без попередження шляхом відновлення заводських налаштувань."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Видаляйте всі дані інформаційно-розважальної системи без попередження, відновлюючи заводські налаштування."</string>
@@ -1869,8 +1869,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-а робота: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-я робота: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Копія додатка <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> (приватний профіль)"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-код для відкріплення"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитувати ключ розблокування перед відкріпленням"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитувати пароль перед відкріпленням"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index c8cd1cb2b9d9..bd6ea76a820f 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"دوسرا کام <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"تیسرا کام <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> کلون"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"نجی <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"‏پن ہٹانے سے پہلے PIN طلب کریں"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 5b92609c8b96..c02adbc5d2c7 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1867,8 +1867,7 @@
<string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Công việc thứ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Công việc thứ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="clone_profile_label_badge" msgid="1871997694718793964">"Sao chép <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for private_profile_label_badge (1712086003787839183) -->
- <skip />
+ <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> riêng tư"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Hỏi mã PIN trước khi bỏ ghim"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Hỏi hình mở khóa trước khi bỏ ghim"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Hỏi mật khẩu trước khi bỏ ghim"</string>
diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml
index 5319762c27d1..4027f5c78035 100644
--- a/core/res/res/values-watch/config.xml
+++ b/core/res/res/values-watch/config.xml
@@ -81,4 +81,9 @@
<!-- Floating windows can be fullscreen (i.e. windowIsFloating can still have fullscreen
window that does not wrap content). -->
<bool name="config_allowFloatingWindowsFillScreen">true</bool>
+
+ <!-- Whether scroll haptic feedback is enabled for rotary encoder scrolls on
+ {@link MotionEvent#AXIS_SCROLL} generated by {@link InputDevice#SOURCE_ROTARY_ENCODER}
+ devices. -->
+ <bool name="config_viewRotaryEncoderHapticScrollFedbackEnabled">true</bool>
</resources>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 6bb87f3c4e99..582153766dbe 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -151,6 +151,27 @@
<integer name="config_timeout_to_receive_delivered_ack_millis">300000</integer>
<java-symbol type="integer" name="config_timeout_to_receive_delivered_ack_millis" />
+ <!-- The time duration in millis that the satellite will stay at listening state to wait for the
+ next incoming page before disabling listening and moving to IDLE state. This timeout
+ duration is used when transitioning from sending state to listening state.
+ -->
+ <integer name="config_satellite_stay_at_listening_from_sending_millis">180000</integer>
+ <java-symbol type="integer" name="config_satellite_stay_at_listening_from_sending_millis" />
+
+ <!-- The time duration in millis that the satellite will stay at listening state to wait for the
+ next incoming page before disabling listening and moving to IDLE state. This timeout
+ duration is used when transitioning from receiving state to listening state.
+ -->
+ <integer name="config_satellite_stay_at_listening_from_receiving_millis">30000</integer>
+ <java-symbol type="integer" name="config_satellite_stay_at_listening_from_receiving_millis" />
+
+ <!-- The time duration in millis after which cellular scanning will be enabled and satellite
+ will move to IDLE state. This timeout duration is used for satellite with NB IOT radio
+ technologies.
+ -->
+ <integer name="config_satellite_nb_iot_inactivity_timeout_millis">180000</integer>
+ <java-symbol type="integer" name="config_satellite_nb_iot_inactivity_timeout_millis" />
+
<!-- Telephony config for services supported by satellite providers. The format of each config
string in the array is as follows: "PLMN_1:service_1,service_2,..."
where PLMN is the satellite PLMN of a provider and service is an integer with the
@@ -204,4 +225,8 @@
<bool name="telephony_analytics_switch">true</bool>
<java-symbol type="bool" name="telephony_analytics_switch" />
+ <!-- Whether to enable modem on boot if behavior is not defined -->
+ <bool name="config_enable_cellular_on_boot_default">true</bool>
+ <java-symbol type="bool" name="config_enable_cellular_on_boot_default" />
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 591e505a792f..fac6aac1db16 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1444,6 +1444,11 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
<string name="permdesc_cameraOpenCloseListener">This app can receive callbacks when any camera device is being opened (by what application) or closed.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
+ <string name="permlab_cameraHeadlessSystemUser">Allow an application or service to access camera as Headless System User.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
+ <string name="permdesc_cameraHeadlessSystemUser">This app can access camera as Headless System User.</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_vibrate">control vibration</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index 89b91cf27b38..14f268a91abf 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -89,9 +89,6 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
new ProgramSelector.Identifier(
ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY, TEST_DAB_FREQUENCY_VALUE);
- private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
- new ProgramSelector.Identifier(
- ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, TEST_FM_FREQUENCY_VALUE);
private static final ProgramSelector.Identifier TEST_VENDOR_ID =
new ProgramSelector.Identifier(
ProgramSelector.IDENTIFIER_TYPE_VENDOR_START, TEST_VENDOR_ID_VALUE);
@@ -251,6 +248,20 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
}
@Test
+ public void identifierToHalProgramIdentifier_withDeprecateDabId() {
+ long value = 0x98765ABCDL;
+ ProgramSelector.Identifier dabId = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT, value);
+ ProgramIdentifier halDabIdExpected = AidlTestUtils.makeHalIdentifier(
+ IdentifierType.DAB_SID_EXT, 0x987650000ABCDL);
+
+ ProgramIdentifier halDabId = ConversionUtils.identifierToHalProgramIdentifier(dabId);
+
+ expect.withMessage("Converted 28-bit DAB identifier for HAL").that(halDabId)
+ .isEqualTo(halDabIdExpected);
+ }
+
+ @Test
public void identifierFromHalProgramIdentifier_withDabId() {
ProgramSelector.Identifier dabId =
ConversionUtils.identifierFromHalProgramIdentifier(TEST_HAL_DAB_SID_EXT_ID);
diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
index 555390231983..37ef6cba8814 100644
--- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
@@ -85,9 +85,11 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
assertEquals(2, cache.getAllServicesSize(U0));
assertEquals(2, cache.getPersistentServicesSize(U0));
assertNotEmptyFileCreated(cache, U0);
+ cache.unregisterReceivers();
// Make sure all services can be loaded from xml
cache = new TestServicesCache();
assertEquals(2, cache.getPersistentServicesSize(U0));
+ cache.unregisterReceivers();
}
public void testGetAllServicesReplaceUid() {
@@ -110,6 +112,7 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
assertTrue("UID must be updated to the new value",
uids.contains(SYSTEM_IMAGE_UID));
assertFalse("UID must be updated to the new value", uids.contains(UID2));
+ cache.unregisterReceivers();
}
public void testGetAllServicesServiceRemoved() {
@@ -118,6 +121,7 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
cache.addServiceForQuerying(U0, r2, newServiceInfo(t2, UID2));
assertEquals(2, cache.getAllServicesSize(U0));
assertEquals(2, cache.getPersistentServicesSize(U0));
+ cache.unregisterReceivers();
// Re-read data from disk and verify services were saved
cache = new TestServicesCache();
assertEquals(2, cache.getPersistentServicesSize(U0));
@@ -125,6 +129,7 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
cache.addServiceForQuerying(U0, r1, newServiceInfo(t1, UID1));
assertEquals(1, cache.getAllServicesSize(U0));
assertEquals(1, cache.getPersistentServicesSize(U0));
+ cache.unregisterReceivers();
}
public void testGetAllServicesMultiUser() {
@@ -137,12 +142,14 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
assertEquals(1, cache.getAllServicesSize(U1));
assertEquals(1, cache.getPersistentServicesSize(U1));
assertEquals("No services should be available for user 3", 0, cache.getAllServicesSize(3));
+ cache.unregisterReceivers();
// Re-read data from disk and verify services were saved
cache = new TestServicesCache();
assertEquals(1, cache.getPersistentServicesSize(U0));
assertEquals(1, cache.getPersistentServicesSize(U1));
assertNotEmptyFileCreated(cache, U0);
assertNotEmptyFileCreated(cache, U1);
+ cache.unregisterReceivers();
}
public void testOnRemove() {
@@ -158,6 +165,7 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
cache.clearServicesForQuerying();
assertEquals(1, cache.getAllServicesSize(U0));
assertEquals(0, cache.getAllServicesSize(U1));
+ cache.unregisterReceivers();
}
public void testMigration() {
@@ -186,10 +194,12 @@ public class RegisteredServicesCacheTest extends AndroidTestCase {
cache.addServiceForQuerying(0, r2, newServiceInfo(t2, 2));
assertEquals(2, cache.getAllServicesSize(u0));
assertEquals(0, cache.getAllServicesSize(u1));
+ cache.unregisterReceivers();
// Re-read data from disk. Verify that services were saved and old file was ignored
cache = new TestServicesCache();
assertEquals(2, cache.getPersistentServicesSize(u0));
assertEquals(0, cache.getPersistentServicesSize(u1));
+ cache.unregisterReceivers();
}
private static RegisteredServicesCache.ServiceInfo<TestServiceType> newServiceInfo(
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index 9840e15c5975..0e1a6b7e7daa 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -71,6 +71,7 @@ public class DeviceConfigTest {
deleteViaContentProvider(NAMESPACE, KEY2);
deleteViaContentProvider(NAMESPACE, KEY3);
DeviceConfig.clearAllLocalOverrides();
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
}
/**
diff --git a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java
index a2c41e440107..d2af2a734330 100644
--- a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java
+++ b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java
@@ -47,7 +47,6 @@ public final class HapticScrollFeedbackProviderTest {
private static final int INPUT_DEVICE_2 = 2;
private TestView mView;
- private long mCurrentTimeMillis = 1000; // arbitrary starting time value
@Mock ViewConfiguration mMockViewConfig;
@@ -67,24 +66,15 @@ public final class HapticScrollFeedbackProviderTest {
setHapticScrollFeedbackEnabled(false);
// Call different types scroll feedback methods; non of them should produce feedback because
// feedback has been disabled.
- mProvider.onSnapToItem(createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL);
mProvider.onSnapToItem(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ true);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
- mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ true);
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 10);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ -9);
- mProvider.onScrollProgress(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* deltaInPixels= */ 300);
mProvider.onScrollProgress(
@@ -95,14 +85,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testSnapToItem_withMotionEvent() {
- mProvider.onSnapToItem(createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_ITEM_FOCUS);
- }
-
- @Test
- public void testSnapToItem_withDeviceIdAndSource() {
+ public void testSnapToItem() {
mProvider.onSnapToItem(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
@@ -110,15 +93,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_start_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ true);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
- }
-
- @Test
- public void testScrollLimit_start_withDeviceIdAndSource() {
+ public void testScrollLimit_start() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ true);
@@ -127,15 +102,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_stop_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
- }
-
- @Test
- public void testScrollLimit_stop_withDeviceIdAndSource() {
+ public void testScrollLimit_stop() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -144,21 +111,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollProgress_zeroTickInterval_withMotionEvent() {
- setHapticScrollTickInterval(0);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 10);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 30);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 30);
-
- assertNoFeedback(mView);
- }
-
- @Test
- public void testScrollProgress_zeroTickInterval_withDeviceIdAndSource() {
+ public void testScrollProgress_zeroTickInterval() {
setHapticScrollTickInterval(0);
mProvider.onScrollProgress(
@@ -172,30 +125,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollProgress_progressEqualsOrExceedsPositiveThreshold_withMotionEvent() {
- setHapticScrollTickInterval(100);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 20);
-
- assertNoFeedback(mView);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 80);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 1);
-
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 80);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 40);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 2);
- }
-
- @Test
- public void testScrollProgress_progressEqualsOrExceedsPositiveThreshold_withDeviceIdAndSrc() {
+ public void testScrollProgress_progressEqualsOrExceedsPositiveThreshold() {
setHapticScrollTickInterval(100);
mProvider.onScrollProgress(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
@@ -217,37 +147,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollProgress_progressEqualsOrExceedsNegativeThreshold_withMotionEvent() {
- setHapticScrollTickInterval(100);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ -20);
-
- assertNoFeedback(mView);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ -80);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 1);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ -70);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ -40);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 2);
- }
-
- @Test
- public void testScrollProgress_progressEqualsOrExceedsNegativeThreshold_withDeviceIdAndSrc() {
+ public void testScrollProgress_progressEqualsOrExceedsNegativeThreshold() {
setHapticScrollTickInterval(100);
mProvider.onScrollProgress(
@@ -273,42 +173,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollProgress_positiveAndNegativeProgresses_withMotionEvent() {
- setHapticScrollTickInterval(100);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 20);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ -90);
-
- assertNoFeedback(mView);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 10);
-
- assertNoFeedback(mView);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ -50);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 1);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 40);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 50);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 60);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 2);
- }
-
- @Test
- public void testScrollProgress_positiveAndNegativeProgresses_withDeviceIdAndSource() {
+ public void testScrollProgress_positiveAndNegativeProgresses() {
setHapticScrollTickInterval(100);
mProvider.onScrollProgress(
@@ -348,19 +213,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollProgress_singleProgressExceedsThreshold_withMotionEvent() {
- setHapticScrollTickInterval(100);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(),
- MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ 1000);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 1);
- }
-
- @Test
- public void testScrollProgress_singleProgressExceedsThreshold_withDeviceIdAndSource() {
+ public void testScrollProgress_singleProgressExceedsThreshold() {
setHapticScrollTickInterval(100);
mProvider.onScrollProgress(
@@ -371,17 +224,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_startAndEndLimit_playsOnlyOneFeedback_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ true);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
- }
-
- @Test
- public void testScrollLimit_startAndEndLimit_playsOnlyOneFeedback_withDeviceIdAndSource() {
+ public void testScrollLimit_startAndEndLimit_playsOnlyOneFeedback() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -393,17 +236,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_doubleStartLimit_playsOnlyOneFeedback_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ true);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ true);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
- }
-
- @Test
- public void testScrollLimit_doubleStartLimit_playsOnlyOneFeedback_withDeviceIdAndSource() {
+ public void testScrollLimit_doubleStartLimit_playsOnlyOneFeedback() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ true);
@@ -415,17 +248,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_doubleEndLimit_playsOnlyOneFeedback_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT);
- }
-
- @Test
- public void testScrollLimit_doubleEndLimit_playsOnlyOneFeedback_withDeviceIdAndSource() {
+ public void testScrollLimit_doubleEndLimit_playsOnlyOneFeedback() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -439,14 +262,15 @@ public final class HapticScrollFeedbackProviderTest {
@Test
public void testScrollLimit_notEnabledWithZeroProgress() {
mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(INPUT_DEVICE_1), MotionEvent.AXIS_SCROLL,
+ INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
mProvider.onScrollProgress(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* deltaInPixels= */ 0);
mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ true);
+ INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
+ /* isStart= */ true);
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -455,20 +279,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_enabledWithProgress_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 80);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
- }
-
- @Test
- public void testScrollLimit_enabledWithProgress_withDeviceIdAndSource() {
+ public void testScrollLimit_enabledWithProgress() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -484,19 +295,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_enabledWithSnap_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- mProvider.onSnapToItem(createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
- }
-
- @Test
- public void testScrollLimit_enabledWithSnap_withDeviceIdAndSource() {
+ public void testScrollLimit_enabledWithSnap() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -511,19 +310,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_enabledWithDissimilarSnap_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- mProvider.onSnapToItem(createTouchMoveEvent(), MotionEvent.AXIS_X);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
- }
-
- @Test
- public void testScrollLimit_enabledWithDissimilarSnap_withDeviceIdAndSource() {
+ public void testScrollLimit_enabledWithDissimilarSnap() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -538,20 +325,7 @@ public final class HapticScrollFeedbackProviderTest {
}
@Test
- public void testScrollLimit_enabledWithDissimilarProgress_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- mProvider.onScrollProgress(
- createTouchMoveEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 80);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
- }
-
- @Test
- public void testScrollLimit_enabledWithDissimilarProgress_withDeviceIdAndSource() {
+ public void testScrollLimit_enabledWithDissimilarProgress() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -566,54 +340,9 @@ public final class HapticScrollFeedbackProviderTest {
assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
}
- @Test
- public void testScrollLimit_enabledWithDissimilarLimit_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- mProvider.onScrollLimit(createTouchMoveEvent(), MotionEvent.AXIS_SCROLL, false);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 3);
- }
@Test
- public void testScrollLimit_enabledWithDissimilarLimit_withDeviceIdAndSource() {
- mProvider.onScrollLimit(
- INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
-
- mProvider.onScrollLimit(INPUT_DEVICE_2, InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.AXIS_X,
- /* isStart= */ false);
- mProvider.onScrollLimit(
- INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 3);
- }
-
- @Test
- public void testScrollLimit_enabledWithMotionFromDifferentDeviceId_withMotionEvent() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(INPUT_DEVICE_1),
- MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
-
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(INPUT_DEVICE_2),
- MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(INPUT_DEVICE_1),
- MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 3);
- }
-
- @Test
- public void testScrollLimit_enabledWithMotionFromDifferentDeviceId_withDeviceIdAndSource() {
+ public void testScrollLimit_enabledWithMotionFromDifferentDeviceId() {
mProvider.onScrollLimit(
INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
/* isStart= */ false);
@@ -632,57 +361,6 @@ public final class HapticScrollFeedbackProviderTest {
assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 3);
}
- @Test
- public void testSnapToItem_differentApis() {
- mProvider.onSnapToItem(
- INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
- mProvider.onSnapToItem(createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_ITEM_FOCUS, 2);
- }
-
- @Test
- public void testScrollLimit_differentApis() {
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(INPUT_DEVICE_1),
- MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
- mProvider.onScrollLimit(
- INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
- /* isStart= */ false);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1);
-
- mProvider.onScrollLimit(
- INPUT_DEVICE_2, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
- /* isStart= */ true);
- mProvider.onScrollLimit(
- createRotaryEncoderScrollEvent(INPUT_DEVICE_2),
- MotionEvent.AXIS_SCROLL,
- /* isStart= */ true);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2);
- }
-
- @Test
- public void testScrollProgress_differentApis() {
- setHapticScrollTickInterval(100);
-
- // Neither types of APIs independently excceeds the "100" tick interval.
- // But the combined deltas pass 100.
- mProvider.onScrollProgress(
- INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ 20);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 40);
- mProvider.onScrollProgress(
- INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL,
- /* deltaInPixels= */ 30);
- mProvider.onScrollProgress(
- createRotaryEncoderScrollEvent(), MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 30);
-
- assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 1);
- }
private void assertNoFeedback(TestView view) {
for (int feedback : new int[] {SCROLL_ITEM_FOCUS, SCROLL_LIMIT, SCROLL_TICK}) {
@@ -715,41 +393,6 @@ public final class HapticScrollFeedbackProviderTest {
.thenReturn(enabled);
}
- private MotionEvent createTouchMoveEvent() {
- long downTime = mCurrentTimeMillis;
- long eventTime = mCurrentTimeMillis + 2; // arbitrary increment from the down time.
- ++mCurrentTimeMillis;
- return MotionEvent.obtain(
- downTime , eventTime, MotionEvent.ACTION_MOVE, /* x= */ 3, /* y= */ 5, 0);
- }
-
- private MotionEvent createRotaryEncoderScrollEvent() {
- return createRotaryEncoderScrollEvent(INPUT_DEVICE_1);
- }
-
- private MotionEvent createRotaryEncoderScrollEvent(int deviceId) {
- MotionEvent.PointerProperties props = new MotionEvent.PointerProperties();
- props.id = 0;
-
- MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
- coords.setAxisValue(MotionEvent.AXIS_SCROLL, 20);
-
- return MotionEvent.obtain(0 /* downTime */,
- ++mCurrentTimeMillis,
- MotionEvent.ACTION_SCROLL,
- /* pointerCount= */ 1,
- new MotionEvent.PointerProperties[] {props},
- new MotionEvent.PointerCoords[] {coords},
- /* metaState= */ 0,
- /* buttonState= */ 0,
- /* xPrecision= */ 0,
- /* yPrecision= */ 0,
- deviceId,
- /* edgeFlags= */ 0,
- InputDevice.SOURCE_ROTARY_ENCODER,
- /* flags= */ 0);
- }
-
private static class TestView extends View {
final Map<Integer, Integer> mFeedbackCount = new HashMap<>();
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
index c46118db617f..f39bddd7f032 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
@@ -88,8 +88,8 @@ public class HandwritingInitiatorTest {
}
private HandwritingInitiator mHandwritingInitiator;
- private View mTestView1;
- private View mTestView2;
+ private EditText mTestView1;
+ private EditText mTestView2;
private Context mContext;
@Before
@@ -123,6 +123,9 @@ public class HandwritingInitiatorTest {
@Test
public void onTouchEvent_startHandwriting_when_stylusMoveOnce_withinHWArea() {
+ mTestView1.setText("hello");
+ when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
+
mHandwritingInitiator.onInputConnectionCreated(mTestView1);
final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
@@ -141,6 +144,9 @@ public class HandwritingInitiatorTest {
// After IMM.startHandwriting is triggered, onTouchEvent should return true for ACTION_MOVE
// events so that the events are not dispatched to the view tree.
assertThat(onTouchEventResult2).isTrue();
+ // Since the stylus down point was inside the TextView's bounds, the handwriting initiator
+ // does not need to set the cursor position.
+ verify(mTestView1, never()).setSelection(anyInt());
}
@Test
@@ -185,6 +191,9 @@ public class HandwritingInitiatorTest {
@Test
public void onTouchEvent_startHandwriting_when_stylusMove_withinExtendedHWArea() {
+ mTestView1.setText("hello");
+ when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
+
mHandwritingInitiator.onInputConnectionCreated(mTestView1);
final int x1 = sHwArea1.left - HW_BOUNDS_OFFSETS_LEFT_PX / 2;
final int y1 = sHwArea1.top - HW_BOUNDS_OFFSETS_TOP_PX / 2;
@@ -199,6 +208,9 @@ public class HandwritingInitiatorTest {
// Stylus movement within extended HandwritingArea should trigger IMM.startHandwriting once.
verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView1);
+ // Since the stylus down point was outside the TextView's bounds, the handwriting initiator
+ // sets the cursor position.
+ verify(mTestView1).setSelection(4);
}
@Test
@@ -221,6 +233,8 @@ public class HandwritingInitiatorTest {
@Test
public void onTouchEvent_startHandwriting_inputConnectionBuilt_stylusMoveInExtendedHWArea() {
+ mTestView1.setText("hello");
+ when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
// The stylus down point is between mTestView1 and mTestView2, but it is within the
// extended handwriting area of both views. It is closer to mTestView1.
final int x1 = sHwArea1.right + HW_BOUNDS_OFFSETS_RIGHT_PX / 2;
@@ -241,6 +255,9 @@ public class HandwritingInitiatorTest {
// the stylus down point is closest to this view.
mHandwritingInitiator.onInputConnectionCreated(mTestView1);
verify(mHandwritingInitiator).startHandwriting(mTestView1);
+ // Since the stylus down point was outside the TextView's bounds, the handwriting initiator
+ // sets the cursor position.
+ verify(mTestView1).setSelection(4);
}
@Test
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java b/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
index b4c72ca3226b..3b2ab4c8bb50 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingTestUtil.java
@@ -16,6 +16,9 @@
package android.view.stylus;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -26,22 +29,23 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.EditText;
import androidx.test.platform.app.InstrumentationRegistry;
public class HandwritingTestUtil {
- public static View createView(Rect handwritingArea) {
+ public static EditText createView(Rect handwritingArea) {
return createView(handwritingArea, true /* autoHandwritingEnabled */,
true /* isStylusHandwritingAvailable */);
}
- public static View createView(Rect handwritingArea, boolean autoHandwritingEnabled,
+ public static EditText createView(Rect handwritingArea, boolean autoHandwritingEnabled,
boolean isStylusHandwritingAvailable) {
return createView(handwritingArea, autoHandwritingEnabled, isStylusHandwritingAvailable,
0, 0, 0, 0);
}
- public static View createView(Rect handwritingArea, boolean autoHandwritingEnabled,
+ public static EditText createView(Rect handwritingArea, boolean autoHandwritingEnabled,
boolean isStylusHandwritingAvailable,
float handwritingBoundsOffsetLeft, float handwritingBoundsOffsetTop,
float handwritingBoundsOffsetRight, float handwritingBoundsOffsetBottom) {
@@ -68,7 +72,7 @@ public class HandwritingTestUtil {
}
};
- View view = spy(new View(context));
+ EditText view = spy(new EditText(context));
when(view.isAttachedToWindow()).thenReturn(true);
when(view.isAggregatedVisible()).thenReturn(true);
when(view.isStylusHandwritingAvailable()).thenReturn(isStylusHandwritingAvailable);
@@ -77,6 +81,13 @@ public class HandwritingTestUtil {
when(view.getHandwritingBoundsOffsetTop()).thenReturn(handwritingBoundsOffsetTop);
when(view.getHandwritingBoundsOffsetRight()).thenReturn(handwritingBoundsOffsetRight);
when(view.getHandwritingBoundsOffsetBottom()).thenReturn(handwritingBoundsOffsetBottom);
+ doAnswer(invocation -> {
+ int[] outLocation = invocation.getArgument(0);
+ outLocation[0] = handwritingArea.left;
+ outLocation[1] = handwritingArea.top;
+ return null;
+ }).when(view).getLocationInWindow(any());
+ when(view.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(0);
view.setAutoHandwritingEnabled(autoHandwritingEnabled);
parent.addView(view);
return view;
diff --git a/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java b/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java
index a49bb6af13d2..109c8080de94 100644
--- a/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java
+++ b/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java
@@ -17,7 +17,9 @@
package android.widget;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import android.content.Context;
import android.platform.test.annotations.Presubmit;
import android.util.PollingCheck;
@@ -32,6 +34,9 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
@RunWith(AndroidJUnit4.class)
@MediumTest
@Presubmit
@@ -49,23 +54,43 @@ public class ScrollViewFunctionalTest {
}
@Test
- public void testScrollAfterFlingTop() {
- mScrollView.scrollTo(0, 100);
- mScrollView.fling(-10000);
- PollingCheck.waitFor(() -> mScrollView.mEdgeGlowTop.getDistance() > 0);
- PollingCheck.waitFor(() -> mScrollView.mEdgeGlowTop.getDistance() == 0f);
+ public void testScrollAfterFlingTop() throws Throwable {
+ WatchedEdgeEffect edgeEffect = new WatchedEdgeEffect(mActivity);
+ mScrollView.mEdgeGlowTop = edgeEffect;
+ mActivityRule.runOnUiThread(() -> mScrollView.scrollTo(0, 100));
+ mActivityRule.runOnUiThread(() -> mScrollView.fling(-10000));
+ assertTrue(edgeEffect.onAbsorbLatch.await(1, TimeUnit.SECONDS));
+ mActivityRule.runOnUiThread(() -> {}); // let the absorb takes effect -- least one frame
+ PollingCheck.waitFor(() -> edgeEffect.getDistance() == 0f);
assertEquals(0, mScrollView.getScrollY());
}
@Test
- public void testScrollAfterFlingBottom() {
+ public void testScrollAfterFlingBottom() throws Throwable {
+ WatchedEdgeEffect edgeEffect = new WatchedEdgeEffect(mActivity);
+ mScrollView.mEdgeGlowBottom = edgeEffect;
int childHeight = mScrollView.getChildAt(0).getHeight();
int maxScroll = childHeight - mScrollView.getHeight();
- mScrollView.scrollTo(0, maxScroll - 100);
- mScrollView.fling(10000);
- PollingCheck.waitFor(() -> mScrollView.mEdgeGlowBottom.getDistance() > 0);
- PollingCheck.waitFor(() -> mScrollView.mEdgeGlowBottom.getDistance() == 0f);
+ mActivityRule.runOnUiThread(() -> mScrollView.scrollTo(0, maxScroll - 100));
+ mActivityRule.runOnUiThread(() -> mScrollView.fling(10000));
+ assertTrue(edgeEffect.onAbsorbLatch.await(1, TimeUnit.SECONDS));
+ mActivityRule.runOnUiThread(() -> {}); // let the absorb takes effect -- least one frame
+ PollingCheck.waitFor(() -> edgeEffect.getDistance() == 0f);
assertEquals(maxScroll, mScrollView.getScrollY());
}
+
+ static class WatchedEdgeEffect extends EdgeEffect {
+ public CountDownLatch onAbsorbLatch = new CountDownLatch(1);
+
+ WatchedEdgeEffect(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onAbsorb(int velocity) {
+ super.onAbsorb(velocity);
+ onAbsorbLatch.countDown();
+ }
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverAppPredictorCallbackTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverAppPredictorCallbackTest.java
new file mode 100644
index 000000000000..4aca854469f2
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverAppPredictorCallbackTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.app;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.prediction.AppTarget;
+import android.app.prediction.AppTargetId;
+import android.os.UserHandle;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+@RunWith(AndroidJUnit4.class)
+public class ResolverAppPredictorCallbackTest {
+ private class Callback implements Consumer<List<AppTarget>> {
+ public int count = 0;
+ public List<AppTarget> latest = null;
+ @Override
+ public void accept(List<AppTarget> appTargets) {
+ count++;
+ latest = appTargets;
+ }
+ };
+
+ @Test
+ public void testAsConsumer() {
+ Callback callback = new Callback();
+ ResolverAppPredictorCallback wrapped = new ResolverAppPredictorCallback(callback);
+ assertThat(callback.count).isEqualTo(0);
+
+ List<AppTarget> targets = createAppTargetList();
+ wrapped.asConsumer().accept(targets);
+
+ assertThat(callback.count).isEqualTo(1);
+ assertThat(callback.latest).isEqualTo(targets);
+
+ wrapped.destroy();
+
+ // Shouldn't do anything:
+ wrapped.asConsumer().accept(targets);
+
+ assertThat(callback.count).isEqualTo(1);
+ }
+
+ @Test
+ public void testAsCallback() {
+ Callback callback = new Callback();
+ ResolverAppPredictorCallback wrapped = new ResolverAppPredictorCallback(callback);
+ assertThat(callback.count).isEqualTo(0);
+
+ List<AppTarget> targets = createAppTargetList();
+ wrapped.asCallback().onTargetsAvailable(targets);
+
+ assertThat(callback.count).isEqualTo(1);
+ assertThat(callback.latest).isEqualTo(targets);
+
+ wrapped.destroy();
+
+ // Shouldn't do anything:
+ wrapped.asConsumer().accept(targets);
+
+ assertThat(callback.count).isEqualTo(1);
+ }
+
+ @Test
+ public void testAsConsumer_null() {
+ Callback callback = new Callback();
+ ResolverAppPredictorCallback wrapped = new ResolverAppPredictorCallback(callback);
+ assertThat(callback.count).isEqualTo(0);
+
+ wrapped.asConsumer().accept(null);
+
+ assertThat(callback.count).isEqualTo(1);
+ assertThat(callback.latest).isEmpty();
+
+ wrapped.destroy();
+
+ // Shouldn't do anything:
+ wrapped.asConsumer().accept(null);
+
+ assertThat(callback.count).isEqualTo(1);
+ }
+
+ private List<AppTarget> createAppTargetList() {
+ AppTarget.Builder builder = new AppTarget.Builder(
+ new AppTargetId("ID"), "package", UserHandle.CURRENT);
+ return List.of(builder.build());
+ }
+}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 3206dd2123d5..69aa40156e78 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -235,6 +235,7 @@ applications that come with the platform
<privapp-permissions package="com.android.shell">
<!-- Needed for test only -->
+ <permission name="android.permission.CAMERA_HEADLESS_SYSTEM_USER"/>
<permission name="android.permission.MANAGE_HEALTH_DATA"/>
<permission name="android.permission.LAUNCH_DEVICE_MANAGER_SETUP"/>
<permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index ee2eacfd304f..fb53e9136567 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -253,12 +253,6 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1883484959": {
- "message": "Content Recording: Display %d state is now (%d), so update recording?",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-1872288685": {
"message": "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b Callers=%s",
"level": "VERBOSE",
@@ -2377,6 +2371,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimationController.java"
},
+ "34106798": {
+ "message": "Content Recording: Display %d state was (%d), is now (%d), so update recording?",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"34682671": {
"message": "Not moving display (displayId=%d) to top. Top focused displayId=%d. Reason: FLAG_STEAL_TOP_FOCUS_DISABLED",
"level": "INFO",
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
index ace2053cc1a7..9d3fca86903b 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
@@ -195,7 +195,7 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
if (!ACCEPTED_SIGNING_SCHEMES.contains(key.getAlgorithm().toLowerCase())) {
throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
- + ". Only" + Arrays.toString(ACCEPTED_SIGNING_SCHEMES.stream().toArray())
+ + ". Only " + Arrays.toString(ACCEPTED_SIGNING_SCHEMES.stream().toArray())
+ " supported");
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java
index 931c2f864eba..d5fb49a5cb94 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreRSASignatureSpi.java
@@ -189,7 +189,7 @@ abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSp
protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) {
throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
- + ". Only" + KeyProperties.KEY_ALGORITHM_RSA + " supported");
+ + ". Only " + KeyProperties.KEY_ALGORITHM_RSA + " supported");
}
super.initKey(key);
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
index 0112e32e05a7..15d14e87fcf6 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
@@ -213,9 +213,6 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
if (mRearDisplayStateRequest != null || isRearDisplayActive()) {
mRearDisplayStateRequest = null;
mDeviceStateManager.cancelStateRequest();
- } else {
- throw new IllegalStateException(
- "Unable to cancel a rear display session as there is no active session");
}
}
}
@@ -432,10 +429,6 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
synchronized (mLock) {
if (mRearDisplayPresentationController != null) {
mDeviceStateManager.cancelStateRequest();
- } else {
- throw new IllegalStateException(
- "Unable to cancel a rear display presentation session as there is no "
- + "active session");
}
}
}
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index e9abc7e522d5..c72a42cce2bd 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -158,6 +158,7 @@ android_library {
"kotlinx-coroutines-android",
"kotlinx-coroutines-core",
"iconloader_base",
+ "com_android_wm_shell_flags_lib",
"WindowManager-Shell-proto",
"dagger2",
"jsr330",
diff --git a/libs/WindowManager/Shell/aconfig/Android.bp b/libs/WindowManager/Shell/aconfig/Android.bp
new file mode 100644
index 000000000000..1a98ffcea9e7
--- /dev/null
+++ b/libs/WindowManager/Shell/aconfig/Android.bp
@@ -0,0 +1,12 @@
+aconfig_declarations {
+ name: "com_android_wm_shell_flags",
+ package: "com.android.wm.shell",
+ srcs: [
+ "multitasking.aconfig",
+ ],
+}
+
+java_aconfig_library {
+ name: "com_android_wm_shell_flags_lib",
+ aconfig_declarations: "com_android_wm_shell_flags",
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
new file mode 100644
index 000000000000..d55a41fc0cf7
--- /dev/null
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.wm.shell"
+
+flag {
+ name: "example_flag"
+ namespace: "multitasking"
+ description: "An Example Flag"
+ bug: "300136750"
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 4f763425b601..6622973007b4 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Het dit"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen onlangse borrels nie"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Onlangse borrels en borrels wat toegemaak is, sal hier verskyn"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Beheer borrels enige tyd"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tik hier om te bestuur watter apps en gesprekke in borrels kan verskyn"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 1e5f5f136315..a3f77411b0f6 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ገባኝ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ምንም የቅርብ ጊዜ አረፋዎች የሉም"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"የቅርብ ጊዜ አረፋዎች እና የተሰናበቱ አረፋዎች እዚህ ብቅ ይላሉ"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"በማንኛውም ጊዜ ዓረፋዎችን ይቆጣጠሩ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"የትኛዎቹ መተግበሪያዎች እና ውይይቶች ዓረፋ መፍጠር እንደሚችሉ ለማስተዳደር እዚህ ጋር መታ ያድርጉ"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 9c52608a8d23..ee4302e461df 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"حسنًا"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ليس هناك فقاعات محادثات"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ستظهر هنا أحدث فقاعات المحادثات وفقاعات المحادثات التي تم إغلاقها."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"التحكّم في إظهار الفقاعات في أي وقت"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"انقر هنا للتحكّم في إظهار فقاعات التطبيقات والمحادثات التي تريدها."</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index e880b8744f40..a568d5841d32 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"বুজি পালোঁ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"কোনো শেহতীয়া bubbles নাই"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"শেহতীয়া bubbles আৰু অগ্ৰাহ্য কৰা bubbles ইয়াত প্ৰদর্শিত হ\'ব"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"যিকোনো সময়তে বাবল নিয়ন্ত্ৰণ কৰক"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"কোনবোৰ এপ্‌ আৰু বাৰ্তালাপ বাবল হ’ব পাৰে সেয়া পৰিচালনা কৰিবলৈ ইয়াত টিপক"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 6e746fb761f0..1a681e1c63a6 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Anladım"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Yumrucuqlar yoxdur"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Son yumrucuqlar və buraxılmış yumrucuqlar burada görünəcək"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Yumrucuqları idarə edin"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Bura toxunaraq yumrucuq göstərəcək tətbiq və söhbətləri idarə edin"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 3be326907cd2..cba293b20c3d 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Važi"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Ovde se prikazuju nedavni i odbačeni oblačići"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrolišite oblačiće u svakom trenutku"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dodirnite ovde i odredite koje aplikacije i konverzacije mogu da imaju oblačić"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 85ae1c10617c..80e5a677e86d 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Зразумела"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Няма нядаўніх усплывальных апавяшчэнняў"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Нядаўнія і адхіленыя ўсплывальныя апавяшчэнні будуць паказаны тут"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Кіруйце наладамі ўсплывальных апавяшчэнняў у любы час"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Каб кіраваць усплывальнымі апавяшчэннямі для праграм і размоў, націсніце тут"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 640fb2e0ef92..ca5923919d36 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Разбрах"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Няма скорошни балончета"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Скорошните и отхвърлените балончета ще се показват тук"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Управление на балончетата по всяко време"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Докоснете тук, за да управл. кои прил. и разговори могат да показват балончета"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index e7c8886a99be..c1eb469f73a4 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"বুঝেছি"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"কোনও সাম্প্রতিক বাবল নেই"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"সাম্প্রতিক ও বাতিল করা বাবল এখানে দেখা যাবে"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"যেকোনও সময় বাবল নিয়ন্ত্রণ করুন"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"কোন অ্যাপ ও কথোপকথনের জন্য বাবলের সুবিধা চান তা ম্যানেজ করতে এখানে ট্যাপ করুন"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 1335f8d897be..c97fc3dffb6d 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Razumijem"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nedavni i odbačeni oblačići će se pojaviti ovdje"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Upravljajte oblačićima u svakom trenutku"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dodirnite ovdje da upravljate time koje aplikacije i razgovori mogu imati oblačić"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 22fc21c64e09..a9195e4dbc03 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entesos"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No hi ha bombolles recents"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bombolles recents i les ignorades es mostraran aquí"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controla les bombolles en qualsevol moment"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toca aquí per gestionar quines aplicacions i converses poden fer servir bombolles"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index a85fa7c9435d..89bd22203c8c 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Žádné nedávné bubliny"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Zde se budou zobrazovat nedávné bubliny a zavřené bubliny"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Nastavení bublin můžete kdykoli upravit"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Klepnutím sem lze spravovat, které aplikace a konverzace mohou vytvářet bubliny"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index cd621f802d91..fd880bcfbd0c 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ingen seneste bobler"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nye bobler og afviste bobler vises her"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Administrer bobler når som helst"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tryk her for at administrere, hvilke apps og samtaler der kan vises i bobler"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 366fdefc3013..b28394d27e9a 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Keine kürzlich geschlossenen Bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Hier werden aktuelle und geschlossene Bubbles angezeigt"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bubble-Einstellungen festlegen"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tippe hier, um zu verwalten, welche Apps und Unterhaltungen als Bubble angezeigt werden können"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index a449b9f3c665..684c3bbddd82 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Το κατάλαβα"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Δεν υπάρχουν πρόσφατα συννεφάκια"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Τα πρόσφατα συννεφάκια και τα συννεφάκια που παραβλέψατε θα εμφανίζονται εδώ."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Ελέγξτε τα συννεφάκια ανά πάσα στιγμή."</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Πατήστε εδώ για τη διαχείριση εφαρμογών και συζητήσεων που προβάλλουν συννεφάκια"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index c7dd3882734b..1890c3d28591 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles at any time"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 99da073cb2c2..72189df6d65d 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -76,6 +76,8 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Got it"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string>
+ <string name="bubble_bar_education_stack_title" msgid="2486903590422497245">"Chat using bubbles"</string>
+ <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"New conversations appear as icons in a bottom corner of your screen. Tap to expand them or drag to dismiss them."</string>
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles anytime"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index c7dd3882734b..1890c3d28591 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles at any time"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index c7dd3882734b..1890c3d28591 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles at any time"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index cc19579c1216..294bdb5edf3b 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -76,6 +76,8 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎Got it‎‏‎‎‏‎"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‎No recent bubbles‎‏‎‎‏‎"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎Recent bubbles and dismissed bubbles will appear here‎‏‎‎‏‎"</string>
+ <string name="bubble_bar_education_stack_title" msgid="2486903590422497245">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎Chat using bubbles‎‏‎‎‏‎"</string>
+ <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎New conversations appear as icons in a bottom corner of your screen. Tap to expand them or drag to dismiss them.‎‏‎‎‏‎"</string>
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎Control bubbles anytime‎‏‎‎‏‎"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎Tap here to manage which apps and conversations can bubble‎‏‎‎‏‎"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎Bubble‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 80d10f26e4e9..54f2de06e5fb 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No hay burbujas recientes"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Las burbujas recientes y las que se descartaron aparecerán aquí"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controla las burbujas"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Presiona para administrar las apps y conversaciones que pueden mostrar burbujas"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 13dfce03b775..19a8a1402022 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No hay burbujas recientes"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Las burbujas recientes y las cerradas aparecerán aquí"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controla las burbujas cuando quieras"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toca aquí para gestionar qué aplicaciones y conversaciones pueden usar burbujas"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 269968f48c77..c0558e4fc95e 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Selge"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Hiljutisi mulle pole"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Siin kuvatakse hiljutised ja suletud mullid."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Juhtige mulle igal ajal"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Puudutage siin, et hallata, milliseid rakendusi ja vestlusi saab mullina kuvada"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index b4a8d57abc94..7610f0dc4312 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ados"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ez dago azkenaldiko burbuilarik"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Azken burbuilak eta baztertutakoak agertuko dira hemen"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrolatu burbuilak edonoiz"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Sakatu hau burbuiletan zein aplikazio eta elkarrizketa ager daitezkeen kudeatzeko"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 434bfe11db4e..f1fb51fa5ece 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"متوجه‌ام"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"هیچ حبابک جدیدی وجود ندارد"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حبابک‌های اخیر و حبابک‌های ردشده اینجا ظاهر خواهند شد"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"کنترل حبابک‌ها در هرزمانی"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"برای مدیریت اینکه کدام برنامه‌ها و مکالمه‌ها حباب داشته باشند، ضربه بزنید"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index a04ef1252aa8..526925531ac0 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Okei"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ei viimeaikaisia kuplia"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Viimeaikaiset ja äskettäin ohitetut kuplat näkyvät täällä"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Muuta kuplien asetuksia milloin tahansa"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Valitse napauttamalla tästä, mitkä sovellukset ja keskustelut voivat kuplia"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index fbc619144f71..cd85f402cfab 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Aucune bulle récente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bulles récentes et les bulles ignorées s\'afficheront ici"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Gérez les bulles en tout temps"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Touchez ici pour gérer les applis et les conversations à inclure aux bulles"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index e1fe2917a729..23ba785363f7 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Aucune bulle récente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bulles récentes et ignorées s\'afficheront ici"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Contrôlez les bulles à tout moment"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Appuyez ici pour gérer les applis et conversations s\'affichant dans des bulles"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 485a89502c86..8693e42118fc 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -76,17 +76,18 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Non hai burbullas recentes"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"As burbullas recentes e ignoradas aparecerán aquí."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controlar as burbullas"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toca para xestionar as aplicacións e conversas que poden aparecer en burbullas"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string>
- <!-- no translation found for restart_button_description (4564728020654658478) -->
- <skip />
- <!-- no translation found for user_aspect_ratio_settings_button_hint (734835849600713016) -->
- <skip />
- <!-- no translation found for user_aspect_ratio_settings_button_description (4315566801697411684) -->
- <skip />
+ <string name="restart_button_description" msgid="4564728020654658478">"Toca o botón para reiniciar esta aplicación e gozar dunha mellor visualización"</string>
+ <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambia a proporción desta aplicación en Configuración"</string>
+ <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambiar a proporción"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tes problemas coa cámara?\nToca para reaxustala"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 365faef85ff6..a7cdf7352189 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"સમજાઈ ગયું"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"તાજેતરના કોઈ બબલ નથી"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"એકદમ નવા બબલ અને છોડી દીધેલા બબલ અહીં દેખાશે"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"બબલને કોઈપણ સમયે નિયંત્રિત કરે છે"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"કઈ ઍપ અને વાતચીતોને બબલ કરવા માગો છો તે મેનેજ કરવા માટે, અહીં ટૅપ કરો"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 76579d10b695..13e0258ce87b 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ठीक है"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के कोई बबल्स नहीं हैं"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हाल ही के बबल्स और हटाए गए बबल्स यहां दिखेंगे"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"जब चाहें, बबल्स की सुविधा को कंट्रोल करें"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"किसी ऐप्लिकेशन और बातचीत के लिए बबल की सुविधा को मैनेज करने के लिए यहां टैप करें"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index de071f1b959d..957e56c35e87 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Shvaćam"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Ovdje će se prikazivati nedavni i odbačeni oblačići"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Upravljanje oblačićima u svakom trenutku"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dodirnite ovdje da biste odredili koje aplikacije i razgovori mogu imati oblačić"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index b5631bbf0152..e9808ac6c2be 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Értem"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nincsenek buborékok a közelmúltból"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"A legutóbbi és az elvetett buborékok itt jelennek majd meg"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Buborékok vezérlése bármikor"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ide koppintva jeleníthetők meg az alkalmazások és a beszélgetések buborékként"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 2d5d371df41e..8a9d89bd879f 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Եղավ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ամպիկներ չկան"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Այստեղ կցուցադրվեն վերջերս օգտագործված և փակված ամպիկները, որոնք կկարողանաք հեշտությամբ վերաբացել"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Ամպիկների կարգավորումներ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Հպեք այստեղ՝ ընտրելու, թե որ հավելվածների և զրույցների համար ամպիկներ ցուցադրել"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 90b1f152d035..6b84a1d9bdac 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Oke"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Tidak ada balon baru-baru ini"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Balon yang baru dipakai dan balon yang telah ditutup akan muncul di sini"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrol balon kapan saja"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ketuk di sini untuk mengelola balon aplikasi dan percakapan"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 813f9e6f4021..913e1964c4df 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ég skil"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Engar nýlegar blöðrur"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nýlegar blöðrur og blöðrur sem þú hefur lokað birtast hér"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Hægt er að stjórna blöðrum hvenær sem er"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ýttu hér til að stjórna því hvaða forrit og samtöl mega nota blöðrur."</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 8918821a8f27..575210bffc7d 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nessuna bolla recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Le bolle recenti e ignorate appariranno qui"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Gestisci le bolle in qualsiasi momento"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tocca qui per gestire le app e le conversazioni per cui mostrare le bolle"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string>
@@ -90,7 +94,7 @@
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Visualizza più contenuti e fai di più"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Trascina in un\'altra app per usare lo schermo diviso"</string>
<string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tocca due volte fuori da un\'app per riposizionarla"</string>
- <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+ <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string>
<string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Espandi per avere ulteriori informazioni."</string>
<string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vuoi riavviare per migliorare la visualizzazione?"</string>
<string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Puoi riavviare l\'app affinché venga visualizzata meglio sullo schermo, ma potresti perdere i tuoi progressi o eventuali modifiche non salvate"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 4d7a0936a3e0..fbc384f1be67 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"הבנתי"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"אין בועות מהזמן האחרון"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"בועות אחרונות ובועות שנסגרו יופיעו כאן"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"שליטה בבועות בכל זמן"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"אפשר להקיש כאן כדי לקבוע אילו אפליקציות ושיחות יוכלו להופיע בבועות"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 96683590d097..dce3a18f8cd0 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近閉じたバブルはありません"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"最近表示されたバブルや閉じたバブルが、ここに表示されます"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"バブルはいつでも管理可能"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"バブルで表示するアプリや会話を管理するには、ここをタップします"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index a949a18fd449..b396c8c89046 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"გასაგებია"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ბოლო დროს გამოყენებული ბუშტები არ არის"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"აქ გამოჩნდება ბოლოდროინდელი ბუშტები და უარყოფილი ბუშტები"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ამოხტომის გაკონტროლება ნებისმიერ დროს"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"აქ შეეხეთ იმის სამართავად, თუ რომელი აპები და საუბრები ამოხტეს"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index cbc924907cac..63ef3d2000dd 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Түсінікті"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Жақындағы қалқыма хабарлар жоқ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Соңғы және жабылған қалқыма хабарлар осы жерде көрсетіледі."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Қалқыма хабарларды кез келген уақытта басқарыңыз"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Қалқыма хабарда көрсетілетін қолданбалар мен әңгімелерді реттеу үшін осы жерді түртіңіз."</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 3e36113995d9..2ce8ba37b3bf 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"យល់ហើយ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"មិនមាន​ពពុះ​ថ្មីៗ​ទេ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ពពុះថ្មីៗ​ និង​ពពុះដែលបានបិទ​​នឹង​បង្ហាញ​នៅទីនេះ"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"គ្រប់គ្រង​ផ្ទាំងអណ្ដែតនៅពេលណាក៏បាន"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ចុចត្រង់នេះ ដើម្បីគ្រប់គ្រងកម្មវិធី និងការសន្ទនាដែលអាចបង្ហាញជាផ្ទាំងអណ្ដែត"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 5e0dad8255b4..4b8aaa93b2a7 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ಅರ್ಥವಾಯಿತು"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಬಬಲ್ಸ್ ಇಲ್ಲ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ಇತ್ತೀಚಿನ ಬಬಲ್ಸ್ ಮತ್ತು ವಜಾಗೊಳಿಸಿದ ಬಬಲ್ಸ್ ಇಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಬಬಲ್ಸ್ ಅನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ಯಾವ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಸಂಭಾಷಣೆಗಳನ್ನು ಬಬಲ್ ಮಾಡಬಹುದು ಎಂಬುದನ್ನು ನಿರ್ವಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index f1b34556954e..ffa77b0dc0e2 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"확인"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"최근 대화창 없음"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"최근 대화창과 내가 닫은 대화창이 여기에 표시됩니다."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"언제든지 대화창을 제어하세요"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"대화창을 만들 수 있는 앱과 대화를 관리하려면 여기를 탭하세요."</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 200359aded72..b74875c5885a 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Түшүндүм"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Азырынча эч нерсе жок"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Акыркы жана жабылган калкып чыкма билдирмелер ушул жерде көрүнөт"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Калкып чыкма билдирме түрүндө көрүнө турган колдонмолор менен маектерди тандоо үчүн бул жерди таптаңыз"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 43835d5afa67..3e1ab6d28eeb 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ເຂົ້າໃຈແລ້ວ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ບໍ່ມີຟອງຫຼ້າສຸດ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ຟອງຫຼ້າສຸດ ແລະ ຟອງທີ່ປິດໄປຈະປາກົດຢູ່ບ່ອນນີ້"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ຄວບຄຸມຟອງໄດ້ທຸກເວລາ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ແຕະບ່ອນນີ້ເພື່ອຈັດການແອັບ ແລະ ການສົນທະນາທີ່ສາມາດສະແດງເປັນແບບຟອງໄດ້"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 0c6cc58aa1ec..f4751aae323d 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Supratau"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nėra naujausių burbulų"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Naujausi ir atsisakyti burbulai bus rodomi čia"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bet kada valdyti burbulus"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Palietę čia valdykite, kurie pokalbiai ir programos gali būti rodomi burbuluose"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index f86e937edd33..5fab5778d3d5 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Labi"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nav nesen aizvērtu burbuļu"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Šeit būs redzami nesen rādītie burbuļi un aizvērtie burbuļi"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Pārvaldīt burbuļus jebkurā laikā"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Pieskarieties šeit, lai pārvaldītu, kuras lietotnes un sarunas var rādīt burbulī"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 49e850fac1c0..906fc094ea5a 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Сфатив"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нема неодамнешни балончиња"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Неодамнешните и отфрлените балончиња ќе се појавуваат тука"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Контролирајте ги балончињата во секое време"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Допрете тука за да одредите на кои апл. и разговори може да се појават балончиња"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index fbb5514e4648..65e6d2c4c8e7 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"മനസ്സിലായി"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"അടുത്തിടെയുള്ള ബബിളുകൾ ഒന്നുമില്ല"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"അടുത്തിടെയുള്ള ബബിളുകൾ, ഡിസ്മിസ് ചെയ്ത ബബിളുകൾ എന്നിവ ഇവിടെ ദൃശ്യമാവും"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ബബിളുകൾ ഏതുസമയത്തും നിയന്ത്രിക്കുക"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ഏതൊക്കെ ആപ്പുകളും സംഭാഷണങ്ങളും ബബിൾ ചെയ്യാനാകുമെന്നത് മാനേജ് ചെയ്യാൻ ഇവിടെ ടാപ്പ് ചെയ്യുക"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 8274f4456c57..44c594691e36 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ойлголоо"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Саяхны бөмбөлөг алга байна"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Саяхны бөмбөлгүүд болон үл хэрэгссэн бөмбөлгүүд энд харагдана"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Бөмбөлгүүдийг хүссэн үедээ хянах"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ямар апп болон харилцан ярианууд бөмбөлгөөр харагдахыг энд удирдана уу"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index c1f3e123ac41..bd898c4395ee 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"समजले"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"अलीकडील कोणतेही बबल नाहीत"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"अलीकडील बबल आणि डिसमिस केलेले बबल येथे दिसतील"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"बबल कधीही नियंत्रित करा"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"कोणती ॲप्स आणि संभाषणे बबल होऊ शकतात हे व्यवस्थापित करण्यासाठी येथे टॅप करा"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 82d84e8da6d9..86a7025f5e39 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Tiada gelembung terbaharu"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Gelembung baharu dan gelembung yang diketepikan akan dipaparkan di sini"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kawal gelembung pada bila-bila masa"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ketik di sini untuk mengurus apl dan perbualan yang boleh menggunakan gelembung"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 2e88ab341984..4c494eb586a2 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"နားလည်ပြီ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"လတ်တလော ပူဖောင်းကွက်များ မရှိပါ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"လတ်တလော ပူဖောင်းကွက်များနှင့် ပိတ်လိုက်သော ပူဖောင်းကွက်များကို ဤနေရာတွင် မြင်ရပါမည်"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ပူဖောင်းကွက်ကို အချိန်မရွေး ထိန်းချုပ်ရန်"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ပူဖောင်းကွက်သုံးနိုင်သည့် အက်ပ်နှင့် စကားဝိုင်းများ စီမံရန် ဤနေရာကို တို့ပါ"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index f7ea9ce78dd8..e9f90c0cb0ea 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Greit"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ingen nylige bobler"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nylige bobler og avviste bobler vises her"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontroller bobler når som helst"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Trykk her for å administrere hvilke apper og samtaler som kan vises i bobler"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 3f6dc046c10b..dcfff7c30a1a 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"बुझेँ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हालैका बबलहरू छैनन्"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हालैका बबल र खारेज गरिएका बबलहरू यहाँ देखिने छन्"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"जुनसुकै बेला बबलसम्बन्धी सुविधा नियन्त्रण गर्नुहोस्"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"कुन एप र कुराकानी बबल प्रयोग गर्न सक्छन् भन्ने कुराको व्यवस्थापन गर्न यहाँ ट्याप गर्नुहोस्"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 978ed3ccad3c..2f560f04205c 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen recente bubbels"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recente bubbels en gesloten bubbels zie je hier"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bubbels beheren wanneer je wilt"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tik hier om te beheren welke apps en gesprekken als bubbel kunnen worden getoond"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index b66448b6308f..ad25de51a3e7 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ବୁଝିଗଲି"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ବର୍ତ୍ତମାନ କୌଣସି ବବଲ୍ ନାହିଁ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ବର୍ତ୍ତମାନର ଏବଂ ଖାରଜ କରାଯାଇଥିବା ବବଲଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯିବ"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ଯେ କୌଣସି ସମୟରେ ବବଲଗୁଡ଼ିକ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"କେଉଁ ଆପ୍ସ ଓ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ବବଲ ହୋଇପାରିବ ତାହା ପରିଚାଳନା କରିବାକୁ ଏଠାରେ ଟାପ କରନ୍ତୁ"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 72cb92053e56..4bd9d6b9d214 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ਸਮਝ ਲਿਆ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ਕੋਈ ਹਾਲੀਆ ਬਬਲ ਨਹੀਂ"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ਹਾਲੀਆ ਬਬਲ ਅਤੇ ਖਾਰਜ ਕੀਤੇ ਬਬਲ ਇੱਥੇ ਦਿਸਣਗੇ"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ਬਬਲ ਦੀ ਸੁਵਿਧਾ ਨੂੰ ਕਿਸੇ ਵੀ ਵੇਲੇ ਕੰਟਰੋਲ ਕਰੋ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ਇਹ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਇੱਥੇ ਟੈਪ ਕਰੋ ਕਿ ਕਿਹੜੀਆਂ ਐਪਾਂ ਅਤੇ ਗੱਲਾਂਬਾਤਾਂ ਬਬਲ ਹੋ ਸਕਦੀਆਂ ਹਨ"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 24c1f1410fde..d98be758c97e 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Brak ostatnich dymków"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Tutaj będą pojawiać się ostatnie i odrzucone dymki"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Zarządzaj dymkami, kiedy chcesz"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Kliknij tutaj, aby zarządzać wyświetlaniem aplikacji i rozmów jako dymków"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 69002026f2e5..81d325a7ec58 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ok"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nenhum balão recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Os balões recentes e dispensados aparecerão aqui"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controle os balões a qualquer momento"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toque aqui para gerenciar quais apps e conversas podem aparecer em balões"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 853c682b5089..7fa592afbbe3 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nenhum balão recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Os balões recentes e ignorados vão aparecer aqui."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controle os balões em qualquer altura"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toque aqui para gerir que apps e conversas podem aparecer em balões"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 69002026f2e5..81d325a7ec58 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ok"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nenhum balão recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Os balões recentes e dispensados aparecerão aqui"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controle os balões a qualquer momento"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toque aqui para gerenciar quais apps e conversas podem aparecer em balões"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 7356f7cf08d2..0341667be3e3 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nu există baloane recente"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Baloanele recente și baloanele respinse vor apărea aici"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controlează baloanele oricând"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Atinge aici pentru a gestiona aplicațiile și conversațiile care pot apărea în balon"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 61e3ec9b7da2..da234c71a009 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ОК"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нет недавних всплывающих чатов"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Здесь будут появляться недавние и скрытые всплывающие чаты."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Всплывающие чаты"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Укажите приложения и разговоры, для которых разрешены всплывающие чаты."</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index ac78385b9644..236da5d67fc9 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"තේරුණා"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"මෑත බුබුලු නැත"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"මෑත බුබුලු සහ ඉවත ලූ බුබුලු මෙහි දිස් වනු ඇත"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ඕනෑම වේලාවක බුබුලු පාලනය කරන්න"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"බුබුලු කළ හැකි යෙදුම් සහ සංවාද කළමනාකරණය කිරීමට මෙහි තට්ටු කරන්න"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index d659d51afc5f..eaabdabb0285 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Dobre"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Žiadne nedávne bubliny"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Tu sa budú zobrazovať nedávne a zavreté bubliny"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Ovládajte bubliny kedykoľvek"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Klepnite tu a spravujte, ktoré aplikácie a konverzácie môžu ovládať bubliny"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 91871fbf94ec..514a0b3548db 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"V redu"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ni nedavnih oblačkov"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Tukaj bodo prikazani tako nedavni kot tudi opuščeni oblački"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Upravljanje oblačkov"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dotaknite se tukaj za upravljanje aplikacij in pogovorov, ki so lahko prikazani v oblačkih"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 45eb04a45271..790119b8e9cc 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"E kuptova"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nuk ka flluska të fundit"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Flluskat e fundit dhe flluskat e hequra do të shfaqen këtu"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrollo flluskat në çdo moment"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Trokit këtu për të menaxhuar aplikacionet e bisedat që do të shfaqen në flluska"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 368df542796f..9fd9f3ed18a9 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Важи"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нема недавних облачића"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Овде се приказују недавни и одбачени облачићи"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Контролишите облачиће у сваком тренутку"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Додирните овде и одредите које апликације и конверзације могу да имају облачић"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 35d5b7af2b62..f7f218e4ded7 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Inga nya bubblor"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"De senaste bubblorna och ignorerade bubblor visas här"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Styr bubblor när som helst"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tryck här för att hantera vilka appar och konversationer som får visas i bubblor"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 52e0a6960948..83173f3649c0 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Nimeelewa"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Hakuna viputo vya hivi majuzi"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Viputo vya hivi karibuni na vile vilivyoondolewa vitaonekana hapa"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Dhibiti viputo wakati wowote"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Gusa hapa ili udhibiti programu na mazungumzo yanayoweza kutumia viputo"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 98a7d679014c..ea2ee9c22c08 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"சரி"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"சமீபத்திய குமிழ்கள் இல்லை"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"சமீபத்திய குமிழ்களும் நிராகரிக்கப்பட்ட குமிழ்களும் இங்கே தோன்றும்"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"எப்போது வேண்டுமானாலும் குமிழ்களைக் கட்டுப்படுத்துங்கள்"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"எந்தெந்த ஆப்ஸும் உரையாடல்களும் குமிழியாகலாம் என்பதை நிர்வகிக்க இங்கே தட்டுங்கள்"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 70f810e21fcc..e2772bf7311e 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"అర్థమైంది"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ఇటీవలి బబుల్స్ ఏవీ లేవు"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ఇటీవలి బబుల్స్ మరియు తీసివేసిన బబుల్స్ ఇక్కడ కనిపిస్తాయి"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"బబుల్స్‌ను ఎప్పుడైనా కంట్రోల్ చేయండి"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ఏ యాప్‌లు, సంభాషణలను బబుల్ చేయాలో మేనేజ్ చేయడానికి ఇక్కడ ట్యాప్ చేయండి"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 0efaab2d2f15..14bdc4bb040f 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"รับทราบ"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ไม่มีบับเบิลเมื่อเร็วๆ นี้"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"บับเบิลที่แสดงและที่ปิดไปเมื่อเร็วๆ นี้จะปรากฏที่นี่"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ควบคุมบับเบิลได้ทุกเมื่อ"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"แตะที่นี่เพื่อจัดการแอปและการสนทนาที่แสดงเป็นบับเบิลได้"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index e5d535015c52..208e8cbc2277 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Walang kamakailang bubble"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Lalabas dito ang mga kamakailang bubble at na-dismiss na bubble"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrolin ang mga bubble anumang oras"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Mag-tap dito para pamahalaan ang mga app at conversion na puwedeng mag-bubble"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 8e7f1620354b..b6c0d6864d1c 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Anladım"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Son kapatılan baloncuk yok"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Son baloncuklar ve kapattığınız baloncuklar burada görünür"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Baloncukları istediğiniz zaman kontrol edin"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Buraya dokunarak baloncuk olarak gösterilecek uygulama ve görüşmeleri yönetin"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 5c7c6c4dae30..6a119881518a 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Зрозуміло"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Немає нещодавніх спливаючих чатів"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Тут з\'являтимуться нещодавні й закриті спливаючі чати"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Контроль спливаючих чатів"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Натисніть тут, щоб вибрати, для яких додатків і розмов дозволити спливаючі чати"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 451d048ca825..292cabae3cdb 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"سمجھ آ گئی"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"کوئی حالیہ بلبلہ نہیں"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حالیہ بلبلے اور برخاست شدہ بلبلے یہاں ظاہر ہوں گے"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"کسی بھی وقت بلبلے کو کنٹرول کریں"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"یہ نظم کرنے کے لیے یہاں تھپتھپائیں کہ کون سی ایپس اور گفتگوئیں بلبلہ سکتی ہیں"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 4211ea7a5e7d..5f33fe941040 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Hech qanday bulutcha topilmadi"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Eng oxirgi va yopilgan bulutchali chatlar shu yerda chiqadi"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bulutchalardagi bildirishnomalar"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Bulutchalarda bildirishnomalar chiqishiga ruxsat beruvchi ilova va suhbatlarni tanlang."</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 0a0205d8f591..29b3b854e3c3 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Đã hiểu"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Không có bong bóng trò chuyện nào gần đây"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Bong bóng trò chuyện đã đóng và bong bóng trò chuyện gần đây sẽ xuất hiện ở đây"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kiểm soát bong bóng bất cứ lúc nào"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Nhấn vào đây để quản lý việc dùng bong bóng cho các ứng dụng và cuộc trò chuyện"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 29dc077469e6..7820965a81c1 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"知道了"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近没有对话泡"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"此处会显示最近的对话泡和已关闭的对话泡"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"随时控制对话泡"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"点按此处即可管理哪些应用和对话可以显示对话泡"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 0755d61e6a6d..f0df04a1ea53 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"知道了"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"沒有最近曾使用的小視窗"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"最近使用和關閉的小視窗會在這裡顯示"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"隨時控制對話氣泡"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"輕按這裡即可管理哪些應用程式和對話可以使用對話氣泡"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index f93188343fdf..a9773634ea3d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"我知道了"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近沒有任何對話框"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"最近的對話框和已關閉的對話框會顯示在這裡"</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"你隨時可以控管對話框的各項設定"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"輕觸這裡即可管理哪些應用程式和對話可顯示對話框"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 3ba0abee2a95..a6903a38ecf4 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -76,6 +76,10 @@
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ngiyezwa"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Awekho amabhamuza akamuva"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Amabhamuza akamuva namabhamuza asusiwe azobonakala lapha."</string>
+ <!-- no translation found for bubble_bar_education_stack_title (2486903590422497245) -->
+ <skip />
+ <!-- no translation found for bubble_bar_education_stack_text (2446934610817409820) -->
+ <skip />
<string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Lawula amabhamuza noma nini"</string>
<string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Thepha lapha ukuze ulawule ukuthi yimaphi ama-app kanye nezingxoxo ezingenza amabhamuza"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index eabe3a4eca0b..b556150e2ab9 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -142,6 +142,10 @@
<string name="bubble_accessibility_action_move_bottom_left">Move bottom left</string>
<!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
<string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
+ <!-- Accessibility announcement when the stack of bubbles expands. [CHAR LIMIT=NONE]-->
+ <string name="bubble_accessibility_announce_expand">expand <xliff:g id="bubble_title" example="Messages">%1$s</xliff:g></string>
+ <!-- Accessibility announcement when the stack of bubbles collapses. [CHAR LIMIT=NONE]-->
+ <string name="bubble_accessibility_announce_collapse">collapse <xliff:g id="bubble_title" example="Messages">%1$s</xliff:g></string>
<!-- Label for the button that takes the user to the notification settings for the given app. -->
<string name="bubbles_app_settings"><xliff:g id="notification_title" example="Android Messages">%1$s</xliff:g> settings</string>
<!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=30] -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 3f9dcc19dda7..c124b532b89d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -2037,6 +2037,7 @@ public class BubbleStackView extends FrameLayout
});
}
notifyExpansionChanged(mExpandedBubble, mIsExpanded);
+ announceExpandForAccessibility(mExpandedBubble, mIsExpanded);
}
/**
@@ -2053,6 +2054,34 @@ public class BubbleStackView extends FrameLayout
}
}
+ private void announceExpandForAccessibility(BubbleViewProvider bubble, boolean expanded) {
+ if (bubble instanceof Bubble) {
+ String contentDescription = getBubbleContentDescription((Bubble) bubble);
+ String message = getResources().getString(
+ expanded
+ ? R.string.bubble_accessibility_announce_expand
+ : R.string.bubble_accessibility_announce_collapse, contentDescription);
+ announceForAccessibility(message);
+ }
+ }
+
+ @NonNull
+ private String getBubbleContentDescription(Bubble bubble) {
+ final String appName = bubble.getAppName();
+ final String title = bubble.getTitle() != null
+ ? bubble.getTitle()
+ : getResources().getString(R.string.notification_bubble_title);
+
+ if (appName == null || title.equals(appName)) {
+ // App bubble title equals the app name, so return only the title to avoid having
+ // content description like: `<app> from <app>`.
+ return title;
+ } else {
+ return getResources().getString(
+ R.string.bubble_content_description_single, title, appName);
+ }
+ }
+
private boolean isGestureNavEnabled() {
return mContext.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index dc6dc7910feb..e916a140e5d5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -171,13 +171,14 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
return false;
}
final RecentsController controller = mControllers.get(controllerIdx);
- Transitions.setRunningRemoteTransitionDelegate(mAnimApp);
+ final IApplicationThread animApp = mAnimApp;
mAnimApp = null;
if (!controller.start(info, startTransaction, finishTransaction, finishCallback)) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"RecentsTransitionHandler.startAnimation: failed to start animation");
return false;
}
+ Transitions.setRunningRemoteTransitionDelegate(animApp);
return true;
}
@@ -225,6 +226,13 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
private ArrayList<TaskState> mPausingTasks = null;
/**
+ * List of tasks were pausing but closed in a subsequent merged transition. If a
+ * closing task is reopened, the leash is not initially hidden since it is already
+ * visible.
+ */
+ private ArrayList<TaskState> mClosingTasks = null;
+
+ /**
* List of tasks that we are switching to. Upon finish, these will remain visible and
* on top.
*/
@@ -375,6 +383,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
mFinishTransaction = null;
mPausingTasks = null;
+ mClosingTasks = null;
mOpeningTasks = null;
mInfo = null;
mTransition = null;
@@ -419,6 +428,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mFinishCB = finishCB;
mFinishTransaction = finishT;
mPausingTasks = new ArrayList<>();
+ mClosingTasks = new ArrayList<>();
mOpeningTasks = new ArrayList<>();
mLeashMap = new ArrayMap<>();
mKeyguardLocked = (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0;
@@ -670,7 +680,10 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
final TransitionInfo.Change change = closingTasks.get(i);
final int pausingIdx = TaskState.indexOf(mPausingTasks, change);
if (pausingIdx >= 0) {
- mPausingTasks.remove(pausingIdx);
+ // We are closing the pausing task, but it is still visible and can be
+ // restart by another transition prior to this transition finishing
+ final TaskState closingTask = mPausingTasks.remove(pausingIdx);
+ mClosingTasks.add(closingTask);
didMergeThings = true;
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
" closing pausing taskId=%d", change.getTaskInfo().taskId);
@@ -706,7 +719,12 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
for (int i = 0; i < openingTasks.size(); ++i) {
final TransitionInfo.Change change = openingTasks.get(i);
final boolean isLeaf = openingTaskIsLeafs.get(i) == 1;
- int pausingIdx = TaskState.indexOf(mPausingTasks, change);
+ final int closingIdx = TaskState.indexOf(mClosingTasks, change);
+ if (closingIdx >= 0) {
+ // Remove opening tasks from closing set
+ mClosingTasks.remove(closingIdx);
+ }
+ final int pausingIdx = TaskState.indexOf(mPausingTasks, change);
if (pausingIdx >= 0) {
// Something is showing/opening a previously-pausing app.
if (isLeaf) {
@@ -729,12 +747,14 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
appearedTargets[nextTargetIdx++] = target;
// reparent into the original `mInfo` since that's where we are animating.
final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
+ final boolean wasClosing = closingIdx >= 0;
t.reparent(target.leash, mInfo.getRoot(rootIdx).getLeash());
t.setLayer(target.leash, layer);
- // Hide the animation leash, let listener show it.
- t.hide(target.leash);
+ // Hide the animation leash if not already visible, let listener show it
+ t.setVisibility(target.leash, !wasClosing);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " opening new leaf taskId=%d", target.taskId);
+ " opening new leaf taskId=%d wasClosing=%b",
+ target.taskId, wasClosing);
mOpeningTasks.add(new TaskState(change, target.leash));
} else {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
index 20c4d5ae5f58..e7e1e0a98550 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
@@ -35,13 +35,14 @@ class SnapshotWindowCreator {
void makeTaskSnapshotWindow(StartingWindowInfo startingWindowInfo, TaskSnapshot snapshot) {
final int taskId = startingWindowInfo.taskInfo.taskId;
// Remove any existing starting window for this task before adding.
- mStartingWindowRecordManager.removeWindow(taskId, true);
+ mStartingWindowRecordManager.removeWindow(taskId);
final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo,
startingWindowInfo.appToken, snapshot, mMainExecutor,
- () -> mStartingWindowRecordManager.removeWindow(taskId, true));
+ () -> mStartingWindowRecordManager.removeWindow(taskId));
if (surface != null) {
final SnapshotWindowRecord tView = new SnapshotWindowRecord(surface,
- startingWindowInfo.taskInfo.topActivityType, mMainExecutor);
+ startingWindowInfo.taskInfo.topActivityType, mMainExecutor,
+ taskId, mStartingWindowRecordManager);
mStartingWindowRecordManager.addRecord(taskId, tView);
}
}
@@ -50,8 +51,9 @@ class SnapshotWindowCreator {
private final TaskSnapshotWindow mTaskSnapshotWindow;
SnapshotWindowRecord(TaskSnapshotWindow taskSnapshotWindow,
- int activityType, ShellExecutor removeExecutor) {
- super(activityType, removeExecutor);
+ int activityType, ShellExecutor removeExecutor, int id,
+ StartingSurfaceDrawer.StartingWindowRecordManager recordManager) {
+ super(activityType, removeExecutor, id, recordManager);
mTaskSnapshotWindow = taskSnapshotWindow;
mBGColor = mTaskSnapshotWindow.getBackgroundColor();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index 4cfbbd971fe3..31fc98b713ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -358,7 +358,7 @@ class SplashscreenWindowCreator extends AbsSplashWindowCreator {
}
}
if (shouldSaveView) {
- mStartingWindowRecordManager.removeWindow(taskId, true);
+ mStartingWindowRecordManager.removeWindow(taskId);
saveSplashScreenRecord(appToken, taskId, view, suggestType);
}
return shouldSaveView;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 7cbf263f7cb1..e2be1533118a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -188,7 +188,7 @@ public class StartingSurfaceDrawer {
final SnapshotRecord record = sRecord instanceof SnapshotRecord
? (SnapshotRecord) sRecord : null;
if (record != null && record.hasImeSurface()) {
- records.removeWindow(taskId, true);
+ records.removeWindow(taskId);
}
}
@@ -256,10 +256,15 @@ public class StartingSurfaceDrawer {
@WindowConfiguration.ActivityType protected final int mActivityType;
protected final ShellExecutor mRemoveExecutor;
+ private final int mTaskId;
+ private final StartingWindowRecordManager mRecordManager;
- SnapshotRecord(int activityType, ShellExecutor removeExecutor) {
+ SnapshotRecord(int activityType, ShellExecutor removeExecutor, int taskId,
+ StartingWindowRecordManager recordManager) {
mActivityType = activityType;
mRemoveExecutor = removeExecutor;
+ mTaskId = taskId;
+ mRecordManager = recordManager;
}
@Override
@@ -301,6 +306,7 @@ public class StartingSurfaceDrawer {
@CallSuper
protected void removeImmediately() {
mRemoveExecutor.removeCallbacks(mScheduledRunnable);
+ mRecordManager.onRecordRemoved(mTaskId);
}
}
@@ -316,7 +322,7 @@ public class StartingSurfaceDrawer {
taskIds[i] = mStartingWindowRecords.keyAt(i);
}
for (int i = taskSize - 1; i >= 0; --i) {
- removeWindow(taskIds[i], true);
+ removeWindow(taskIds[i]);
}
}
@@ -335,9 +341,13 @@ public class StartingSurfaceDrawer {
}
}
- void removeWindow(int taskId, boolean immediately) {
+ void removeWindow(int taskId) {
mTmpRemovalInfo.taskId = taskId;
- removeWindow(mTmpRemovalInfo, immediately);
+ removeWindow(mTmpRemovalInfo, true/* immediately */);
+ }
+
+ void onRecordRemoved(int taskId) {
+ mStartingWindowRecords.remove(taskId);
}
StartingWindowRecord getRecord(int taskId) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
index 144547885501..fed2f34b5e0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
@@ -92,7 +92,8 @@ class WindowlessSnapshotWindowCreator {
final SnapshotWindowRecord record = new SnapshotWindowRecord(mViewHost, wlw.mChildSurface,
taskDescription.getBackgroundColor(), snapshot.hasImeSurface(),
- runningTaskInfo.topActivityType, removeExecutor);
+ runningTaskInfo.topActivityType, removeExecutor,
+ taskId, mStartingWindowRecordManager);
mStartingWindowRecordManager.addRecord(taskId, record);
info.notifyAddComplete(wlw.mChildSurface);
}
@@ -104,8 +105,9 @@ class WindowlessSnapshotWindowCreator {
SnapshotWindowRecord(SurfaceControlViewHost viewHost, SurfaceControl childSurface,
int bgColor, boolean hasImeSurface, int activityType,
- ShellExecutor removeExecutor) {
- super(activityType, removeExecutor);
+ ShellExecutor removeExecutor, int id,
+ StartingSurfaceDrawer.StartingWindowRecordManager recordManager) {
+ super(activityType, removeExecutor, id, recordManager);
mViewHost = viewHost;
mChildSurface = childSurface;
mBGColor = bgColor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index adae21b20b3c..93d763608b5f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -54,12 +54,13 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
private static final String TAG = TaskViewTaskController.class.getSimpleName();
private final CloseGuard mGuard = new CloseGuard();
-
+ private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+ /** Used to inset the activity content to allow space for a caption bar. */
+ private final Binder mCaptionInsetsOwner = new Binder();
private final ShellTaskOrganizer mTaskOrganizer;
private final Executor mShellExecutor;
private final SyncTransactionQueue mSyncQueue;
private final TaskViewTransitions mTaskViewTransitions;
- private TaskViewBase mTaskViewBase;
private final Context mContext;
/**
@@ -70,21 +71,19 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
* in this situation to allow us to notify listeners correctly if the task failed to open.
*/
private ActivityManager.RunningTaskInfo mPendingInfo;
- /* Indicates that the task we attempted to launch in the task view failed to launch. */
- private boolean mTaskNotFound;
+ private TaskViewBase mTaskViewBase;
protected ActivityManager.RunningTaskInfo mTaskInfo;
private WindowContainerToken mTaskToken;
private SurfaceControl mTaskLeash;
- private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+ /* Indicates that the task we attempted to launch in the task view failed to launch. */
+ private boolean mTaskNotFound;
private boolean mSurfaceCreated;
private SurfaceControl mSurfaceControl;
private boolean mIsInitialized;
private boolean mNotifiedForInitialized;
+ private boolean mHideTaskWithSurface = true;
private TaskView.Listener mListener;
private Executor mListenerExecutor;
-
- /** Used to inset the activity content to allow space for a caption bar. */
- private final Binder mCaptionInsetsOwner = new Binder();
private Rect mCaptionInsets;
public TaskViewTaskController(Context context, ShellTaskOrganizer organizer,
@@ -102,6 +101,19 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
mGuard.open("release");
}
+ /**
+ * Specifies if the task should be hidden when the surface is destroyed.
+ * <p>This is {@code true} by default.
+ *
+ * @param hideTaskWithSurface {@code false} if task needs to remain visible even when the
+ * surface is destroyed, {@code true} otherwise.
+ */
+ public void setHideTaskWithSurface(boolean hideTaskWithSurface) {
+ // TODO(b/299535374): Remove mHideTaskWithSurface once the taskviews with launch root tasks
+ // are moved to a window in SystemUI in auto.
+ mHideTaskWithSurface = hideTaskWithSurface;
+ }
+
SurfaceControl getSurfaceControl() {
return mSurfaceControl;
}
@@ -257,9 +269,17 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
mTaskNotFound = false;
}
+ /** This method shouldn't be called when shell transitions are enabled. */
private void updateTaskVisibility() {
+ boolean visible = mSurfaceCreated;
+ if (!visible && !mHideTaskWithSurface) {
+ return;
+ }
WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setHidden(mTaskToken, !mSurfaceCreated /* hidden */);
+ wct.setHidden(mTaskToken, !visible /* hidden */);
+ if (!visible) {
+ wct.reorder(mTaskToken, false /* onTop */);
+ }
mSyncQueue.queue(wct);
if (mListener == null) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
index bbf67a6155d7..a90edf20f94e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -137,7 +137,6 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
});
}
};
- Transitions.setRunningRemoteTransitionDelegate(remote.getAppThread());
try {
// If the remote is actually in the same process, then make a copy of parameters since
// remote impls assume that they have to clean-up native references.
@@ -149,6 +148,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
remote.getRemoteTransition().startAnimation(transition, remoteInfo, remoteStartT, cb);
// assume that remote will apply the start transaction.
startTransaction.clear();
+ Transitions.setRunningRemoteTransitionDelegate(remote.getAppThread());
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);
unhandleDeath(remote.asBinder(), finishCallback);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 8d76fc6c542b..a26927586b61 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.windowdecor;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -220,6 +221,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
final Resources resources = mDecorWindowContext.getResources();
final Configuration taskConfig = mTaskInfo.getConfiguration();
final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
+ final boolean isFullscreen = taskConfig.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_FULLSCREEN;
outResult.mWidth = taskBounds.width();
outResult.mHeight = taskBounds.height();
@@ -279,13 +282,24 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
final Point taskPosition = mTaskInfo.positionInParent;
- startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight)
- .setShadowRadius(mTaskSurface, shadowRadius)
+ if (isFullscreen) {
+ // Setting the task crop to the width/height stops input events from being sent to
+ // some regions of the app window. See b/300324920
+ // TODO(b/296921174): investigate whether crop/position needs to be set by window
+ // decorations at all when transition handlers are already taking ownership of the task
+ // surface placement/crop, especially when in fullscreen where tasks cannot be
+ // drag-resized by the window decoration.
+ startT.setWindowCrop(mTaskSurface, null);
+ finishT.setWindowCrop(mTaskSurface, null);
+ } else {
+ startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
+ finishT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
+ }
+ startT.setShadowRadius(mTaskSurface, shadowRadius)
.setColor(mTaskSurface, mTmpColor)
.show(mTaskSurface);
finishT.setPosition(mTaskSurface, taskPosition.x, taskPosition.y)
- .setShadowRadius(mTaskSurface, shadowRadius)
- .setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
+ .setShadowRadius(mTaskSurface, shadowRadius);
if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
index fb6c09381d3b..c9a98c73e5e5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
@@ -33,14 +33,14 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
@Postsubmit
@Test
override fun pipAppWindowAlwaysVisible() {
- flicker.assertWm { this.isAppWindowVisible(standardAppHelper) }
+ flicker.assertWm { this.isAppWindowVisible(standardAppHelper.packageNameMatcher) }
}
/** Checks [standardAppHelper] layer remains visible throughout the animation */
@Postsubmit
@Test
override fun pipAppLayerAlwaysVisible() {
- flicker.assertLayers { this.isVisible(standardAppHelper) }
+ flicker.assertLayers { this.isVisible(standardAppHelper.packageNameMatcher) }
}
/** Checks the content overlay appears then disappears during the animation */
@@ -57,7 +57,9 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
@Postsubmit
@Test
override fun pipWindowRemainInsideVisibleBounds() {
- flicker.assertWmVisibleRegion(standardAppHelper) { coversAtMost(displayBounds) }
+ flicker.assertWmVisibleRegion(standardAppHelper.packageNameMatcher) {
+ coversAtMost(displayBounds)
+ }
}
/**
@@ -68,7 +70,7 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
@Test
override fun pipLayerOrOverlayRemainInsideVisibleBounds() {
flicker.assertLayersVisibleRegion(
- standardAppHelper.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)
+ standardAppHelper.packageNameMatcher.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)
) {
coversAtMost(displayBounds)
}
@@ -93,9 +95,9 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
@Test
override fun pipWindowBecomesPinned() {
flicker.assertWm {
- invoke("pipWindowIsNotPinned") { it.isNotPinned(standardAppHelper) }
+ invoke("pipWindowIsNotPinned") { it.isNotPinned(standardAppHelper.packageNameMatcher) }
.then()
- .invoke("pipWindowIsPinned") { it.isPinned(standardAppHelper) }
+ .invoke("pipWindowIsPinned") { it.isPinned(standardAppHelper.packageNameMatcher) }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
index 54b3e2a8c8c0..d7ba3d57b548 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
@@ -16,19 +16,22 @@
package com.android.wm.shell.flicker.pip.apps
-import android.os.Handler
-import android.os.Looper
-import android.os.SystemClock
import android.content.Context
import android.location.Criteria
import android.location.Location
import android.location.LocationManager
+import android.os.Handler
+import android.os.Looper
+import android.os.SystemClock
+import android.platform.test.annotations.Postsubmit
import android.tools.device.apphelpers.MapsAppHelper
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
+import org.junit.Assume
import org.junit.FixMethodOrder
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -129,4 +132,12 @@ open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { tapl.goHome() }
}
+
+ @Postsubmit
+ @Test
+ override fun focusChanges() {
+ // in gestural nav the focus goes to different activity on swipe up with auto enter PiP
+ Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+ super.focusChanges()
+ }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
new file mode 100644
index 000000000000..c370d91034fd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip.apps
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.apphelpers.YouTubeAppHelper
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import androidx.test.filters.RequiresDevice
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from YouTube app by interacting with the app UI
+ *
+ * To run this test: `atest WMShellFlickerTests:YouTubeEnterPipTest`
+ *
+ * Actions:
+ * ```
+ * Launch YouTube and start playing a video
+ * Go home to enter PiP
+ * ```
+ *
+ * Notes:
+ * ```
+ * 1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ * are inherited from [PipTransition]
+ * 2. Part of the test setup occurs automatically via
+ * [android.tools.device.flicker.legacy.runner.TransitionRunner],
+ * including configuring navigation mode, initial orientation and ensuring no
+ * apps are running before setup
+ * ```
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class YouTubeEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) {
+ override val standardAppHelper: YouTubeAppHelper = YouTubeAppHelper(instrumentation)
+
+ override val defaultEnterPip: FlickerBuilder.() -> Unit = {
+ setup {
+ standardAppHelper.launchViaIntent(
+ wmHelper,
+ YouTubeAppHelper.getYoutubeVideoIntent("HPcEAtoXXLA"),
+ ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
+ )
+ standardAppHelper.waitForVideoPlaying()
+ }
+ }
+
+ override val defaultTeardown: FlickerBuilder.() -> Unit = {
+ teardown {
+ standardAppHelper.exit(wmHelper)
+ }
+ }
+
+ override val thisTransition: FlickerBuilder.() -> Unit = {
+ transitions { tapl.goHome() }
+ }
+
+ @Postsubmit
+ @Test
+ override fun pipOverlayLayerAppearThenDisappear() {
+ // YouTube uses source rect hint, so PiP overlay is never present
+ }
+
+ @Postsubmit
+ @Test
+ override fun focusChanges() {
+ // in gestural nav the focus goes to different activity on swipe up with auto enter PiP
+ Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+ super.focusChanges()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
index fa1be63296e0..2539fd50d742 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
@@ -31,7 +31,8 @@ import org.junit.runner.RunWith
class DismissSplitScreenByDividerGesturalNavPortrait :
DismissSplitScreenByDivider(Rotation.ROTATION_0) {
- @ExpectedScenarios(["SPLIT_SCREEN_EXIT"])
+ // TODO(b/300260196): Not detecting this scenario right now
+ @ExpectedScenarios(["ENTIRE_TRACE"])
@Test
override fun dismissSplitScreenByDivider() = super.dismissSplitScreenByDivider()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt
index 17ed396987af..e7274918fa2b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt
@@ -424,6 +424,7 @@ class PhysicsAnimatorTest : ShellTestCase() {
eq(-5f), anyFloat(), eq(true))
}
+ @Ignore("Started flaking despite no changes, tracking in b/299636216")
@Test
fun testIsPropertyAnimating() {
PhysicsAnimatorTestUtils.setAllAnimationsBlock(false)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
index 9f0d89bc3128..52375850b9a5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt
@@ -27,15 +27,13 @@ import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.anyString
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Mockito
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyNoMoreInteractions
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -66,7 +64,7 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
@Before
fun setup() {
- launcherApps = mock(LauncherApps::class.java)
+ launcherApps = mock<LauncherApps>()
repository = BubbleVolatileRepository(launcherApps)
}
@@ -98,7 +96,7 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
repository.addBubbles(user11.identifier, listOf(bubble12))
assertEquals(listOf(bubble11, bubble12), repository.getEntities(user11.identifier))
- Mockito.verifyNoMoreInteractions(launcherApps)
+ verifyNoMoreInteractions(launcherApps)
}
@Test
@@ -167,9 +165,8 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
assertThat(ret).isTrue() // bubbles were removed
assertThat(repository.getEntities(user0.identifier).toList()).isEmpty()
- verify(launcherApps, never()).uncacheShortcuts(anyString(),
- any(),
- any(UserHandle::class.java), anyInt())
+ verify(launcherApps, never())
+ .uncacheShortcuts(any<String>(), any(), any<UserHandle>(), any<Int>())
}
@Test
@@ -184,9 +181,8 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
assertThat(repository.getEntities(user0.identifier).toList())
.isEqualTo(listOf(bubble1, bubble3))
- verify(launcherApps, never()).uncacheShortcuts(anyString(),
- any(),
- any(UserHandle::class.java), anyInt())
+ verify(launcherApps, never())
+ .uncacheShortcuts(any<String>(), any(), any<UserHandle>(), any<Int>())
}
@Test
@@ -200,9 +196,8 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
assertThat(repository.getEntities(user0.identifier).toList())
.isEqualTo(listOf(bubble1, bubble2, bubble3))
- verify(launcherApps, never()).uncacheShortcuts(anyString(),
- any(),
- any(UserHandle::class.java), anyInt())
+ verify(launcherApps, never())
+ .uncacheShortcuts(any<String>(), any(), any<UserHandle>(), any<Int>())
}
@Test
@@ -219,9 +214,8 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
user11.identifier))
assertThat(ret).isFalse() // bubbles were NOT removed
- verify(launcherApps, never()).uncacheShortcuts(anyString(),
- any(),
- any(UserHandle::class.java), anyInt())
+ verify(launcherApps, never())
+ .uncacheShortcuts(any<String>(), any(), any<UserHandle>(), any<Int>())
}
@Test
@@ -237,9 +231,8 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
assertThat(ret).isTrue() // bubbles were removed
assertThat(repository.getEntities(user0.identifier).toList()).isEmpty()
- verify(launcherApps, never()).uncacheShortcuts(anyString(),
- any(),
- any(UserHandle::class.java), anyInt())
+ verify(launcherApps, never())
+ .uncacheShortcuts(any<String>(), any(), any<UserHandle>(), any<Int>())
// User 11 bubbles should still be here
assertThat(repository.getEntities(user11.identifier).toList())
@@ -261,9 +254,8 @@ class BubbleVolatileRepositoryTest : ShellTestCase() {
// bubble2 is the work profile bubble and should be removed
assertThat(repository.getEntities(user0.identifier).toList())
.isEqualTo(listOf(bubble1, bubble3))
- verify(launcherApps, never()).uncacheShortcuts(anyString(),
- any(),
- any(UserHandle::class.java), anyInt())
+ verify(launcherApps, never())
+ .uncacheShortcuts(any<String>(), any(), any<UserHandle>(), any<Int>())
// User 11 bubbles should still be here
assertThat(repository.getEntities(user11.identifier).toList())
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
index d098d332a376..0088051928fb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
@@ -221,6 +221,20 @@ public class TaskViewTest extends ShellTestCase {
}
@Test
+ public void testSurfaceDestroyed_withTask_shouldNotHideTask_legacyTransitions() {
+ assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS);
+ mTaskViewTaskController.setHideTaskWithSurface(false);
+
+ SurfaceHolder sh = mock(SurfaceHolder.class);
+ mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash);
+ mTaskView.surfaceCreated(sh);
+ reset(mViewListener);
+ mTaskView.surfaceDestroyed(sh);
+
+ verify(mViewListener, never()).onTaskVisibilityChanged(anyInt(), anyBoolean());
+ }
+
+ @Test
public void testSurfaceDestroyed_withTask_legacyTransitions() {
assumeFalse(Transitions.ENABLE_SHELL_TRANSITIONS);
SurfaceHolder sh = mock(SurfaceHolder.class);
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index fd6e18ee364a..68befffecf2f 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -812,10 +812,10 @@ Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode m
/* check the appropriate Zip file */
ZipFileRO* pZip = getZipFileLocked(ap);
if (pZip != NULL) {
- ALOGV("GOT zip, checking NA '%s'", (const char*) path);
+ ALOGV("GOT zip, checking NA '%s'", path.c_str());
ZipEntryRO entry = pZip->findEntryByName(path.c_str());
if (entry != NULL) {
- ALOGV("FOUND NA in Zip file for %s", (const char*) path);
+ ALOGV("FOUND NA in Zip file for %s", path.c_str());
pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
pZip->releaseEntry(entry);
}
@@ -1425,7 +1425,7 @@ AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
mResourceTableAsset(NULL), mResourceTable(NULL)
{
if (kIsDebug) {
- ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+ ALOGI("Creating SharedZip %p %s\n", this, mPath.c_str());
}
ALOGV("+++ opening zip '%s'\n", mPath.c_str());
mZipFile = ZipFileRO::open(mPath.c_str());
@@ -1439,7 +1439,7 @@ AssetManager::SharedZip::SharedZip(int fd, const String8& path)
mResourceTableAsset(NULL), mResourceTable(NULL)
{
if (kIsDebug) {
- ALOGI("Creating SharedZip %p fd=%d %s\n", this, fd, (const char*)mPath);
+ ALOGI("Creating SharedZip %p fd=%d %s\n", this, fd, mPath.c_str());
}
ALOGV("+++ opening zip fd=%d '%s'\n", fd, mPath.c_str());
mZipFile = ZipFileRO::openFd(fd, mPath.c_str());
@@ -1453,7 +1453,7 @@ sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path,
bool createIfNotPresent)
{
AutoMutex _l(gLock);
- time_t modWhen = getFileModDate(path);
+ time_t modWhen = getFileModDate(path.c_str());
sp<SharedZip> zip = gOpen.valueFor(path).promote();
if (zip != NULL && zip->mModWhen == modWhen) {
return zip;
@@ -1541,7 +1541,7 @@ bool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const
AssetManager::SharedZip::~SharedZip()
{
if (kIsDebug) {
- ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+ ALOGI("Destroying SharedZip %p %s\n", this, mPath.c_str());
}
if (mResourceTable != NULL) {
delete mResourceTable;
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index edccb8a73fc8..7f226939ffaa 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -1026,7 +1026,7 @@ std::string AssetManager2::GetLastResourceResolution() const {
log_stream << "\nBest matching is from "
<< (last_resolution_.best_config_name.empty() ? "default"
- : last_resolution_.best_config_name)
+ : last_resolution_.best_config_name.c_str())
<< " configuration of " << last_resolution_.best_package_name;
return log_stream.str();
}
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index 436f10737cb4..ef4cc46cb1c8 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -1,5 +1,4 @@
set noparent
-toddke@google.com
zyy@google.com
patb@google.com
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 099287cb9634..4c992becda7c 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -5286,19 +5286,19 @@ bool ResTable::expandResourceRef(const char16_t* refStr, size_t refLen,
*outType = *defType;
}
*outName = String16(p, end-p);
- if(**outPackage == 0) {
+ if(outPackage->empty()) {
if(outErrorMsg) {
*outErrorMsg = "Resource package cannot be an empty string";
}
return false;
}
- if(**outType == 0) {
+ if(outType->empty()) {
if(outErrorMsg) {
*outErrorMsg = "Resource type cannot be an empty string";
}
return false;
}
- if(**outName == 0) {
+ if(outName->empty()) {
if(outErrorMsg) {
*outErrorMsg = "Resource id cannot be an empty string";
}
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
index f4a358de1c41..1bfb874729d7 100644
--- a/libs/protoutil/include/android/util/ProtoOutputStream.h
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -102,7 +102,7 @@ public:
bool write(uint64_t fieldId, long val);
bool write(uint64_t fieldId, long long val);
bool write(uint64_t fieldId, bool val);
- bool write(uint64_t fieldId, std::string val);
+ bool write(uint64_t fieldId, std::string_view val);
bool write(uint64_t fieldId, const char* val, size_t size);
/**
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
index fcf82eed4eb1..a44a1b210924 100644
--- a/libs/protoutil/src/ProtoOutputStream.cpp
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -170,13 +170,13 @@ ProtoOutputStream::write(uint64_t fieldId, bool val)
}
bool
-ProtoOutputStream::write(uint64_t fieldId, std::string val)
+ProtoOutputStream::write(uint64_t fieldId, std::string_view val)
{
if (mCompact) return false;
const uint32_t id = (uint32_t)fieldId;
switch (fieldId & FIELD_TYPE_MASK) {
case FIELD_TYPE_STRING:
- writeUtf8StringImpl(id, val.c_str(), val.size());
+ writeUtf8StringImpl(id, val.data(), val.size());
return true;
default:
ALOGW("Field type %" PRIu64 " is not supported when writing string val.",
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index ceb3858eb0b3..a311296dd90c 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -1284,7 +1284,8 @@ public final class AudioFormat implements Parcelable {
* {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}.
* <p> For a valid {@link AudioTrack} channel position mask,
* the following conditions apply:
- * <br> (1) at most eight channel positions may be used;
+ * <br> (1) at most {@link AudioSystem#OUT_CHANNEL_COUNT_MAX} channel positions may be
+ * used;
* <br> (2) right/left pairs should be matched.
* <p> For input or {@link AudioRecord}, the mask should be
* {@link AudioFormat#CHANNEL_IN_MONO} or
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 86e53f5bb2e2..83d2b613f80a 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -13,3 +13,10 @@ flag {
description: "Gates whether to adjust local stream volume when the app in the foreground is the last app to play audio or adjust the volume of the last active media session that the user interacted with."
bug: "275185436"
}
+
+flag {
+ namespace: "media_solutions"
+ name: "enable_audio_policies_device_and_bluetooth_controller"
+ description: "Use Audio Policies implementation for device and Bluetooth route controllers."
+ bug: "280576228"
+}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index b03a039d74b8..ef90bf993437 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -1043,7 +1043,7 @@ static jthrowable createCodecException(
CHECK(ctor != NULL);
ScopedLocalRef<jstring> msgObj(
- env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err)));
+ env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err).c_str()));
// translate action code to Java equivalent
switch (actionCode) {
@@ -3036,7 +3036,7 @@ static void android_media_MediaCodec_setVideoScalingMode(
if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW
&& mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
jniThrowException(env, "java/lang/IllegalArgumentException",
- String8::format("Unrecognized mode: %d", mode));
+ String8::format("Unrecognized mode: %d", mode).c_str());
return;
}
@@ -3467,27 +3467,27 @@ static void android_media_MediaCodec_native_setup(
if (err == NAME_NOT_FOUND) {
// fail and do not try again.
jniThrowException(env, "java/lang/IllegalArgumentException",
- String8::format("Failed to initialize %s, error %#x (NAME_NOT_FOUND)", tmp, err));
+ String8::format("Failed to initialize %s, error %#x (NAME_NOT_FOUND)", tmp, err).c_str());
env->ReleaseStringUTFChars(name, tmp);
return;
}
if (err == NO_MEMORY) {
throwCodecException(env, err, ACTION_CODE_TRANSIENT,
- String8::format("Failed to initialize %s, error %#x (NO_MEMORY)", tmp, err));
+ String8::format("Failed to initialize %s, error %#x (NO_MEMORY)", tmp, err).c_str());
env->ReleaseStringUTFChars(name, tmp);
return;
}
if (err == PERMISSION_DENIED) {
jniThrowException(env, "java/lang/SecurityException",
String8::format("Failed to initialize %s, error %#x (PERMISSION_DENIED)", tmp,
- err));
+ err).c_str());
env->ReleaseStringUTFChars(name, tmp);
return;
}
if (err != OK) {
// believed possible to try again
jniThrowException(env, "java/io/IOException",
- String8::format("Failed to find matching codec %s, error %#x (?)", tmp, err));
+ String8::format("Failed to find matching codec %s, error %#x (?)", tmp, err).c_str());
env->ReleaseStringUTFChars(name, tmp);
return;
}
diff --git a/media/jni/android_media_MediaDescrambler.cpp b/media/jni/android_media_MediaDescrambler.cpp
index c61365a448d3..37111c28c242 100644
--- a/media/jni/android_media_MediaDescrambler.cpp
+++ b/media/jni/android_media_MediaDescrambler.cpp
@@ -368,7 +368,7 @@ static jthrowable createServiceSpecificException(
ScopedLocalRef<jstring> msgObj(
env, env->NewStringUTF(msg != NULL ?
- msg : String8::format("Error %#x", serviceSpecificError)));
+ msg : String8::format("Error %#x", serviceSpecificError).c_str()));
return (jthrowable)env->NewObject(
clazz.get(), ctor, serviceSpecificError, msgObj.get());
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 3551ea422310..d05ee551c172 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -260,7 +260,7 @@ android_media_MediaPlayer_setDataSourceAndHeaders(
status_t opStatus =
mp->setDataSource(
httpService,
- pathStr,
+ pathStr.c_str(),
headersVector.size() > 0? &headersVector : NULL);
process_media_player_call(
diff --git a/native/android/obb.cpp b/native/android/obb.cpp
index e9900249b289..a14fa7e58fa8 100644
--- a/native/android/obb.cpp
+++ b/native/android/obb.cpp
@@ -42,7 +42,7 @@ void AObbInfo_delete(AObbInfo* obbInfo) {
}
const char* AObbInfo_getPackageName(AObbInfo* obbInfo) {
- return obbInfo->getPackageName();
+ return obbInfo->getPackageName().c_str();
}
int32_t AObbInfo_getVersion(AObbInfo* obbInfo) {
diff --git a/packages/CarrierDefaultApp/res/values-sq/strings.xml b/packages/CarrierDefaultApp/res/values-sq/strings.xml
index 238921aaa8f0..d8a1ed7f6620 100644
--- a/packages/CarrierDefaultApp/res/values-sq/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sq/strings.xml
@@ -5,7 +5,7 @@
<string name="android_system_label" msgid="2797790869522345065">"Operatori celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Të dhënat celulare kanë përfunduar"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Të dhënat celulare janë çaktivizuar"</string>
- <string name="portal_notification_detail" msgid="2295729385924660881">"Trokit për të vizituar sajtin e uebit të %s"</string>
+ <string name="portal_notification_detail" msgid="2295729385924660881">"Trokit për të vizituar uebsajtin e %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakto me ofruesin e shërbimit %s"</string>
<string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nuk ka lidhje të të dhënave celulare"</string>
<string name="no_mobile_data_connection" msgid="544980465184147010">"Shto plan të dhënash ose plan roaming përmes %s"</string>
@@ -16,7 +16,7 @@
<string name="ssl_error_continue" msgid="1138548463994095584">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Përforcimi i performancës"</string>
<string name="performance_boost_notification_title" msgid="3126203390685781861">"Opsionet 5G nga operatori yt celular"</string>
- <string name="performance_boost_notification_detail" msgid="216569851036236346">"Vizito sajtin e uebit të %s për të parë opsione për përvojën tënde me aplikacionin"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Vizito uebsajtin e %s për të parë opsione për përvojën tënde me aplikacionin"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Jo tani"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Menaxho"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Bli një paketë përforcimi të performancës."</string>
diff --git a/packages/CredentialManager/horologist/README.md b/packages/CredentialManager/horologist/README.md
new file mode 100644
index 000000000000..005ad2d36b77
--- /dev/null
+++ b/packages/CredentialManager/horologist/README.md
@@ -0,0 +1,3 @@
+This folder is to place the code from Horologist (go/horologist).
+It should be removed once Horologist is imported to the platform and the dependencies to this
+module are updated to point to the imported Horologist.
diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
index 89e48f96d27b..780274cc0a5b 100644
--- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
@@ -49,7 +49,7 @@
<string name="sign_ins" msgid="4710739369149469208">"prijavljivanja"</string>
<string name="sign_in_info" msgid="2627704710674232328">"podaci za prijavljivanje"</string>
<string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> u"</string>
- <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Želite da napravite pristupni kôd na drugom uređaju?"</string>
+ <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Želite da napravite pristupni ključ na drugom uređaju?"</string>
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Želite da sačuvate lozinku na drugom uređaju?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Želite da sačuvate akreditive za prijavu na drugom uređaju?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Želite da za sva prijavljivanja koristite: <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>?"</string>
@@ -72,7 +72,7 @@
<string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Želite da koristite sačuvanu lozinku za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Želite li da koristite svoje podatke za prijavljivanje za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Želite da otključate opcije prijavljivanja za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
- <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Izaberite sačuvan pristupni kôd za: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Izaberite sačuvan pristupni ključ za: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Izaberite sačuvanu lozinku za: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Izaberite sačuvane podatke za prijavljivanje za: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Odaberite podatke za prijavljivanje za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml
index e47cf7b2c75e..d6bf9463158f 100644
--- a/packages/CredentialManager/res/values-in/strings.xml
+++ b/packages/CredentialManager/res/values-in/strings.xml
@@ -54,7 +54,7 @@
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Simpan info login di perangkat lain?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Gunakan <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> untuk semua info login Anda?"</string>
<string name="use_provider_for_all_description" msgid="1998772715863958997">"Pengelola sandi untuk <xliff:g id="USERNAME">%1$s</xliff:g> ini akan menyimpan sandi dan kunci sandi guna membantu Anda login dengan mudah"</string>
- <string name="set_as_default" msgid="4415328591568654603">"Setel sebagai default"</string>
+ <string name="set_as_default" msgid="4415328591568654603">"Jadikan default"</string>
<string name="settings" msgid="6536394145760913145">"Setelan"</string>
<string name="use_once" msgid="9027366575315399714">"Gunakan sekali"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> sandi • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> kunci sandi"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index 40f8dc48c5d5..bf6bc8bbbac9 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -34,7 +34,7 @@
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografia e çelësit publik"</string>
<string name="public_key_cryptography_detail" msgid="6937631710280562213">"Bazuar në aleancën FIDO (e cila përfshin Google, Apple, Microsoft e të tjera) dhe standardet W3C, çelësat e kalimit përdorin çifte çelësash kriptografikë. Ndryshe nga emri i përdoruesit dhe vargu i karaktereve që përdorim për fjalëkalime, një çift çelësash privat-publik krijohet për aplikacion ose sajtin e uebit. Çelësi privat ruhet i sigurt në pajisjen tënde ose në menaxherin e fjalëkalimeve dhe konfirmon identitetin tënd. Çelësi publik ndahet me aplikacionin ose serverin e sajtit të uebit. Me çelësat përkatës, mund të regjistrohesh dhe të identifikohesh në çast."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Siguri e përmirësuar e llogarisë"</string>
- <string name="improved_account_security_detail" msgid="9123750251551844860">"Secili çelës është i lidhur ekskluzivisht me aplikacionin ose sajtin e uebit për të cilin është krijuar, kështu që nuk do të identifikohesh asnjëherë gabimisht në një aplikacion ose sajt uebi mashtrues. Gjithashtu, me serverët që mbajnë vetëm çelësa publikë, pirateria informatike është shumë më e vështirë."</string>
+ <string name="improved_account_security_detail" msgid="9123750251551844860">"Secili çelës është i lidhur ekskluzivisht me aplikacionin ose uebsajtin për të cilin është krijuar, kështu që nuk do të identifikohesh asnjëherë gabimisht në një aplikacion ose uebsajt mashtrues. Gjithashtu, me serverët që mbajnë vetëm çelësa publikë, pirateria informatike është shumë më e vështirë."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Kalim i thjeshtuar"</string>
<string name="seamless_transition_detail" msgid="4475509237171739843">"Teksa shkojmë drejt një të ardhmeje pa fjalëkalime, këto të fundit do të ofrohen ende së bashku me çelësat e kalimit."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Zgjidh se ku t\'i ruash <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml
index f5a29a212a61..b83c69816341 100644
--- a/packages/CredentialManager/res/values-sr/strings.xml
+++ b/packages/CredentialManager/res/values-sr/strings.xml
@@ -49,7 +49,7 @@
<string name="sign_ins" msgid="4710739369149469208">"пријављивања"</string>
<string name="sign_in_info" msgid="2627704710674232328">"подаци за пријављивање"</string>
<string name="save_credential_to_title" msgid="3172811692275634301">"Сачувај <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> у"</string>
- <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Желите да направите приступни кôд на другом уређају?"</string>
+ <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Желите да направите приступни кључ на другом уређају?"</string>
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Желите да сачувате лозинку на другом уређају?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Желите да сачувате акредитиве за пријаву на другом уређају?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Желите да за сва пријављивања користите: <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>?"</string>
@@ -72,7 +72,7 @@
<string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Желите да користите сачувану лозинку за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Желите ли да користите своје податке за пријављивање за апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Желите да откључате опције пријављивања за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
- <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Изаберите сачуван приступни кôд за: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Изаберите сачуван приступни кључ за: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Изаберите сачувану лозинку за: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Изаберите сачуване податке за пријављивање за: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Одаберите податке за пријављивање за апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/shared/README.md b/packages/CredentialManager/shared/README.md
new file mode 100644
index 000000000000..d2375a0ccdf9
--- /dev/null
+++ b/packages/CredentialManager/shared/README.md
@@ -0,0 +1,2 @@
+This folder is to place the common code that will be shared between the phone project and the wear
+project of the Credential Manager implementation.
diff --git a/packages/CredentialManager/wear/README.md b/packages/CredentialManager/wear/README.md
new file mode 100644
index 000000000000..b9d27b9a98e5
--- /dev/null
+++ b/packages/CredentialManager/wear/README.md
@@ -0,0 +1 @@
+This project is the wear implementation of the Credential Manager feature. \ No newline at end of file
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt
index 292e002779f5..37c8eef8a90d 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt
@@ -46,21 +46,23 @@ object SettingsExposedDropdownMenuCheckBoxProvider : SettingsPageProvider {
@Composable
override fun Page(arguments: Bundle?) {
RegularScaffold(title = TITLE) {
- SettingsExposedDropdownMenuCheckBox(label = exposedDropdownMenuCheckBoxLabel,
+ SettingsExposedDropdownMenuCheckBox(
+ label = exposedDropdownMenuCheckBoxLabel,
options = options,
selectedOptionsState = remember { selectedOptionsState1 },
enabled = true,
- onselectedOptionStateChange = {})
+ onSelectedOptionStateChange = {},
+ )
}
}
fun buildInjectEntry(): SettingsEntryBuilder {
return SettingsEntryBuilder.createInject(owner = createSettingsPage()).setUiLayoutFn {
- Preference(object : PreferenceModel {
- override val title = TITLE
- override val onClick = navigator(name)
- })
- }
+ Preference(object : PreferenceModel {
+ override val title = TITLE
+ override val onClick = navigator(name)
+ })
+ }
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
index 08e3a27da125..9f8c868f4aa4 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
@@ -22,6 +22,7 @@ import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.VisibleForTesting
+import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
@@ -126,18 +127,22 @@ private fun NavControllerWrapperImpl.NavContent(
allProvider: Collection<SettingsPageProvider>,
content: @Composable (SettingsPage) -> Unit,
) {
- NavHost(
- navController = navController,
- startDestination = NullPageProvider.name,
- ) {
- composable(NullPageProvider.name) {}
- for (spp in allProvider) {
- animatedComposable(
- route = spp.name + spp.parameter.navRoute(),
- arguments = spp.parameter,
- ) { navBackStackEntry ->
- val page = remember { spp.createSettingsPage(navBackStackEntry.arguments) }
- content(page)
+ // TODO(b/298520326): Remove Box after the issue is fixed.
+ // Wrap the top level node into a Box to workaround an issue of Compose 1.6.0-alpha03.
+ Box {
+ NavHost(
+ navController = navController,
+ startDestination = NullPageProvider.name,
+ ) {
+ composable(NullPageProvider.name) {}
+ for (spp in allProvider) {
+ animatedComposable(
+ route = spp.name + spp.parameter.navRoute(),
+ arguments = spp.parameter,
+ ) { navBackStackEntry ->
+ val page = remember { spp.createSettingsPage(navBackStackEntry.arguments) }
+ content(page)
+ }
}
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt
index 459a78382f39..682b4eac0c84 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt
@@ -52,7 +52,7 @@ fun SettingsExposedDropdownMenuCheckBox(
options: List<String>,
selectedOptionsState: SnapshotStateList<String>,
enabled: Boolean,
- onselectedOptionStateChange: (String) -> Unit,
+ onSelectedOptionStateChange: () -> Unit,
) {
var dropDownWidth by remember { mutableStateOf(0) }
var expanded by remember { mutableStateOf(false) }
@@ -70,7 +70,7 @@ fun SettingsExposedDropdownMenuCheckBox(
.menuAnchor()
.fillMaxWidth(),
value = selectedOptionsState.joinToString(", "),
- onValueChange = onselectedOptionStateChange,
+ onValueChange = {},
label = { Text(text = label) },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(
@@ -89,18 +89,21 @@ fun SettingsExposedDropdownMenuCheckBox(
onDismissRequest = { expanded = false },
) {
options.forEach { option ->
- TextButton(modifier = Modifier
- .fillMaxHeight()
- .fillMaxWidth(), onClick = {
- if (selectedOptionsState.contains(option)) {
- selectedOptionsState.remove(
- option
- )
- } else {
- selectedOptionsState.add(
- option
- )
- }
+ TextButton(
+ modifier = Modifier
+ .fillMaxHeight()
+ .fillMaxWidth(),
+ onClick = {
+ if (selectedOptionsState.contains(option)) {
+ selectedOptionsState.remove(
+ option
+ )
+ } else {
+ selectedOptionsState.add(
+ option
+ )
+ }
+ onSelectedOptionStateChange()
}) {
Row(
modifier = Modifier
@@ -109,9 +112,10 @@ fun SettingsExposedDropdownMenuCheckBox(
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
- Checkbox(checked = selectedOptionsState.contains(
- option
- ), onCheckedChange = {})
+ Checkbox(
+ checked = selectedOptionsState.contains(option),
+ onCheckedChange = null,
+ )
Text(text = option)
}
}
@@ -131,6 +135,6 @@ private fun ActionButtonsPreview() {
options = options,
selectedOptionsState = selectedOptionsState,
enabled = true,
- onselectedOptionStateChange = {})
+ onSelectedOptionStateChange = {})
}
} \ No newline at end of file
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
index b77368a429ae..3a0e51b24c2c 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
@@ -32,8 +32,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.foundation.layout.asPaddingValues
-import androidx.compose.foundation.layout.navigationBars
+import androidx.compose.foundation.layout.WindowInsetsSides
+import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -49,10 +49,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
-import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
@@ -73,7 +71,6 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
-import com.android.settingslib.spa.framework.compose.horizontalValues
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsTheme
import kotlin.math.abs
@@ -129,16 +126,10 @@ internal fun CustomizedLargeTopAppBar(
private fun Title(title: String, maxLines: Int = Int.MAX_VALUE) {
Text(
text = title,
- modifier = Modifier
- .padding(
- WindowInsets.navigationBars
- .asPaddingValues()
- .horizontalValues()
- )
- .padding(
- start = SettingsDimension.itemPaddingAround,
- end = SettingsDimension.itemPaddingEnd,
- ),
+ modifier = Modifier.padding(
+ start = SettingsDimension.itemPaddingAround,
+ end = SettingsDimension.itemPaddingEnd,
+ ),
overflow = TextOverflow.Ellipsis,
maxLines = maxLines,
)
@@ -157,6 +148,15 @@ private fun topAppBarColors() = TopAppBarColors(
* Represents the colors used by a top app bar in different states.
* This implementation animates the container color according to the top app bar scroll state. It
* does not animate the leading, headline, or trailing colors.
+ *
+ * @constructor create an instance with arbitrary colors, see [TopAppBarColors] for a
+ * factory method using the default material3 spec
+ * @param containerColor the color used for the background of this BottomAppBar. Use
+ * [Color.Transparent] to have no color.
+ * @param scrolledContainerColor the container color when content is scrolled behind it
+ * @param navigationIconContentColor the content color used for the navigation icon
+ * @param titleContentColor the content color used for the title
+ * @param actionIconContentColor the content color used for actions
*/
@Stable
private class TopAppBarColors(
@@ -248,7 +248,6 @@ private fun SingleRowTopAppBar(
titleTextStyle = titleTextStyle,
titleAlpha = 1f,
titleVerticalArrangement = Arrangement.Center,
- titleHorizontalArrangement = Arrangement.Start,
titleBottomPadding = 0,
hideTitleSemantics = false,
navigationIcon = navigationIcon,
@@ -312,7 +311,7 @@ private fun TwoRowsTopAppBar(
// This will potentially animate or interpolate a transition between the container color and the
// container's scrolled color according to the app bar's scroll state.
val colorTransitionFraction = scrollBehavior?.state?.collapsedFraction ?: 0f
- val appBarContainerColor by rememberUpdatedState(colors.containerColor(colorTransitionFraction))
+ val appBarContainerColor = colors.containerColor(colorTransitionFraction)
// Wrap the given actions in a Row.
val actionsRow = @Composable {
@@ -364,14 +363,17 @@ private fun TwoRowsTopAppBar(
titleTextStyle = smallTitleTextStyle,
titleAlpha = topTitleAlpha,
titleVerticalArrangement = Arrangement.Center,
- titleHorizontalArrangement = Arrangement.Start,
titleBottomPadding = 0,
hideTitleSemantics = hideTopRowSemantics,
navigationIcon = navigationIcon,
actions = actionsRow,
)
TopAppBarLayout(
- modifier = Modifier.clipToBounds(),
+ modifier = Modifier
+ // only apply the horizontal sides of the window insets padding, since the top
+ // padding will always be applied by the layout above
+ .windowInsetsPadding(windowInsets.only(WindowInsetsSides.Horizontal))
+ .clipToBounds(),
heightPx = maxHeightPx.floatValue - pinnedHeightPx +
(scrollBehavior?.state?.heightOffset ?: 0f),
navigationIconContentColor = colors.navigationIconContentColor,
@@ -392,7 +394,6 @@ private fun TwoRowsTopAppBar(
titleTextStyle = titleTextStyle,
titleAlpha = bottomTitleAlpha,
titleVerticalArrangement = Arrangement.Bottom,
- titleHorizontalArrangement = Arrangement.Start,
titleBottomPadding = titleBottomPaddingPx,
hideTitleSemantics = hideBottomRowSemantics,
navigationIcon = {},
@@ -419,7 +420,6 @@ private fun TwoRowsTopAppBar(
* @param modifier a [Modifier]
* @param titleAlpha the title's alpha
* @param titleVerticalArrangement the title's vertical arrangement
- * @param titleHorizontalArrangement the title's horizontal arrangement
* @param titleBottomPadding the title's bottom padding
* @param hideTitleSemantics hides the title node from the semantic tree. Apply this
* boolean when this layout is part of a [TwoRowsTopAppBar] to hide the title's semantics
@@ -440,7 +440,6 @@ private fun TopAppBarLayout(
titleTextStyle: TextStyle,
titleAlpha: Float,
titleVerticalArrangement: Arrangement.Vertical,
- titleHorizontalArrangement: Arrangement.Horizontal,
titleBottomPadding: Int,
hideTitleSemantics: Boolean,
navigationIcon: @Composable () -> Unit,
@@ -470,10 +469,10 @@ private fun TopAppBarLayout(
CompositionLocalProvider(
LocalContentColor provides titleContentColor,
LocalDensity provides with(LocalDensity.current) {
- Density(
- density = density,
- fontScale = if (titleScaleDisabled) 1f else fontScale,
- )
+ Density(
+ density = density,
+ fontScale = if (titleScaleDisabled) 1f else fontScale,
+ )
},
content = title
)
@@ -528,15 +527,7 @@ private fun TopAppBarLayout(
// Title
titlePlaceable.placeRelative(
- x = when (titleHorizontalArrangement) {
- Arrangement.Center -> (constraints.maxWidth - titlePlaceable.width) / 2
- Arrangement.End ->
- constraints.maxWidth - titlePlaceable.width - actionIconsPlaceable.width
- // Arrangement.Start.
- // A TopAppBarTitleInset will make sure the title is offset in case the
- // navigation icon is missing.
- else -> max(TopAppBarTitleInset.roundToPx(), navigationIconPlaceable.width)
- },
+ x = max(TopAppBarTitleInset.roundToPx(), navigationIconPlaceable.width),
y = when (titleVerticalArrangement) {
Arrangement.Center -> (layoutHeight - titlePlaceable.height) / 2
// Apply bottom padding from the title's baseline only when the Arrangement is
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt
index 58bc72213a1b..b0271ae1d98c 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt
@@ -45,11 +45,12 @@ class SettingsExposedDropdownMenuCheckBoxTest {
@Test
fun exposedDropdownMenuCheckBox_displayed() {
composeTestRule.setContent {
- SettingsExposedDropdownMenuCheckBox(label = exposedDropdownMenuCheckBoxLabel,
+ SettingsExposedDropdownMenuCheckBox(
+ label = exposedDropdownMenuCheckBoxLabel,
options = options,
selectedOptionsState = remember { selectedOptionsState1 },
enabled = true,
- onselectedOptionStateChange = {})
+ ) {}
}
composeTestRule.onNodeWithText(
exposedDropdownMenuCheckBoxLabel, substring = true
@@ -59,11 +60,12 @@ class SettingsExposedDropdownMenuCheckBoxTest {
@Test
fun exposedDropdownMenuCheckBox_expanded() {
composeTestRule.setContent {
- SettingsExposedDropdownMenuCheckBox(label = exposedDropdownMenuCheckBoxLabel,
+ SettingsExposedDropdownMenuCheckBox(
+ label = exposedDropdownMenuCheckBoxLabel,
options = options,
selectedOptionsState = remember { selectedOptionsState1 },
enabled = true,
- onselectedOptionStateChange = {})
+ ) {}
}
composeTestRule.onNodeWithText(item3, substring = true).assertDoesNotExist()
composeTestRule.onNodeWithText(exposedDropdownMenuCheckBoxLabel, substring = true)
@@ -74,11 +76,12 @@ class SettingsExposedDropdownMenuCheckBoxTest {
@Test
fun exposedDropdownMenuCheckBox_valueAdded() {
composeTestRule.setContent {
- SettingsExposedDropdownMenuCheckBox(label = exposedDropdownMenuCheckBoxLabel,
+ SettingsExposedDropdownMenuCheckBox(
+ label = exposedDropdownMenuCheckBoxLabel,
options = options,
selectedOptionsState = remember { selectedOptionsState1 },
enabled = true,
- onselectedOptionStateChange = {})
+ ) {}
}
composeTestRule.onNodeWithText(item3, substring = true).assertDoesNotExist()
composeTestRule.onNodeWithText(exposedDropdownMenuCheckBoxLabel, substring = true)
@@ -90,11 +93,12 @@ class SettingsExposedDropdownMenuCheckBoxTest {
@Test
fun exposedDropdownMenuCheckBox_valueDeleted() {
composeTestRule.setContent {
- SettingsExposedDropdownMenuCheckBox(label = exposedDropdownMenuCheckBoxLabel,
+ SettingsExposedDropdownMenuCheckBox(
+ label = exposedDropdownMenuCheckBoxLabel,
options = options,
selectedOptionsState = remember { selectedOptionsState1 },
enabled = true,
- onselectedOptionStateChange = {})
+ ) {}
}
composeTestRule.onNodeWithText(item2, substring = true).assertIsDisplayed()
composeTestRule.onNodeWithText(exposedDropdownMenuCheckBoxLabel, substring = true)
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
index a6a5ed229756..3dac7dbc005d 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
@@ -22,7 +22,6 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
-import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -307,8 +306,8 @@ class CustomizedAppBarTest {
}
/**
- * Checks the app bar's components positioning when it's a [CustomizedTopAppBar], a
- * [CenterAlignedTopAppBar], or a larger app bar that is scrolled up and collapsed into a small
+ * Checks the app bar's components positioning when it's a [CustomizedTopAppBar]
+ * or a larger app bar that is scrolled up and collapsed into a small
* configuration and there is no navigation icon.
*/
private fun assertSmallPositioningWithoutNavigation(isCenteredTitle: Boolean = false) {
@@ -335,8 +334,7 @@ class CustomizedAppBarTest {
}
/**
- * Checks the app bar's components positioning when it's a [CustomizedTopAppBar] or a
- * [CenterAlignedTopAppBar].
+ * Checks the app bar's components positioning when it's a [CustomizedTopAppBar].
*/
private fun assertSmallDefaultPositioning(isCenteredTitle: Boolean = false) {
val appBarBounds = rule.onNodeWithTag(TopAppBarTestTag).getUnclippedBoundsInRoot()
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 9b82c13ce21b..ed15e7c7be9c 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Kanselleer"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Saambinding bied toegang tot jou kontakte en oproepgeskiedenis wanneer dit gekoppel is."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Kon nie saambind met <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nie."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Kon nie met <xliff:g id="DEVICE_NAME">%1$s</xliff:g> saambind nie weens \'n verkeerde PIN of wagwoordsleutel."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Kon nie met <xliff:g id="DEVICE_NAME">%1$s</xliff:g> saambind nie weens \'n verkeerde PIN of toegangsleutel."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Kan nie met <xliff:g id="DEVICE_NAME">%1$s</xliff:g> kommunikeer nie."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Saambinding verwerp deur <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Rekenaar"</string>
@@ -580,7 +580,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Beperkte profiel"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Voeg nuwe gebruiker by?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Jy kan hierdie toestel met ander mense deel deur bykomende gebruikers te skep. Elke gebruiker het hulle eie spasie wat hulle kan pasmaak met programme, muurpapier en so meer. Gebruikers kan ook toestelinstellings wat almal raak, soos wi-fi, aanpas.\n\nWanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul eie spasie opstel.\n\nEnige gebruiker kan programme vir alle ander gebruikers opdateer. Toeganklikheidinstellings en -dienste sal dalk nie na die nuwe gebruiker oorgedra word nie."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan apps vir al die ander gebruikers opdateer."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Maak hierdie gebruiker ’n admin?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Admins het spesiale voorregte wat ander gebruikers nie het nie. ’n Admin kan alle gebruikers bestuur, hierdie toestel opdateer of terugstel, instellings wysig, alle geïnstalleerde apps sien, en adminvoorregte vir ander mense gee of herroep."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Maak admin"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellingteruggebaaranimasies"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktiveer stelselanimasies vir voorspellingteruggebaar."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per program op waar gestel word in die manifeslêer."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Skuif links"</item>
- <item msgid="5425394847942513942">"Skuif af"</item>
- <item msgid="7728484337962740316">"Skuif regs"</item>
- <item msgid="324200556467459329">"Skuif op"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nie gespesifiseer nie"</string>
<string name="neuter" msgid="2075249330106127310">"Neutrum"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index bd025ec8950e..4831a2734f6b 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"የግምት ጀርባ እነማዎች"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ለግምት ጀርባ የስርዓት እንማዎችን ያንቁ።"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ይህ ቅንብር የስርዓት እነማዎችን ለመገመት የምልክት እነማን ያነቃል። በዝርዝር ሰነድ ፋይሉ ውስጥ በእያንዳንዱ መተግበሪያ enableOnBackInvokedCallbackን ወደ እውነት ማቀናበር ያስፈልገዋል።"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ወደ ግራ ውሰድ"</item>
- <item msgid="5425394847942513942">"ወደ ታች ውሰድ"</item>
- <item msgid="7728484337962740316">"ወደ ቀኝ ውሰድ"</item>
- <item msgid="324200556467459329">"ወደ ላይ ውሰድ"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"አልተገለጸም"</string>
<string name="neuter" msgid="2075249330106127310">"ገለልተኛ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index f5ab801a4c9e..53fbdb1d9884 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"صور متحركة تعرض إيماءة الرجوع إلى الخلف التنبؤية"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"تفعيل الصور المتحركة في النظام لإيماءة الرجوع إلى الخلف التنبؤية"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏يفعّل هذا الإعداد الصور المتحركة في النظام للصور المتحركة التي تعرض إيماءة الرجوع إلى الخلف التنبؤية. يتطلب الإعداد ضبط enableOnBackInvokedCallback إلى true لكل تطبيق في ملف البيان."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"نقل لليسار"</item>
- <item msgid="5425394847942513942">"نقل للأسفل"</item>
- <item msgid="7728484337962740316">"نقل لليمين"</item>
- <item msgid="324200556467459329">"نقل للأعلى"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="not_specified" msgid="5423502443185110328">"صيغة مخاطبة غير محدَّدة"</string>
<string name="neuter" msgid="2075249330106127310">"صيغة مخاطبة محايدة"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index a0a52b5ec262..20edf938a937 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"প্ৰেডিক্টিভ বেক এনিমেশ্বন"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"প্ৰেডিক্টিভ বেকৰ বাবে ছিষ্টেম এনিমেশ্বন সক্ষম কৰক।"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"এই ছেটিংটোৱে প্ৰেডিক্টিভ বেক এনিমেশ্বনৰ বাবে ছিষ্টেম এনিমেশ্বন সক্ষম কৰে। ইয়াৰ বাবে মেনিফেষ্ট ফাইলত প্ৰতি এপত enableOnBackInvokedCallback সত্য বুলি ছেট কৰাৰ প্ৰয়োজন।"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"বাওঁফাললৈ নিয়ক"</item>
- <item msgid="5425394847942513942">"তললৈ নিয়ক"</item>
- <item msgid="7728484337962740316">"সোঁফাললৈ নিয়ক"</item>
- <item msgid="324200556467459329">"ওপৰলৈ নিয়ক"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"নিৰ্দিষ্ট কৰা হোৱা নাই"</string>
<string name="neuter" msgid="2075249330106127310">"ক্লীৱ লিংগ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index cb515bfa9234..d7ca008b8abe 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -676,7 +676,7 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Defolt"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Ekranı aktiv etmək"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Ekranı aktiv etməyə icazə verin"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Tətbiqin ekranı aktiv etməsinə icazə verin. İcazə verilərsə, tətbiq istənilən vaxt sizə soruşmadan ekranı aktiv edə bilər."</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Tətbiqin ekranı aktiv etməsinə icazə verin. İcazə verilərsə, tətbiq istənilən vaxt sizdən soruşmadan ekranı aktiv edə bilər."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Proqnozlaşdırılan geri animasiyalar"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Proqnozlaşdırıcı geri jest üçün sistem animasiyalarını aktiv edin."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu ayar proqnozlaşdırıcı jest animasiyası üçün sistem animasiyalarını aktiv edir. Bu, manifest faylında hər bir tətbiq üçün enableOnBackInvokedCallback-in doğru kimi ayarlanmasını tələb edir."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Sola köçürün"</item>
- <item msgid="5425394847942513942">"Aşağı köçürün"</item>
- <item msgid="7728484337962740316">"Sağa köçürün"</item>
- <item msgid="324200556467459329">"Yuxarı köçürün"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Göstərilməyib"</string>
<string name="neuter" msgid="2075249330106127310">"Neytral"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 011967493a0e..a10f109ab418 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Otkaži"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Uparivanje omogućava pristup kontaktima i istoriji poziva nakon povezivanja."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog ključa."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nije moguće komunicirati sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> je odbio/la uparivanje"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Računar"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka sa predviđanjem"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućite animacije sistema za pokret povratka sa predviđanjem."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ovo podešavanje omogućava animacije sistema za pokret povratka sa predviđanjem. Zahteva podešavanje dozvole enableOnBackInvokedCallback po aplikaciji na true u fajlu manifesta."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Pomerite nalevo"</item>
- <item msgid="5425394847942513942">"Pomerite nadole"</item>
- <item msgid="7728484337962740316">"Pomerite nadesno"</item>
- <item msgid="324200556467459329">"Pomerite nagore"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nije navedeno"</string>
<string name="neuter" msgid="2075249330106127310">"Srednji rod"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index b46debff8c66..66ce12d5948c 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Анімацыя падказкі для жэста вяртання"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Уключыць сістэмную анімацыю падказкі для жэстаў вяртання."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Гэта налада ўключае сістэмную анімацыю падказкі для жэста вяртання. Для гэтага неабходна задаць у файле маніфеста для параметра enableOnBackInvokedCallback значэнне \"True\" для кожнай праграмы."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Перамясціць улева"</item>
- <item msgid="5425394847942513942">"Перамясціць уніз"</item>
- <item msgid="7728484337962740316">"Перамясціць управа"</item>
- <item msgid="324200556467459329">"Перамясціць уверх"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Не ўказаны"</string>
<string name="neuter" msgid="2075249330106127310">"Ніякі"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 592f6178e74d..5166d876ec11 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Анимации за предвиждащия жест за връщане назад"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Активиране на системните анимации за предвиждащия жест за връщане назад."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Тази настройка активира системните анимации за предвиждащите жестове. За целта във файла на манифеста трябва да зададете enableOnBackInvokedCallback на true за отделните приложения."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Преместване наляво"</item>
- <item msgid="5425394847942513942">"Преместване надолу"</item>
- <item msgid="7728484337962740316">"Преместване надясно"</item>
- <item msgid="324200556467459329">"Преместване нагоре"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Не е посочено"</string>
<string name="neuter" msgid="2075249330106127310">"Среден род"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 3fafee31d634..7f285f6e76d2 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -174,7 +174,7 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"কিছু ডিফল্ট সেট করা রয়েছে"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"কোনও ডিফল্ট সেট করা নেই"</string>
<string name="tts_settings" msgid="8130616705989351312">"পাঠ্য থেকে ভাষ্য আউটপুট সেটিংস"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"টেক্সট-টু-স্পিচ"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"টেক্সট-টু-স্পিচ আউটপুট"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"কথা বলার হার"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"যে গতিতে পাঠ্য উচ্চারিত হয়"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"পিচ"</string>
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"আলতো চাপ দেখান"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"আলতো চাপ দিলে ভিজ্যুয়াল প্রতিক্রিয়া দেখান"</string>
<string name="show_key_presses" msgid="6360141722735900214">"প্রেস করা কী দেখুন"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"প্রেস করা ফিজিকাল কীয়ের জন্য ভিস্যুয়াল মতামত দেখুন"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"ফিজিক্যাল কী প্রেস করা হলে ভিজুয়াল ফিডব্যাক দেখুন"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"সারফেস আপডেটগুলি দেখান"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"সম্পূর্ণ উইন্ডোর সারফেস আপডেট হয়ে গেলে সেটিকে ফ্ল্যাশ করুন"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"ভিউয়ের আপডেট দেখুন"</string>
@@ -674,7 +674,7 @@
<string name="physical_keyboard_title" msgid="4811935435315835220">"ফিজিক্যাল কীবোর্ড"</string>
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"কীবোর্ড লেআউট বেছে নিন"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"ডিফল্ট"</string>
- <string name="turn_screen_on_title" msgid="3266937298097573424">"স্ক্রিন চালু করুন"</string>
+ <string name="turn_screen_on_title" msgid="3266937298097573424">"স্ক্রিন চালু করা"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"স্ক্রিন চালু করার অনুমতি দিন"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"অ্যাপকে স্ক্রিন চালু করার অনুমতি দিন। অনুমতি দেওয়া হলে, অ্যাপ আপনার এক্সপ্লিসিট ইনটেন্ট ছাড়াই যেকোনও সময় স্ক্রিন চালু করতে পারবে।"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> সম্প্রচার বন্ধ করবেন?"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ফিরে যাওয়ার পূর্বাভাস সংক্রান্ত অ্যানিমেশন"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ফিরে যাওয়া সংক্রান্ত পূর্বাভাসের জন্য সিস্টেম অ্যানিমেশন চালু করুন।"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"জেসচারের পূর্বাভাস সংক্রান্ত অ্যানিমেশন দেখাতে এই সেটিং সিস্টেম অ্যানিমেশন চালু করে। এই সেটিংয়ে \'ম্যানিফেস্ট\' ফাইলে প্রত্যেক অ্যাপে enableOnBackInvokedCallback অ্যাট্রিবিউটকে \'ট্রু\' (true) হিসেবে সেট করতে হয়।"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"বাঁদিকে সরান"</item>
- <item msgid="5425394847942513942">"নিচে নামান"</item>
- <item msgid="7728484337962740316">"ডানদিকে সরান"</item>
- <item msgid="324200556467459329">"উপরে সরান"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"নির্দিষ্টভাবে উল্লেখ করা নেই"</string>
<string name="neuter" msgid="2075249330106127310">"ক্লীব"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 5f7bd2c3cfa5..d7daed5cf936 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -675,8 +675,8 @@
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tastature"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Zadano"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Uključivanje ekrana"</string>
- <string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvolite uključivanje ekrana"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvolite aplikaciji da uključi ekran. Ako se odobri, aplikacija može uključiti ekran bilo kada bez vaše izričite namjere."</string>
+ <string name="allow_turn_screen_on" msgid="6194845766392742639">"Dozvoli uključivanje ekrana"</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Dozvolite aplikaciji da uključuje ekran. Ako se odobri, aplikacija može uključiti ekran bilo kada bez vaše izričite namjere."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacije predvidljivog pokreta unazad"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućava animacije sistema za predvidljivi pokret unazad."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ova postavka omogućava animacije sistema za animaciju predvidljivih pokreta. Potrebno je po aplikaciji postaviti vrijednost za enableOnBackInvokedCallback na tačno u fajlu deklaracije."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Pomjeranje ulijevo"</item>
- <item msgid="5425394847942513942">"Pomjeranje nadolje"</item>
- <item msgid="7728484337962740316">"Pomjeranje udesno"</item>
- <item msgid="324200556467459329">"Pomjeranje nagore"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nije navedeno"</string>
<string name="neuter" msgid="2075249330106127310">"Srednji rod"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 7143f99207c9..89caaf94bdf7 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -306,7 +306,7 @@
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quan aquest mode està activat, és possible que l’adreça MAC d\'aquest dispositiu canviï cada vegada que es connecti a una xarxa amb l\'aleatorització d\'adreces MAC activada"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"D\'ús mesurat"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"D\'ús no mesurat"</string>
- <string name="select_logd_size_title" msgid="1604578195914595173">"Mides de la memòria intermèdia del registrador"</string>
+ <string name="select_logd_size_title" msgid="1604578195914595173">"Mides de la memòria intermèdia del registre"</string>
<string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Selecciona la mida de la memòria intermèdia del registre"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Vols esborrar l\'emmagatzematge persistent del registrador?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Quan deixem de supervisar amb el registrador persistent, hem d\'esborrar les dades del registrador que hi ha al teu dispositiu."</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacions de retrocés predictiu"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Activa animacions del sistema de retrocés predictiu"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Aquesta configuració activa animacions del sistema per a accions gestuals predictives. Requereix definir enableOnBackInvokedCallback com a \"true\" en cada aplicació al fitxer de manifest."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mou cap a l\'esquerra"</item>
- <item msgid="5425394847942513942">"Mou cap avall"</item>
- <item msgid="7728484337962740316">"Mou cap a la dreta"</item>
- <item msgid="324200556467459329">"Mou cap amunt"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"No s\'ha especificat"</string>
<string name="neuter" msgid="2075249330106127310">"Neutre"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 34e65e63c8e8..c4b49672372f 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Prediktivní animace gesta Zpět"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Povolit systémové animace prediktivního gesta Zpět"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Toto nastavení aktivuje systémové prediktivní animace gest. Vyžaduje, aby v souborech manifestu jednotlivých aplikací byl nastaven atribut enableOnBackInvokedCallback na hodnotu True."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Přesunout doleva"</item>
- <item msgid="5425394847942513942">"Přesunout dolů"</item>
- <item msgid="7728484337962740316">"Přesunout doprava"</item>
- <item msgid="324200556467459329">"Přesunout nahoru"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Neurčeno"</string>
<string name="neuter" msgid="2075249330106127310">"Střední rod"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 381c3cc630ea..94852b4c983e 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Foreslåede animationer for Tilbage"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivér systemanimationer for foreslåede animationer for Tilbage."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Denne indstilling aktiverer systemanimationer for de foreslåede animationer for bevægelsen Tilbage. Dette forudsætter konfiguration af enableOnBackInvokedCallback som sand for hver app i manifestfilen."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Flyt til venstre"</item>
- <item msgid="5425394847942513942">"Flyt ned"</item>
- <item msgid="7728484337962740316">"Flyt til højre"</item>
- <item msgid="324200556467459329">"Flyt op"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Ikke angivet"</string>
<string name="neuter" msgid="2075249330106127310">"Neutrum"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index b53d19181148..9d9a82a53d5b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animationen für intelligente „Zurück“-Touch-Geste"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Du kannst Systemanimationen für die intelligente „Zurück“-Touch-Geste aktivieren."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Diese Einstellung aktiviert Systemanimationen für intelligente Touch-Gesten. Dazu muss in der Manifestdatei enableOnBackInvokedCallback auf App-Ebene auf „true“ gesetzt werden."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Nach links"</item>
- <item msgid="5425394847942513942">"Nach unten"</item>
- <item msgid="7728484337962740316">"Nach rechts"</item>
- <item msgid="324200556467459329">"Nach oben"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nicht angegeben"</string>
<string name="neuter" msgid="2075249330106127310">"Neutrum"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index b4cc7aa2630e..d65f2562a445 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -585,7 +585,7 @@
<string name="user_grant_admin_message" msgid="1673791931033486709">"Οι διαχειριστές έχουν ειδικά προνόμια που δεν έχουν οι υπόλοιποι χρήστες Ένας διαχειριστής μπορεί να διαχειριστεί όλους τους χρήστες, να ενημερώσει ή να επαναφέρει αυτήν τη συσκευή, να τροποποιήσει τις ρυθμίσεις, να δει όλες τις εγκατεστημένες εφαρμογές και να εκχωρήσει ή να ανακαλέσει προνόμια διαχειριστή άλλων χρηστών."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Εκχώρηση δικαιωμάτων διαχειριστή"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Να γίνει ρύθμιση χρήστη τώρα;"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Βεβαιωθείτε ότι ο χρήστης μπορεί να πάρει τη συσκευή και ρυθμίστε τον χώρο του"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Βεβαιωθείτε ότι ο χρήστης μπορεί να πάρει τη συσκευή για τη ρύθμιση του χώρου του"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Να γίνει ρύθμιση προφίλ τώρα;"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Ρύθμιση τώρα"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Όχι τώρα"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Κινούμ. εικόνες μετάβασης προς τα πίσω με πρόβλεψη"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Ενεργοποίηση κινούμενων εικόνων συστήματος για μετάβαση προς τα πίσω με πρόβλεψη."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Αυτή η ρύθμιση ενεργοποιεί τις κινούμενες εικόνες συστήματος για τις κινούμενες εικόνες κινήσεων με πρόβλεψη. Απαιτεί τη ρύθμιση της παραμέτρου enableOnBackInvokedCallback ως αληθούς σε κάθε εφαρμογή στο αρχείο μανιφέστου."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Μετακίνηση αριστερά"</item>
- <item msgid="5425394847942513942">"Μετακίνηση προς τα κάτω"</item>
- <item msgid="7728484337962740316">"Μετακίνηση δεξιά"</item>
- <item msgid="324200556467459329">"Μετακίνηση προς τα επάνω"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Δεν έχει καθοριστεί"</string>
<string name="neuter" msgid="2075249330106127310">"Ουδέτερο"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 9fd825bf4e7f..e35bc1931691 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Move left"</item>
- <item msgid="5425394847942513942">"Move down"</item>
- <item msgid="7728484337962740316">"Move right"</item>
- <item msgid="324200556467459329">"Move up"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Not specified"</string>
<string name="neuter" msgid="2075249330106127310">"Neuter"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 546e5d238f54..08bcb77bfe68 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Move left"</item>
- <item msgid="5425394847942513942">"Move down"</item>
- <item msgid="7728484337962740316">"Move right"</item>
- <item msgid="324200556467459329">"Move up"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Not specified"</string>
<string name="neuter" msgid="2075249330106127310">"Neuter"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 9fd825bf4e7f..e35bc1931691 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Move left"</item>
- <item msgid="5425394847942513942">"Move down"</item>
- <item msgid="7728484337962740316">"Move right"</item>
- <item msgid="324200556467459329">"Move up"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Not specified"</string>
<string name="neuter" msgid="2075249330106127310">"Neuter"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 9fd825bf4e7f..e35bc1931691 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Move left"</item>
- <item msgid="5425394847942513942">"Move down"</item>
- <item msgid="7728484337962740316">"Move right"</item>
- <item msgid="324200556467459329">"Move up"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Not specified"</string>
<string name="neuter" msgid="2075249330106127310">"Neuter"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 8256cc953794..dba88d0fb167 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎Predictive back animations‎‏‎‎‏‎"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎Enable system animations for predictive back.‎‏‎‎‏‎"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file.‎‏‎‎‏‎"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎Move left‎‏‎‎‏‎"</item>
- <item msgid="5425394847942513942">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‎Move down‎‏‎‎‏‎"</item>
- <item msgid="7728484337962740316">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎Move right‎‏‎‎‏‎"</item>
- <item msgid="324200556467459329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎Move up‎‏‎‎‏‎"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$d</xliff:g>‎‏‎‎‏‏‏‎ %%‎‏‎‎‏‎"</string>
<string name="not_specified" msgid="5423502443185110328">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎Not specified‎‏‎‎‏‎"</string>
<string name="neuter" msgid="2075249330106127310">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎Neuter‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index ff9f7aeba4bf..79d3822b2e19 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animaciones de gesto predictivo"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Habilita animaciones del sistema para gestos de retroceso predictivos."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuración habilita las animaciones del sistema para la animación de gestos predictiva. Se requiere la configuración por app de enableOnBackInvokedCallback en verdadero en el archivo de manifiesto."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mover hacia la izquierda"</item>
- <item msgid="5425394847942513942">"Mover hacia abajo"</item>
- <item msgid="7728484337962740316">"Mover hacia la derecha"</item>
- <item msgid="324200556467459329">"Mover hacia arriba"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Sin especificar"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index abf60d8386ed..af03e18143c9 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -355,8 +355,8 @@
<string name="pointer_location_summary" msgid="957120116989798464">"Superpone los datos de las pulsaciones en la pantalla"</string>
<string name="show_touches" msgid="8437666942161289025">"Mostrar toques"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Muestra la ubicación de los toques en la pantalla"</string>
- <string name="show_key_presses" msgid="6360141722735900214">"Ver pulsación de teclas"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"Ver respuestas visuales al pulsar teclas físicas"</string>
+ <string name="show_key_presses" msgid="6360141722735900214">"Ver teclas pulsadas"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"Muestra respuestas visuales al pulsar teclas físicas"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Mostrar cambios de superficies"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Hace parpadear todas las superficies de la ventana cuando se actualizan"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Ver actualizaciones de vista"</string>
@@ -580,7 +580,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restringido"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"¿Añadir nuevo usuario?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Puedes compartir este dispositivo si creas más usuarios. Cada uno tendrá su propio espacio y podrá personalizarlo con aplicaciones, un fondo de pantalla y mucho más. Los usuarios también pueden ajustar opciones del dispositivo, como la conexión Wi‑Fi, que afectan a todos los usuarios.\n\nCuando añadas un usuario, tendrá que configurar su espacio.\n\nCualquier usuario puede actualizar aplicaciones de todos los usuarios. Es posible que no se transfieran los servicios y opciones de accesibilidad al nuevo usuario."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un nuevo usuario, dicha persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un nuevo usuario, dicha persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"¿Convertir a este usuario en administrador?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Los administradores tienen privilegios especiales que otros usuarios no tienen. Los administradores pueden gestionar todos los usuarios, actualizar o restablecer este dispositivo, modificar los ajustes, ver todas las aplicaciones instaladas y conceder o revocar privilegios de administrador a otros usuarios."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Convertir en administrador"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animaciones para acciones de retorno predictivas"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Habilita animaciones del sistema para acciones de retorno predictivas."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Este ajuste habilita animaciones del sistema para acciones gestuales predictivas. Exige definir el valor de enableOnBackInvokedCallback en \"verdadero\" para cada aplicación en el archivo de manifiesto."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Muévete hacia la izquierda"</item>
- <item msgid="5425394847942513942">"Muévete hacia abajo"</item>
- <item msgid="7728484337962740316">"Muévete hacia la derecha"</item>
- <item msgid="324200556467459329">"Muévete hacia arriba"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Sin especificar"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 4e70a53e4727..56e50f982a2a 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -585,7 +585,7 @@
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administraatoritel on eriõigused, mida teistel kasutajatel pole. Administraator saab hallata kõiki kasutajaid, värskendada või lähtestada seda seadet, muuta seadeid, vaadata kõiki installitud rakendusi ja anda teistele kasutajatele administraatoriõigused või need eemaldada."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Määra administraatoriks"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Kas seadistada kasutaja kohe?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Veenduge, et isik saaks seadet kasutada ja oma ruumi seadistada"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Veenduge, et isik saaks seadet kasutada ja oma ruumi seadistada."</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Kas soovite kohe profiili seadistada?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Seadista kohe"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Mitte praegu"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Tagasiliigutuse prognoosi animatsioon"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Lubage süsteemi animatsioonid, et näha prognoositud tagasiliigutusi."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"See seade võimaldab süsteemi animatsioonidel prognoosida tagasiliigutusi. See nõuab manifestifailis rakendusepõhise atribuudi enableOnBackInvokedCallback määramist tõeseks."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Liiguta vasakule"</item>
- <item msgid="5425394847942513942">"Liiguta alla"</item>
- <item msgid="7728484337962740316">"Liiguta paremale"</item>
- <item msgid="324200556467459329">"Liiguta üles"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Pole määratud"</string>
<string name="neuter" msgid="2075249330106127310">"Kesksugu"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 8dd60071ad54..41a365186108 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Atzera egiteko keinuaren animazio-igarleak"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Gaitu atzera egiteko keinuaren sistemaren animazio-igarleak."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Atzera egiteko keinuaren sistemaren animazio-igarleak gaitzen ditu ezarpenak. enableOnBackInvokedCallback-ek egiazko gisa ezarrita egon behar du aplikazio bakoitzaren manifestu-fitxategian."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Eraman ezkerrera"</item>
- <item msgid="5425394847942513942">"Eraman behera"</item>
- <item msgid="7728484337962740316">"Eraman eskuinera"</item>
- <item msgid="324200556467459329">"Eraman gora"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="not_specified" msgid="5423502443185110328">"Zehaztugabea"</string>
<string name="neuter" msgid="2075249330106127310">"Neutroa"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index beaaa3922557..838237863d7c 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -675,7 +675,7 @@
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"انتخاب طرح‌بندی صفحه‌کلید"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"پیش‌فرض"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"روشن کردن صفحه‌نمایش"</string>
- <string name="allow_turn_screen_on" msgid="6194845766392742639">"اعطای اجازه برای روشن کردن صفحه‌نمایش"</string>
+ <string name="allow_turn_screen_on" msgid="6194845766392742639">"اجازه روشن کردن صفحه‌نمایش"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"به برنامه اجازه می‌دهد صفحه‌نمایش را روشن کند. اگر اجازه داده شود، ممکن است این برنامه در هر زمانی بدون هدف صریح شما صفحه‌نمایش را روشن کند."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"همه‌فرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همه‌فرستی کنید یا خروجی را تغییر دهید، همه‌فرستی کنونی متوقف خواهد شد"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"پویانمایی‌های اشاره برگشت پیش‌گویانه"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"پویانمایی‌های سیستم را برای اشاره برگشت پیش‌گویانه فعال کنید."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏این تنظیم پویانمایی‌های سیستم را برای پویانمایی اشاره برگشت پیش‌بینانه فعال می‌کند. این تنظیم مستلزم تنظیم شدن enableOnBackInvokedCallback مربوط به هر برنامه روی صحیح در فایل مانیفست است."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"انتقال به‌چپ"</item>
- <item msgid="5425394847942513942">"انتقال به‌پایین"</item>
- <item msgid="7728484337962740316">"انتقال به‌راست"</item>
- <item msgid="324200556467459329">"انتقال به‌بالا"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>٪"</string>
<string name="not_specified" msgid="5423502443185110328">"نامشخص"</string>
<string name="neuter" msgid="2075249330106127310">"خنثی"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index ec1c1f1843dd..20ed75eb9dfa 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Takaisin siirtymisen ennakoivat animaatiot"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Ota käyttöön takaisin siirtymisen ennakoivat järjestelmäanimaatiot"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Asetus ottaa järjestelmäanimaatiot käyttöön ennakoiville eleanimaatioille. Se edellyttää, että enableOnBackInvokedCallback-arvo on Tosi sovelluksen manifestitiedostossa."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Siirrä vasemmalle"</item>
- <item msgid="5425394847942513942">"Siirrä alas"</item>
- <item msgid="7728484337962740316">"Siirrä oikealle"</item>
- <item msgid="324200556467459329">"Siirrä ylös"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Ei määritetty"</string>
<string name="neuter" msgid="2075249330106127310">"Neutri"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index f48bfcb4eb75..3fdf3042a1dc 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animations pour le retour prédictif"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Activer les animations système pour le retour prédictif."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre permet d\'activer les animations du système pour l\'animation des gestes prédictifs. Cela exige de définir le paramètre enableOnBackInvokedCallback à Vrai pour chaque application dans le fichier de configuration."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Déplacez vers la gauche"</item>
- <item msgid="5425394847942513942">"Déplacez vers le bas"</item>
- <item msgid="7728484337962740316">"Déplacez vers la droite"</item>
- <item msgid="324200556467459329">"Déplacez vers le haut"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Non précisé"</string>
<string name="neuter" msgid="2075249330106127310">"Neutre"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ca5edfe44227..7e99fa7ac12e 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -355,8 +355,8 @@
<string name="pointer_location_summary" msgid="957120116989798464">"Superposition à l\'écran indiquant l\'emplacement actuel du curseur"</string>
<string name="show_touches" msgid="8437666942161289025">"Indicateurs visuels"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Afficher un indicateur visuel là où l\'utilisateur appuie sur l\'écran"</string>
- <string name="show_key_presses" msgid="6360141722735900214">"Afficher appuis touche"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"Afficher retour visuel pour appuis de touches"</string>
+ <string name="show_key_presses" msgid="6360141722735900214">"Afficher les pressions sur les touches"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"Afficher un retour visuel des pressions sur les touches"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Mises à jour de la surface"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Faire clignoter les endroits où des mises à jour sont effectuées"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Mises à jour de fenêtres"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animations pour prévisualisation du Retour"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Activer les animations système pour la prévisualisation du Retour"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre active les animations système pour la prévisualisation du geste de retour. Pour cela, enableOnBackInvokedCallback doit être défini sur \"True\" dans le fichier manifeste de chaque appli."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Déplacer vers la gauche"</item>
- <item msgid="5425394847942513942">"Déplacer vers le bas"</item>
- <item msgid="7728484337962740316">"Déplacer vers la droite"</item>
- <item msgid="324200556467459329">"Déplacer vers le haut"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Non défini"</string>
<string name="neuter" msgid="2075249330106127310">"Neutre"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 61b01f63e687..8132a87f39f4 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacións de retroceso preditivo"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Activa as animacións do sistema para o retroceso preditivo."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta opción de configuración activa as animacións xestuais preditivas. É preciso definir enableOnBackInvokedCallback como True (verdadeiro) para cada aplicación no ficheiro de manifesto."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mover cara á esquerda"</item>
- <item msgid="5425394847942513942">"Mover cara abaixo"</item>
- <item msgid="7728484337962740316">"Mover cara á dereita"</item>
- <item msgid="324200556467459329">"Mover cara arriba"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Sen especificar"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 981cf57d734e..239b04d3e944 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"પાછળના પૂર્વાનુમાનિત ઍનિમેશન્સ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"પાછળના પૂર્વાનુમાનિત સંકેત માટે સિસ્ટમ ઍનિમેશન ચાલુ કરો."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"આ સેટિંગ પૂર્વાનુમાનિત સંકેત ઍનિમેશન માટે સિસ્ટમ ઍનિમેશન ચાલુ કરે છે. તેના માટે દરેક ઍપ માટે મેનિફેસ્ટ ફાઇલમાં enableOnBackInvokedCallbackને true પર સેટ કરવાની જરૂર પડે છે."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ડાબે ખસેડો"</item>
- <item msgid="5425394847942513942">"નીચે ખસેડો"</item>
- <item msgid="7728484337962740316">"જમણે ખસેડો"</item>
- <item msgid="324200556467459329">"ઉપર ખસેડો"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"ઉલ્લેખિત નથી"</string>
<string name="neuter" msgid="2075249330106127310">"નાન્યતર"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 9be1cd68b789..06ddcd9f4c72 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -214,7 +214,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"प्रोफ़ाइल चुनें"</string>
<string name="category_personal" msgid="6236798763159385225">"निजी"</string>
- <string name="category_work" msgid="4014193632325996115">"वर्क ऐप्लिकेशन"</string>
+ <string name="category_work" msgid="4014193632325996115">"वर्क"</string>
<string name="category_clone" msgid="1554511758987195974">"क्लोन"</string>
<string name="development_settings_title" msgid="140296922921597393">"डेवलपर के लिए सेटिंग और टूल"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"डेवलपर के लिए सेटिंग और टूल चालू करें"</string>
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"टैप दिखाएं"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"टैप के लिए विज़ुअल फ़ीडबैक दिखाएं"</string>
<string name="show_key_presses" msgid="6360141722735900214">"दबाए गए बटन दिखाएं"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"दबाए गए बटन के लिए विज़ुअल फ़ीडबैक दिखाएं"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"दबाए गए बटन का विज़ुअल फ़ीडबैक दिखाएं"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"सर्फ़ेस अपडेट दिखाएं"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"अपडेट होने पर पूरे विंडो सर्फ़ेस फ़्लैश करें"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"जीपीयू व्यू के अपडेट दिखाएं"</string>
@@ -584,10 +584,10 @@
<string name="user_grant_admin_title" msgid="5157031020083343984">"क्या इस व्यक्ति को एडमिन बनाना है?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"एडमिन के पास अन्य लोगों के मुकाबले खास अधिकार होते हैं. एडमिन के पास ये अधिकार होते हैं: सभी लोगों को मैनेज करना, इस डिवाइस को अपडेट या रीसेट करना, सेटिंग में बदलाव करना, इंस्टॉल किए गए सभी ऐप्लिकेशन देखना, और अन्य लोगों को एडमिन के खास अधिकार देना या उन्हें वापस लेना."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"एडमिन बनाएं"</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"उपयोगकर्ता को अभी सेट करें?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"पक्का करें कि व्यक्ति डिवाइस का इस्तेमाल करने और अपनी जगह सेट करने के लिए मौजूद है"</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"उपयोगकर्ता खाता सेटअप करना है?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"पक्का करें कि उपयोगकर्ता, डिवाइस पर अपने खाते को पसंद के हिसाब से सेट अप करने के लिए मौजूद हो"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"प्रोफ़ाइल अभी सेट करें?"</string>
- <string name="user_setup_button_setup_now" msgid="1708269547187760639">"अभी सेट करें"</string>
+ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"अभी सेट अप करें"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"रद्द करें"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"जोड़ें"</string>
<string name="user_new_user_name" msgid="60979820612818840">"नया उपयोगकर्ता"</string>
@@ -674,7 +674,7 @@
<string name="physical_keyboard_title" msgid="4811935435315835220">"फ़िज़िकल कीबोर्ड"</string>
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"कीबोर्ड का लेआउट चुनें"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"डिफ़ॉल्ट"</string>
- <string name="turn_screen_on_title" msgid="3266937298097573424">"स्क्रीन चालू करें"</string>
+ <string name="turn_screen_on_title" msgid="3266937298097573424">"स्क्रीन चालू करने की अनुमति"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"स्क्रीन चालू करने की अनुमति दें"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"ऐप्लिकेशन को स्क्रीन चालू करने की अनुमति दें. ऐसा करने पर, ऐप्लिकेशन आपकी अनुमति लिए बिना भी, जब चाहे स्क्रीन चालू कर सकता है."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"पीछे जाने पर झलक दिखाने वाले जेस्चर का ऐनिमेशन"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"पीछे जाने पर झलक दिखाने वाले हाथ के जेस्चर के लिए सिस्टम ऐनिमेशन चालू करें."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"यह सेटिंग, सिस्टम के ऐनिमेशन को प्रिडिक्टिव जेस्चर ऐनिमेशन के लिए चालू कर देती है. मेनिफ़ेस्ट फ़ाइल में enableOnBackInvokedCallback की सेटिंग को हर ऐप्लिकेशन के हिसाब से \'सही\' पर सेट होना चाहिए."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"बाईं ओर ले जाएं"</item>
- <item msgid="5425394847942513942">"नीचे ले जाएं"</item>
- <item msgid="7728484337962740316">"दाईं ओर ले जाएं"</item>
- <item msgid="324200556467459329">"ऊपर की ओर ले जाएं"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"जानकारी नहीं दी गई"</string>
<string name="neuter" msgid="2075249330106127310">"नपुंसक लिंग"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 8a0114a0d636..c5bea2761ed6 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka s pregledom"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućuje animaciju kad korisnik napravi povratnu kretnju."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ova postavka omogućuje animacije sustava za animaciju pokreta s predviđanjem. Zahtijeva postavljanje dopuštenja enableOnBackInvokedCallback po aplikaciji na True u datoteci manifesta."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Pomicanje ulijevo"</item>
- <item msgid="5425394847942513942">"Pomicanje prema dolje"</item>
- <item msgid="7728484337962740316">"Pomicanje udesno"</item>
- <item msgid="324200556467459329">"Pomicanje prema gore"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nije navedeno"</string>
<string name="neuter" msgid="2075249330106127310">"Srednji rod"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index b5e1e01587b5..e43ed439a8d3 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Prediktív „vissza” kézmozdulat-animációk"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Rendszeranimációk engedélyezése prediktív „vissza” kézmozdulatok esetén."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"A beállítás engedélyezi a rendszeranimációkat a prediktív kézmozdulat-animációk esetén. A használatukhoz az enableOnBackInvokedCallback beállítást true értékre kell állítani az egyes alkalmazások manifestfájljaiban."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mozgatás balra"</item>
- <item msgid="5425394847942513942">"Mozgatás lefelé"</item>
- <item msgid="7728484337962740316">"Mozgatás jobbra"</item>
- <item msgid="324200556467459329">"Mozgatás felfelé"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nincs megadva"</string>
<string name="neuter" msgid="2075249330106127310">"Semleges nemű alak"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 9808f709fdcb..b8f94f48285b 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"«Հետ» ժեստի հուշման շարժանկարներ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Միացնել համակարգի անիմացիաները «Հետ» ժեստի հուշման համար"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Այս կարգավորման միջոցով կարելի է միացնել համակարգային շարժանկարները ժեստի հուշման համար։ Կարգավորումը պահանջում է մանիֆեստի ֆայլում սահմանել true արժեքը per-app enableOnBackInvokedCallback հատկության համար։"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Տեղափոխել ձախ"</item>
- <item msgid="5425394847942513942">"Տեղափոխել ներքև"</item>
- <item msgid="7728484337962740316">"Տեղափոխել աջ"</item>
- <item msgid="324200556467459329">"Տեղափոխել վերև"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Նշված չէ"</string>
<string name="neuter" msgid="2075249330106127310">"Չեզոք"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7d70b88844ba..f867ba58dcdc 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -598,7 +598,7 @@
<string name="user_set_lock_button" msgid="1427128184982594856">"Setel kunci"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"Beralih ke <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Membuat pengguna baru …"</string>
- <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Membuat tamu baru …"</string>
+ <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Membuat tamu baru…"</string>
<string name="add_user_failed" msgid="4809887794313944872">"Gagal membuat pengguna baru"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Gagal membuat tamu baru"</string>
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animasi kembali prediktif"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktifkan animasi sistem untuk kembali prediktif."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Setelan ini mengaktifkan animasi sistem untuk animasi gestur prediktif. Setelan ini mewajibkan enableOnBackInvokedCallback per-aplikasi disetel ke benar (true) dalam file manifes."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Pindahkan ke kiri"</item>
- <item msgid="5425394847942513942">"Pindahkan ke bawah"</item>
- <item msgid="7728484337962740316">"Pindahkan ke kanan"</item>
- <item msgid="324200556467459329">"Pindahkan ke atas"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Tidak ditentukan"</string>
<string name="neuter" msgid="2075249330106127310">"Netral"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 650f76d990f4..aa9d8f82f43a 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Hreyfimyndir flýtiritunar við bendinguna „til baka“"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Kveikja á hreyfimyndum í kerfinu til að sýna hreyfimyndir þegar bendingin „til baka“ er gerð."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Þessi stilling kveikir á hreyfimyndum í kerfinu til að sýna hreyfimyndir flýtiritunar með bendingum. Stillingin krefst þess að kveikt sé á enableOnBackInvokedCallback í upplýsingaskránni fyrir hvert forrit."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Færa til vinstri"</item>
- <item msgid="5425394847942513942">"Færa niður"</item>
- <item msgid="7728484337962740316">"Færa til hægri"</item>
- <item msgid="324200556467459329">"Færa upp"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Ekki gefið upp"</string>
<string name="neuter" msgid="2075249330106127310">"Kynsegin"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index d783bf1b4e71..1f35f74a9c41 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animazioni predittive per Indietro"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Attiva le animazioni di sistema per il gesto Indietro predittivo."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Questa impostazione attiva le animazioni di sistema per il gesto Indietro predittivo. Richiede di impostare il metodo enableOnBackInvokedCallback su true nel file manifest di tutte le app."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Sposta a sinistra"</item>
- <item msgid="5425394847942513942">"Sposta in basso"</item>
- <item msgid="7728484337962740316">"Sposta a destra"</item>
- <item msgid="324200556467459329">"Sposta in alto"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Non specificato"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index fc83630c30cb..f0a19d414f3e 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"חיזוי אנימציה של תנועת החזרה"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"הפעלת אנימציות מערכת עבור חיזוי של תנועת החזרה."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏ההגדרה הזו מפעילה אנימציות מערכת עבור חיזוי אנימציה של תנועת החזרה. היא מחייבת הגדרה בכל אפליקציה של ערך true בשדה enableOnBackInvokedCallback בקובץ המניפסט."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"הזזה שמאלה"</item>
- <item msgid="5425394847942513942">"הזזה למטה"</item>
- <item msgid="7728484337962740316">"הזזה ימינה"</item>
- <item msgid="324200556467459329">"הזזה למעלה"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="not_specified" msgid="5423502443185110328">"לא רוצה להגדיר"</string>
<string name="neuter" msgid="2075249330106127310">"ניטרלי"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 3f090830de40..36c11cd8c431 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"タップを表示"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"タップを視覚表示する"</string>
<string name="show_key_presses" msgid="6360141722735900214">"キーの押下を表示"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"物理キーの押下に関する視覚的フィードバックを表示"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"物理キーが押下されたことを視覚的に表示"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"表示面の更新を通知"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"更新時にウィンドウの表示面全体を点滅させる"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"画面の更新を表示"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"予測型「戻る」アニメーション"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"予測型「戻る」のシステム アニメーションを有効にする。"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"この設定は、予測型操作のシステム アニメーションを有効にします。アプリごとにマニフェスト ファイルで enableOnBackInvokedCallback を true に設定する必要があります。"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"左に移動"</item>
- <item msgid="5425394847942513942">"下に移動"</item>
- <item msgid="7728484337962740316">"右に移動"</item>
- <item msgid="324200556467459329">"上に移動"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"指定しない"</string>
<string name="neuter" msgid="2075249330106127310">"中性"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index ed7c8d7cd207..f516cf29d222 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"უკან დაბრუნების ანიმაციის პროგნოზირება"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"უკან დაბრუნების პროგნოზირებადი ანიმაციისთვის სისტემის ანიმაციების ჩართვა."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ეს პარამეტრი ჩართავს სისტემის ანიმაციებს ჟესტების პროგნოზირებადი ანიმაციებისთვის. საჭიროა, რომ აღწერის ფაილში აპის enableOnBackInvokedCallback პარამეტრი იყოს ჭეშმარიტი."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"მარცხნივ გადატანა"</item>
- <item msgid="5425394847942513942">"ქვემოთ გადატანა"</item>
- <item msgid="7728484337962740316">"მარჯვნივ გადატანა"</item>
- <item msgid="324200556467459329">"ზემოთ გადატანა"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"არ არის მითითებული"</string>
<string name="neuter" msgid="2075249330106127310">"საშუალო"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 982000f68852..36ee23abb15d 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"\"Артқа\" қимылына арналған тұспал анимациясы"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"\"Артқа\" қимылына арналған жүйелік тұспал анимацияларын іске қосу."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Бұл параметр қимылға арналған жүйелік тұспал анимацияларын іске қосады. Ол үшін әр қолданбаның манифест файлында enableOnBackInvokedCallback үшін \"True\" мәні қойылуы керек."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Солға жылжыту"</item>
- <item msgid="5425394847942513942">"Төмен жылжыту"</item>
- <item msgid="7728484337962740316">"Оңға жылжыту"</item>
- <item msgid="324200556467459329">"Жоғары жылжыту"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Көрсетілмеген"</string>
<string name="neuter" msgid="2075249330106127310">"Орта тек"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 26bb1e27661c..75c0f6a81c2f 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"បង្ហាញការចុច"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"បង្ហាញដានចុច នៅពេលចុច"</string>
<string name="show_key_presses" msgid="6360141722735900214">"បង្ហាញការចុចគ្រាប់ចុច"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"បង្ហាញព័ត៌មានឆ្លើយតបជារូបភាពសម្រាប់ការចុចគ្រាប់ចុចរូបវន្ត"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"បង្ហាញរូបភាពប្រតិកម្មសម្រាប់ការចុចគ្រាប់ចុចរូបវន្ត"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"បង្ហាញ​បច្ចុប្បន្នភាព​ផ្ទៃ"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"ផ្ទៃ​វីនដូទាំង​មូល​បញ្ចេញពន្លឺ​នៅពេល​ធ្វើ​បច្ចុប្បន្នភាព"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"បង្ហាញ​បច្ចុប្បន្នភាពទិដ្ឋភាព"</string>
@@ -585,7 +585,7 @@
<string name="user_grant_admin_message" msgid="1673791931033486709">"អ្នកគ្រប់គ្រងមានសិទ្ធិពិសេសដែលអ្នកប្រើប្រាស់ផ្សេងទៀតមិនមាន។ អ្នកគ្រប់គ្រងអាចគ្រប់គ្រងអ្នកប្រើប្រាស់ទាំងអស់ ធ្វើបច្ចុប្បន្នភាពឬកំណត់ឧបករណ៍នេះឡើងវិញ កែសម្រួលការកំណត់ មើលកម្មវិធីដែលបានដំឡើងទាំងអស់ និងផ្ដល់ឬដកសិទ្ធិជាអ្នកគ្រប់គ្រងសម្រាប់អ្នកផ្សេងទៀត។"</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"ផ្ដល់សិទ្ធិជាអ្នកគ្រប់គ្រង"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"រៀបចំ​អ្នក​ប្រើ​ប្រាស់ឥឡូវនេះ?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"សូម​ប្រាកដ​ថា​​អ្នក​ប្រើ​ប្រាស់នេះ​អាច​យក​​ឧបករណ៍ ​និង​រៀបចំ​​ទំហំ​ផ្ទុករបស់​គេបាន"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"សូម​ប្រាកដ​ថា​​អ្នក​ប្រើ​ប្រាស់នេះ​អាច​យក​​ឧបករណ៍ ​និង​រៀបចំ​​ទំហំ​ផ្ទុករបស់​គាត់បាន"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"រៀបចំ​ប្រវត្តិរូប​ឥឡូវ?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"រៀបចំ​ឥឡូវ"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"កុំទាន់"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ចលនា​ថយក្រោយ​ដែល​ព្យាករ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"បើក​ចលនា​ប្រព័ន្ធ​សម្រាប់​ការ​ថយក្រោយ​ព្យាករ។"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ការ​កំណត់នេះ​បើក​ចលនា​ប្រព័ន្ធ​សម្រាប់​ចលនាព្យាករ។ ចលនា​នេះ​ទាមទារ​ការ​កំណត់ enableOnBackInvokedCallback នៅ​ក្នុងកម្មវិធី​ទៅពិត​នៅ​ក្នុង​ឯកសារ​មេនីហ្វេសថ៍។"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ផ្លាស់ទី​ទៅ​ឆ្វេង"</item>
- <item msgid="5425394847942513942">"ផ្លាស់ទី​ចុះ​ក្រោម"</item>
- <item msgid="7728484337962740316">"ផ្លាស់ទីទៅ​ស្តាំ"</item>
- <item msgid="324200556467459329">"ផ្លាស់ទី​ឡើង​លើ"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"មិនបានបញ្ជាក់"</string>
<string name="neuter" msgid="2075249330106127310">"អភេទ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 5a09396480e7..94df4192aa88 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -579,7 +579,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"ಬಳಕೆದಾರ"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"ನಿರ್ಬಂಧಿಸಿದ ಪ್ರೊಫೈಲ್"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಬೇಕೆ?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಆ್ಯಪ್‌ಗಳು, ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"ಈ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಬೇಕೆ?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"ನಿರ್ವಾಹಕರು ಇತರ ಬಳಕೆದಾರರಿಗೆ ಇಲ್ಲದ ವಿಶೇಷ ಸೌಲಭ್ಯಗಳನ್ನು ಹೊಂದಿದ್ದಾರೆ. ನಿರ್ವಾಹಕರು ಎಲ್ಲಾ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಬಹುದು, ಈ ಸಾಧನವನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು ಅಥವಾ ರೀಸೆಟ್ ಮಾಡಬಹುದು, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಹೊಂದಿಸಬಹುದು, ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ಇತರರಿಗೆ ನಿರ್ವಾಹಕರಿಗೆ ನೀಡಿರುವ ಸೌಲಭ್ಯಗಳನ್ನು ನೀಡಬಹುದು ಅಥವಾ ಹಿಂತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ಮುನ್ಸೂಚಕ ಬ್ಯಾಕ್ ಆ್ಯನಿಮೇಶನ್‌ಗಳು"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ಮುನ್ಸೂಚಕ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್‌ಗಾಗಿ ಸಿಸ್ಟಂ ಆ್ಯನಿಮೇಶನ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ಮುನ್ನೋಟದ ಗೆಸ್ಚರ್ ಆ್ಯನಿಮೇಶನ್‌ಗಾಗಿ ಸಿಸ್ಟಂ ಆ್ಯನಿಮೇಶನ್‌ಗಳನ್ನು ಈ ಸೆಟ್ಟಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸುತ್ತವೆ. ಇದನ್ನು ಮಾಡಲು, ಪ್ರತಿ ಆ್ಯಪ್‌ನ ಮ್ಯಾನಿಫೆಸ್ಟ್ ಫೈಲ್‌ನಲ್ಲಿರುವ enableOnBackInvokedCallback ಪ್ಯಾರಾಮೀಟರ್ ಅನ್ನು ಸರಿ ಎಂದು ಹೊಂದಿಸಬೇಕು."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</item>
- <item msgid="5425394847942513942">"ಕೆಳಕ್ಕೆ ಸರಿಸಿ"</item>
- <item msgid="7728484337962740316">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</item>
- <item msgid="324200556467459329">"ಮೇಲಕ್ಕೆ ಸರಿಸಿ"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿಲ್ಲ"</string>
<string name="neuter" msgid="2075249330106127310">"ನಪುಂಸಕ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 1c5fd76ad7b6..db215dda4245 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -580,7 +580,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"제한된 프로필"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"신규 사용자를 추가할까요?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"추가 사용자를 만들어 다른 사용자와 기기를 공유할 수 있습니다. 각 사용자는 앱, 배경화면 등으로 맞춤설정할 수 있는 자신만의 공간을 갖게 됩니다. 또한 모든 사용자에게 영향을 미치는 Wi‑Fi와 같은 기기 설정도 조정할 수 있습니다.\n\n추가된 신규 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자가 앱을 업데이트할 수 있으며, 업데이트는 다른 사용자에게도 적용됩니다. 접근성 설정 및 서비스는 신규 사용자에게 이전되지 않을 수도 있습니다."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자는 다른 사용자들을 위하여 앱을 업데이트할 수 있습니다."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"추가된 신규 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자가 앱을 업데이트할 수 있으며, 업데이트는 다른 사용자에게도 적용됩니다."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"이 사용자에게 관리자 권한을 부여하시겠습니까?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"관리자는 다른 사용자가 가지지 못한 특별한 권한을 보유합니다. 관리자는 모든 사용자를 관리하고, 기기를 업데이트하거나 재설정하고, 설정을 변경하고, 설치된 모든 앱을 확인하고, 다른 사용자에게 관리자 권한을 부여하거나 취소할 수 있습니다."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"관리자 권한 부여"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"예측된 뒤로 동작 애니메이션"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"예측된 뒤로 동작에 시스템 애니메이션을 사용하도록 설정합니다."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"이 설정은 예측된 동작 애니메이션에 시스템 애니메이션을 사용하도록 합니다. 매니페스트 파일에서 앱별 enableOnBackInvokedCallback을 True로 설정해야 합니다."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"왼쪽으로 이동"</item>
- <item msgid="5425394847942513942">"아래로 이동"</item>
- <item msgid="7728484337962740316">"오른쪽으로 이동"</item>
- <item msgid="324200556467459329">"위로 이동"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"지정되지 않음"</string>
<string name="neuter" msgid="2075249330106127310">"중성"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 4ad4306286bd..3f6874f1f00a 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -351,10 +351,10 @@
<string name="debug_monitoring_category" msgid="1597387133765424994">"Мониторинг"</string>
<string name="strict_mode" msgid="889864762140862437">"Катаал режим иштетилди"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"Узак операцияларда экран күйүп-өчүп турат"</string>
- <string name="pointer_location" msgid="7516929526199520173">"Көрсөткүчтүн жайгшкн жери"</string>
+ <string name="pointer_location" msgid="7516929526199520173">"Көрсөткүчтүн турган жери"</string>
<string name="pointer_location_summary" msgid="957120116989798464">"Басылган жерлер жана жаңсоолор экранда көрүнүп турат"</string>
<string name="show_touches" msgid="8437666942161289025">"Басылган жерлерди көрсөтүү"</string>
- <string name="show_touches_summary" msgid="3692861665994502193">"Экранда басылган жерлер көрүнүп турат"</string>
+ <string name="show_touches_summary" msgid="3692861665994502193">"Экрандын басылган жерлери көрүнүп турат"</string>
<string name="show_key_presses" msgid="6360141722735900214">"Баскычтардын басылганын көрсөтүү"</string>
<string name="show_key_presses_summary" msgid="725387457373015024">"Баскычтар басылганда визуалдык сигнал көрүнөт"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Экран жаңыруусун көрсөтүү"</string>
@@ -584,8 +584,8 @@
<string name="user_grant_admin_title" msgid="5157031020083343984">"Бул колдонуучуну админ кыласызбы?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Админдердин өзгөчө укуктары бар. Админ бардык колдонуучуларды тескеп, бул түзмөктү жаңыртып же баштапкы абалга келтирип, параметрлерди өзгөртүп, орнотулган колдонмолордун баарын көрүп, башкаларга админ укуктарын берип же жокко чыгара алат."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Админ кылуу"</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"Профилди жөндөйсүзбү?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Өз мейкиндигин жөндөп алышы үчүн, түзмөктү колдонуучуга беришиңиз керек."</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"Профиль түзөсүзбү?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Колдонуучу өз мейкиндигин түзүп алышы үчүн түзмөктү ага беришиңиз керек."</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Профайл азыр түзүлсүнбү?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Азыр түзүү"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Азыр эмес"</string>
@@ -676,7 +676,7 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Демейки"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Экранды күйгүзүү"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Экранды күйгүзүүгө уруксат берүү"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Колдонмого экранды күйгүзүүгө уруксат бериңиз. Уруксат берилсе, колдонмо экранды каалаган убакта сизден уруксат сурабастан күйгүзүшү мүмкүн."</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Колдонмого экранды күйгүзүүгө уруксат бересиз. Колдонмо экранды каалаган убакта сизден уруксат сурабастан күйгүзө берет."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Божомолдонгон анимациялар"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Божомолдоп билүү үчүн системанын анимацияларын иштетиңиз."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Бул параметр жаңсоо анимациясын божомолдоп билүү үчүн системанын анимацияларын иштетет. Ал үчүн манифест файлындагы enableOnBackInvokedCallback параметри ар бир колдонмо үчүн \"true\" деп коюлушу керек."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Солго жылдыруу"</item>
- <item msgid="5425394847942513942">"Төмөн жылдыруу"</item>
- <item msgid="7728484337962740316">"Оңго жылдыруу"</item>
- <item msgid="324200556467459329">"Жогору жылдыруу"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Көрсөтүлгөн эмес"</string>
<string name="neuter" msgid="2075249330106127310">"Орто жак"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index fe8b4db7db09..fc82a9be57e0 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"ສະແດງການແຕະ"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"ສະແດງຄໍາຕິຊົມທາງຮູບພາບສຳລັບການແຕະ"</string>
<string name="show_key_presses" msgid="6360141722735900214">"ສະແດງການກົດປຸ່ມ"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"ສະແດງຄຳຕິຊົມພາບສຳລັບການກົດປຸ່ມຈິງ"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"ສະແດງການຕອບສະໜອງທີ່ເປັນພາບສຳລັບການກົດປຸ່ມຈິງ"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"ສະແດງການອັບເດດພື້ນຜິວ"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"ກະພິບໜ້າຈໍທັງໜ້າເມື່ອມີການອັບເດດ"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"ສະແດງອັບເດດມຸມມອງ"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ອະນິເມຊັນກັບຫຼັງແບບຄາດເດົາ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ເປີດການນຳໃຊ້ອະນິເມຊັນລະບົບສຳລັບການກັບຫຼັງແບບຄາດເດົາ."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ການຕັ້ງຄ່ານີ້ຈະເປີດການນຳໃຊ້ອະນິເມຊັນລະບົບສຳລັບອະນິເມຊັນທ່າທາງແບບຄາດເດົາ. ມັນຕ້ອງໃຊ້ການຕັ້ງຄ່າຕໍ່ແອັບ enableOnBackInvokedCallback ເປັນ true ໃນໄຟລ໌ manifest."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ຍ້າຍໄປຊ້າຍ"</item>
- <item msgid="5425394847942513942">"ຍ້າຍລົງ"</item>
- <item msgid="7728484337962740316">"ຍ້າຍໄປຂວາ"</item>
- <item msgid="324200556467459329">"ຍ້າຍຂຶ້ນ"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"ບໍ່ໄດ້ລະບຸ"</string>
<string name="neuter" msgid="2075249330106127310">"ບໍ່ມີເພດ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index e4546e1db323..bc4630dc7f80 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Numatomos grįžimo atgal gestų animacijos"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Įgalinkite sistemos animacijas, kad būtų galima naudoti numatomus grįžimo atgal gestus."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Šis nustatymas įgalina numatomų grįžimo atgal gestų sistemos animacijas. Aprašo faile programos lauką „enableOnBackInvokedCallback“ reikia nustatyti į vertę „true“."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Perkelti kairėn"</item>
- <item msgid="5425394847942513942">"Perkelti žemyn"</item>
- <item msgid="7728484337962740316">"Perkelti dešinėn"</item>
- <item msgid="324200556467459329">"Perkelti aukštyn"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nenurodyta"</string>
<string name="neuter" msgid="2075249330106127310">"Bevardė giminė"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index e9410a20ba5a..133520be1498 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animāciju prognozēšana pāriešanai atpakaļ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Iespējot sistēmas animācijas prognozētam žestam pāriešanai atpakaļ."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Šis iestatījums iespējo sistēmas animācijas prognozēto žestu animācijām. Lai to varētu izmantot, parametram “enableOnBackInvokedCallback” lietotnes manifesta failā jāiestata vērtība “true”."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Pārvietojiet pirkstu pa kreisi"</item>
- <item msgid="5425394847942513942">"Pārvietojiet pirkstu lejup"</item>
- <item msgid="7728484337962740316">"Pārvietojiet pirkstu pa labi"</item>
- <item msgid="324200556467459329">"Pārvietojiet pirkstu augšup"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nav norādīta"</string>
<string name="neuter" msgid="2075249330106127310">"Nekatrā dzimte"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 4866e6ad8f08..2de999818a39 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Анимации за движењето за враќање"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Овозможете системски анимации за движењето за враќање."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Поставкава ги овозможува системските анимации за предвидливи движења. Поставката треба да се постави на „точно“ преку апликација enableOnBackInvokedCallback во датотеката за манифест."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Преместете налево"</item>
- <item msgid="5425394847942513942">"Преместете надолу"</item>
- <item msgid="7728484337962740316">"Преместете надесно"</item>
- <item msgid="324200556467459329">"Преместете нагоре"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Не е наведено"</string>
<string name="neuter" msgid="2075249330106127310">"Среден род"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 78a3968bb0d5..0aad465e1c9e 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"പ്രെഡിക്റ്റീവ് ബാക്ക് ആനിമേഷനുകൾ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"പ്രെഡിക്റ്റീവ് ബാക്കിനായി സിസ്റ്റം ആനിമേഷനുകൾ പ്രവർത്തനക്ഷമമാക്കുക."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ഈ ക്രമീകരണം പ്രെഡിക്റ്റീവ് ജെസ്ച്ചർ ആനിമേഷന് വേണ്ടി സിസ്റ്റം ആനിമേഷനുകളെ പ്രവർത്തനക്ഷമമാക്കുന്നു. ഇതിന് ഓരോ ആപ്പിലും enableOnBackInvokedCallback എന്നത് മാനിഫെസ്റ്റ് ഫയലിൽ ശരി എന്ന് സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ഇടത്തേക്ക് നീക്കുക"</item>
- <item msgid="5425394847942513942">"താഴേക്ക് നീക്കുക"</item>
- <item msgid="7728484337962740316">"വലത്തേക്ക് നീക്കുക"</item>
- <item msgid="324200556467459329">"മുകളിലേക്ക് നീക്കുക"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"വ്യക്തമാക്കിയിട്ടില്ലാത്തവ"</string>
<string name="neuter" msgid="2075249330106127310">"നപുംസകലിംഗം"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 31f190ddd4fc..94e6059bc270 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"Товшилтыг харуулах"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Товшилтын визуал хариу үйлдлийг харуулах"</string>
<string name="show_key_presses" msgid="6360141722735900214">"Түлхүүрийн даралт харуул"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"Биет түлхүүрийн даралтын визуал санал хүсэлт харуул"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"Биет түлхүүрийн даралтын визуал хариу үйлдлийг харуул"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Гадаргын шинэчлэлтүүдийг харуулах"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Шинэчлэгдэх үед цонхны гадаргыг бүхэлд нь анивчуулах"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Шинэчлэлт харахыг харуулах"</string>
@@ -675,7 +675,7 @@
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Гарын бүдүүвчийг сонгох"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Өгөгдмөл"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Дэлгэцийг асаах"</string>
- <string name="allow_turn_screen_on" msgid="6194845766392742639">"Дэлгэцийг асаахыг зөвшөөрнө үү"</string>
+ <string name="allow_turn_screen_on" msgid="6194845766392742639">"Дэлгэцийг асаахыг зөвшөөрөх"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Аппад дэлгэцийг асаахыг зөвшөөрнө үү. Зөвшөөрсөн тохиолдолд тухайн апп таны тодорхой оролцоогүйгээр ямар ч үед дэлгэцийг асааж болно."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Таамаглах боломжтой буцаах анимаци"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Таамаглах боломжтой буцаах зангаанд системийн анимацийг идэвхжүүлнэ үү."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Энэ тохиргоо нь таамаглах боломжтой зангааны анимацид системийн анимацийг идэвхжүүлнэ. Үүнд апп бүрд тодорхойлогч файлл enableOnBackInvokedCallback-г үнэн болгож тохируулахыг шаардана."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Зүүн тийш зөөх"</item>
- <item msgid="5425394847942513942">"Доош зөөх"</item>
- <item msgid="7728484337962740316">"Баруун тийш зөөх"</item>
- <item msgid="324200556467459329">"Дээш зөөх"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Заагаагүй"</string>
<string name="neuter" msgid="2075249330106127310">"Саармаг үг"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index e5852ed726f1..30775199ed70 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"पूर्वानुमानित मागे जाण्याचे अ‍ॅनिमेशन"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"पूर्वानुमानित मागे जाण्यासाठीचे सिस्टीम अ‍ॅनिमेशन सुरू करा."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"हे सेटिंग पूर्वानुमानित जेश्चर ॲनिमेशनसाठी सिस्टीम ॲनिमेशन सुरू करते. यासाठी मॅनिफेस्ट फाइलमध्ये प्रति ॲप enableOnBackInvokedCallback सत्य वर सेट करणे आवश्यक आहे."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"डावीकडे हलवा"</item>
- <item msgid="5425394847942513942">"खाली हलवा"</item>
- <item msgid="7728484337962740316">"उजवीकडे हलवा"</item>
- <item msgid="324200556467459329">"वरती हलवा"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"नमूद केलेले नाही"</string>
<string name="neuter" msgid="2075249330106127310">"नपुसकलिंग"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index ca07d2bba3e3..24c1733d02cd 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -580,12 +580,12 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Profil terhad"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Tambah pengguna baharu?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Anda boleh berkongsi peranti ini dengan orang lain dengan membuat pengguna tambahan. Setiap pengguna mempunyai ruang mereka sendiri, yang boleh diperibadikan dengan apl, kertas dinding dan sebagainya. Pengguna juga boleh melaraskan tetapan peranti seperti Wi-Fi yang akan memberi kesan kepada semua orang.\n\nApabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemaskinikan apl untuk semua pengguna lain. Tetapan dan perkhidmatan kebolehaksesan tidak boleh dipindahkan kepada pengguna baharu."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Apabila anda menambah pengguna baharu, orang itu perlu menyediakan ruangnya sendiri.\n\nMana-mana pengguna boleh mengemaskinikan apl untuk semua pengguna lain."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Apabila anda menambahkan pengguna baharu, orang itu perlu menyediakan ruangnya sendiri.\n\nMana-mana pengguna boleh mengemaskinikan apl untuk semua pengguna lain."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Jadikan pengguna ini pentadbir?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Pentadbir mempunyai keistimewaan khas yang tiada pada pengguna lain. Pentadbir boleh mengurus semua pengguna, mengemaskinikan atau menetapkan semula peranti ini, mengubah suai tetapan, melihat semua apl yang telah dipasang dan memberikan atau membatalkan keistimewaan pentadbir untuk pengguna lain."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Jadikan pentadbir"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Sediakan pengguna sekarang?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Pastikan orang itu tersedia untuk mengambil peranti dan menyediakan ruangan"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Pastikan individu itu bersedia untuk mengambil peranti dan menyediakan ruangannya"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Sediakan profil sekarang?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Sediakan sekarang"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Bukan sekarang"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animasi kembali ramalan"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Dayakan animasi sistem untuk kembali ramalan."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Tetapan ini mendayakan animasi sistem untuk animasi gerak isyarat ramalan. Animasi sistem memerlukan tetapan enableOnBackInvokedCallback untuk setiap apl kepada benar dalam fail manifes."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Alih ke kiri"</item>
- <item msgid="5425394847942513942">"Alih ke bawah"</item>
- <item msgid="7728484337962740316">"Alih ke kanan"</item>
- <item msgid="324200556467459329">"Alih ke atas"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Tidak dinyatakan"</string>
<string name="neuter" msgid="2075249330106127310">"Neuter"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 0b9b3d1cefc0..aa9989ba3bd2 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"နောက်ခလုတ်၏ ရှေ့ပြေးလှုပ်ရှားသက်ဝင်ပုံ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"နောက်ခလုတ်ရှေ့ပြေးအတွက် စနစ်လှုပ်ရှားသက်ဝင်ပုံများကို ဖွင့်ပါသည်။"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ဤဆက်တင်သည် လက်ဟန် ရှေ့ပြေးလှုပ်ရှားသက်ဝင်ပုံအတွက် စနစ်လှုပ်ရှားသက်ဝင်ပုံများကို ဖွင့်ပါသည်။ အက်ပ်တစ်ခုစီ၏ ဆက်တင်အတွက် enableOnBackInvokedCallback ကို မန်နီးဖက်စ် (manifest) ဖိုင်၌ ဖွင့်ထားရန်လိုအပ်သည်။"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ဘယ်သို့ရွှေ့ရန်"</item>
- <item msgid="5425394847942513942">"အောက်သို့ရွှေ့ရန်"</item>
- <item msgid="7728484337962740316">"ညာသို့ရွှေ့ရန်"</item>
- <item msgid="324200556467459329">"အပေါ်သို့ရွှေ့ရန်"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"သတ်မှတ်မထားပါ"</string>
<string name="neuter" msgid="2075249330106127310">"နပုလ္လိင်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index e68a2b78394d..9126f2904620 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -448,8 +448,8 @@
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen"</string>
<string name="power_discharging_duration" msgid="1076561255466053220">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår basert på bruken din"</string>
- <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> gjenstår basert på bruken din (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen basert på bruken din"</string>
+ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen basert på bruken din (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<!-- no translation found for power_remaining_duration_only_short (7438846066602840588) -->
<skip />
<string name="power_discharge_by_enhanced" msgid="563438403581662942">"Skal vare til omtrent <xliff:g id="TIME">%1$s</xliff:g>, basert på bruken din (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Tilbake-animasjoner med forslag"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Slå på systemanimasjoner for tilbakebevegelser med forslag."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Denne innstillingen slår på systemanimasjoner for bevegelsesanimasjoner med forslag. Den krever at enableOnBackInvokedCallback settes til sann i manifestfilen for hver app."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Flytt til venstre"</item>
- <item msgid="5425394847942513942">"Flytt ned"</item>
- <item msgid="7728484337962740316">"Flytt til høyre"</item>
- <item msgid="324200556467459329">"Flytt opp"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Ikke angitt"</string>
<string name="neuter" msgid="2075249330106127310">"Intetkjønn"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index e52b880a2919..f3e2cdd45e9e 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -58,10 +58,10 @@
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' मा जडान गर्न सकिँदैन"</string>
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"पासवर्ड जाँच गरेर फेरि प्रयास गर्नुहोस्"</string>
<string name="wifi_not_in_range" msgid="1541760821805777772">"दायराभित्र छैन"</string>
- <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"स्वतः जडान हुने छैन"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"अटो कनेक्ट हुने छैन"</string>
<string name="wifi_no_internet" msgid="1774198889176926299">"इन्टरनेटमाथिको पहुँच छैन"</string>
<string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा सेभ गरियो"</string>
- <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s मार्फत् स्वतः जडान गरिएको"</string>
+ <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s मार्फत् अटो कनेक्ट गरिएको"</string>
<string name="connected_via_network_scorer_default" msgid="7973529709744526285">"नेटवर्क मूल्याङ्कनकर्ता मार्फत स्वत: जडान गरिएको"</string>
<string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> मार्फत जडान गरिएको"</string>
<string name="tap_to_sign_up" msgid="5356397741063740395">"साइन अप गर्न ट्याप गर्नुहोस्"</string>
@@ -580,12 +580,12 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबन्धित प्रोफाइल"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"नयाँ प्रयोगकर्ता हाल्ने हो?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।\n\nतपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।BREAK_0BREAK_1तपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।BREAK_2BREAK_3सबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तर पहुँचसम्बन्धी सेटिङ तथा सेवाहरू नयाँ प्रयोगकर्तामा नसर्न सक्छन्।"</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने ती प्रयोगकर्ताले आफ्नो स्पेस सेट गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"तपाईंले नयाँ प्रयोगकर्ता हाल्नुभयो भने ती प्रयोगकर्ताले आफ्नो स्पेस सेट गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"यी प्रयोगकर्तालाई एड्मिन बनाउने हो?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"एड्मिनहरूसँग अन्य प्रयोगकर्तासँग नभएका विशेषाधिकारहरू हुन्छन्। एड्मिन सबै प्रयोगकर्ताहरूलाई व्यवस्थापन गर्न, यो डिभाइस अपडेट वा रिसेट गर्न, सेटिङ परिमार्जन गर्न, इन्स्टल गरिएका सबै एपहरू हेर्न र अरूलाई एड्मिनका विशेषाधिकारहरू दिन वा अरूलाई दिइएका एड्मिनका विशेषाधिकारहरू खारेज गर्न सक्नुहुन्छ।"</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"एड्मिन बनाउनुहोस्"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"अहिले प्रयोगकर्ता सेटअप गर्ने हो?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"यी व्यक्ति यन्त्र यो डिभाइस चलाउन र आफ्नो ठाउँ सेट गर्न उपलब्ध छन् भन्ने कुरा सुनिश्चित गर्नुहोस्"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"यी व्यक्ति यो डिभाइस चलाउन र आफ्नो ठाउँ सेट गर्न उपलब्ध छन् भन्ने कुरा सुनिश्चित गर्नुहोस्"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"अहिले प्रोफाइल सेटअप गर्ने हो?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"अब सेटअप गर्नुहोस्"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"अहिले होइन"</string>
@@ -602,8 +602,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"नयाँ प्रयोगकर्ता सिर्जना गर्न सकिएन"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"नयाँ अतिथि बनाउन सकिएन"</string>
<string name="user_nickname" msgid="262624187455825083">"उपनाम"</string>
- <string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता थप्नुहोस्"</string>
- <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string>
+ <string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता कनेक्ट गर्नुहोस्"</string>
+ <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि कनेक्ट गर्नुहोस्"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"गेस्ट मोडबाट बाहिर निस्कियोस्"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"अतिथि सत्र रिसेट गर्नुहोस्"</string>
<string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"अतिथिका रूपमा ब्राउज गर्ने सेसन रिसेट गर्ने हो?"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"पूर्वानुमानयुक्त ब्याक एनिमेसनहरू"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"पूर्वानुमानयुक्त ब्याक एनिमेसनका हकमा सिस्टम एनिमेसनहरू लागू गर्नुहोस्।"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"यो सेटिङले पूर्वानुमानयुक्त जेस्चर एनिमेसनका हकमा सिस्टम एनिमेनसहरू लागू गर्छ। म्यानिफेस्ट फाइलमा हरेक एपका हकमा enableOnBackInvokedCallback सेट गरी TRUE बनाएपछि मात्र यो सेटिङ अन गर्न मिल्छ।"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"बायाँतिर सार्नुहोस्"</item>
- <item msgid="5425394847942513942">"तलतिर सार्नुहोस्"</item>
- <item msgid="7728484337962740316">"दायाँतिर सार्नुहोस्"</item>
- <item msgid="324200556467459329">"माथितिर सार्नुहोस्"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"नतोकिएको"</string>
<string name="neuter" msgid="2075249330106127310">"नपुंसक लिङ्ग"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 0d52d9d2b661..c8581994b75f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellende animaties voor gebaren voor terug"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Systeemanimaties aanzetten voor voorspellende animaties voor gebaren voor terug."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Met deze instelling zet je systeemanimaties aan voor voorspellende gebaaranimaties. Je moet enableOnBackInvokedCallback per app instellen op True in het manifestbestand."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Naar links verplaatsen"</item>
- <item msgid="5425394847942513942">"Omlaag verplaatsen"</item>
- <item msgid="7728484337962740316">"Naar rechts verplaatsen"</item>
- <item msgid="324200556467459329">"Omhoog verplaatsen"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Niet opgegeven"</string>
<string name="neuter" msgid="2075249330106127310">"Onzijdig"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index eb54cba0ae41..ec72ba9fc567 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -584,10 +584,10 @@
<string name="user_grant_admin_title" msgid="5157031020083343984">"ଏହି ୟୁଜରଙ୍କୁ ଜଣେ ଆଡମିନ କରିବେ?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"ଆଡମିନମାନଙ୍କର ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକ ଥାଏ ଯାହା ଅନ୍ୟ ୟୁଜରମାନଙ୍କର ନଥାଏ। ଜଣେ ଆଡମିନ ସମସ୍ତ ୟୁଜରଙ୍କୁ ପରିଚାଳନା କରିପାରିବେ, ଏହି ଡିଭାଇସକୁ ଅପଡେଟ କିମ୍ବା ରିସେଟ କରିପାରିବେ, ସେଟିଂସ ପରିବର୍ତ୍ତନ କରିପାରିବେ, ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସମସ୍ତ ଆପ୍ସ ଦେଖିପାରିବେ ଏବଂ ଅନ୍ୟମାନଙ୍କ ପାଇଁ ଆଡମିନଙ୍କ ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକୁ ଅନୁମତି ଦେଇପାରିବେ କିମ୍ବା ପ୍ରତ୍ୟାହାର କରିପାରିବେ।"</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"ଆଡମିନ କରନ୍ତୁ"</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ଉପଯୋଗକର୍ତ୍ତା ସେଟଅପ କରିବେ?"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍‌ ଓ ନିଜର ସ୍ଥାନ ସେଟଅପ୍‌ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ୟୁଜର ସେଟଅପ କରିବେ?"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ ଓ ନିଜର ସ୍ଥାନ ସେଟଅପ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ପ୍ରୋଫାଇଲ୍‌କୁ ଏବେ ସେଟ୍‌ କରିବେ?"</string>
- <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ଏବେ ସେଟଅପ୍ କରନ୍ତୁ"</string>
+ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ଏବେ ସେଟଅପ କରନ୍ତୁ"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"ଏବେ ନୁହେଁଁ"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"ଯୋଡନ୍ତୁ"</string>
<string name="user_new_user_name" msgid="60979820612818840">"ନୂଆ ୟୁଜର"</string>
@@ -676,7 +676,7 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"ଡିଫଲ୍ଟ"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"ସ୍କ୍ରିନକୁ ଚାଲୁ କରନ୍ତୁ"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"ସ୍କ୍ରିନକୁ ଚାଲୁ କରିବା ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"ସ୍କ୍ରିନକୁ ଚାଲୁ କରିବା ପାଇଁ ଏକ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଯଦି ଅନୁମତି ଦିଆଯାଏ, ତେବେ ଆପଟି ଆପଣଙ୍କ ସ୍ପଷ୍ଟ ଇଣ୍ଟେଣ୍ଟ ବିନା ଯେ କୌଣସି ସମୟରେ ସ୍କ୍ରିନକୁ ଚାଲୁ କରିପାରେ।"</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"ସ୍କ୍ରିନକୁ ଚାଲୁ କରିବା ପାଇଁ ଏକ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଯଦି ଅନୁମତି ଦିଆଯାଏ, ତେବେ ଆପଟି ଆପଣଙ୍କ ଏକ୍ସପ୍ଲିସିଟ ଇଣ୍ଟେଣ୍ଟ ବିନା ଯେ କୌଣସି ସମୟରେ ସ୍କ୍ରିନକୁ ଚାଲୁ କରିପାରେ।"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ପ୍ରେଡିକ୍ଟିଭ ବେକ ଆନିମେସନ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ପ୍ରେଡିକ୍ଟିଭ ବେକ ପାଇଁ ସିଷ୍ଟମ ଆନିମେସନଗୁଡ଼ିକୁ ସକ୍ଷମ କରନ୍ତୁ।"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ଏହି ସେଟିଂ ପ୍ରେଡିକ୍ଟିଭ ଜେଶ୍ଚର ଆନିମେସନ ପାଇଁ ସିଷ୍ଟମ ଆନିମେସନଗୁଡ଼ିକୁ ସକ୍ଷମ କରେ। ଏଥିପାଇଁ ମାନିଫେଷ୍ଟ ଫାଇଲରେ ପ୍ରତି-ଆପ enableOnBackInvokedCallbackକୁ \"ଠିକ\"ରେ ସେଟ କରିବା ଆବଶ୍ୟକ।"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ବାମକୁ ମୁଭ କରନ୍ତୁ"</item>
- <item msgid="5425394847942513942">"ତଳକୁ ମୁଭ କରନ୍ତୁ"</item>
- <item msgid="7728484337962740316">"ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</item>
- <item msgid="324200556467459329">"ଉପରକୁ ମୁଭ କରନ୍ତୁ"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"ନିର୍ଦ୍ଦିଷ୍ଟ କରାଯାଇନାହିଁ"</string>
<string name="neuter" msgid="2075249330106127310">"ନ୍ୟୁଟର"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index b0faa808d4ea..34194589e3a6 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ਪਿਛਲੇ ਐਨੀਮੇਸ਼ਨਾਂ ਦਾ ਪੂਰਵ-ਅਨੁਮਾਨ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ਪੂਰਵ-ਅਨੁਮਾਨ ਵਾਪਸੀ ਲਈ ਸਿਸਟਮ ਐਨੀਮੇਸ਼ਨਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ਇਹ ਸੈਟਿੰਗ ਪੂਰਵ-ਅਨੁਮਾਨ ਇਸ਼ਾਰਾ ਐਨੀਮੇਸ਼ਨ ਲਈ ਸਿਸਟਮ ਐਨੀਮੇਸ਼ਨਾਂ ਨੂੰ ਚਾਲੂ ਕਰਦੀ ਹੈ। ਮੈਨੀਫ਼ੈਸਟ ਫ਼ਾਈਲ ਵਿੱਚ enableOnBackInvokedCallback ਸੈਟਿੰਗ ਨੂੰ ਪ੍ਰਤੀ-ਐਪ \'ਸਹੀ\' \'ਤੇ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ਖੱਬੇ ਲਿਜਾਓ"</item>
- <item msgid="5425394847942513942">"ਹੇਠਾਂ ਲਿਜਾਓ"</item>
- <item msgid="7728484337962740316">"ਸੱਜੇ ਲਿਜਾਓ"</item>
- <item msgid="324200556467459329">"ਉੱਪਰ ਲਿਜਾਓ"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"ਨਿਰਧਾਰਿਤ ਨਹੀਂ"</string>
<string name="neuter" msgid="2075249330106127310">"ਨਿਰਪੱਖ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index cdc5ba26b37b..addad23c5255 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"Pokazuj dotknięcia"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Pokazuj potwierdzenie wizualne po dotknięciu"</string>
<string name="show_key_presses" msgid="6360141722735900214">"Wyświetl naciśnięcia klawiszy"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"Wyświetl opinie wizualne dla naciśnięć fizycznego klucza"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"Pokaż wizualną informację zwrotną po naciśnięciu fizycznego klawisza"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Pokazuj zmiany powierzchni"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Podświetlaj całe aktualizowane powierzchnie okien"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Pokazuj aktualizacje widoku"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacje przewidywanego przejścia wstecz"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Włącz animacje systemowe dla przewidywanego przejścia wstecz"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"To ustawienie uruchamia animacje systemowe dla przewidywanych gestów. Wymaga ustawienia w pliku manifestu wartości true w polu enableOnBackInvokedCallback dla każdej aplikacji."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Przenieś w lewo"</item>
- <item msgid="5425394847942513942">"Przenieś w dół"</item>
- <item msgid="7728484337962740316">"Przenieś w prawo"</item>
- <item msgid="324200556467459329">"Przenieś w górę"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nie określono"</string>
<string name="neuter" msgid="2075249330106127310">"Nijaki"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index f1784bcc3c58..6f3f644ccfd1 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos \"Voltar\" preditivos"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Ativar animações do sistema para gestos \"Voltar\" preditivos"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuração ativa animações do sistema para gestos preditivos. Ela requer que a política enableOnBackInvokedCallback por app seja definida como verdadeira no arquivo de manifesto."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mover para esquerda"</item>
- <item msgid="5425394847942513942">"Mover para baixo"</item>
- <item msgid="7728484337962740316">"Mover para direita"</item>
- <item msgid="324200556467459329">"Mover para cima"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Não especificado"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index c510e2b63bb3..566c5d318a5c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -382,7 +382,7 @@
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operações de clipe não retangulares"</string>
<string name="track_frame_time" msgid="522674651937771106">"Renderização HWUI do perfil"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Ativar cam. depuração GPU"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite carregamento de camadas de depuração de GPU para apps de depuração"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativ. registo do fornecedor"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclua registos adicionais de fornecedores específicos de dispositivos em relatórios de erros, que podem conter informações privadas, utilizar mais bateria e/ou utilizar mais armazenamento."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação de transição"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos para voltar preditivos"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Ative as animações do sistema para gestos para voltar preditivos."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta definição ativa animações do sistema para a animação de gestos preditivos. Requer a definição do atributo enableOnBackInvokedCallback por app como verdadeiro no ficheiro de manifesto."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mover para a esquerda"</item>
- <item msgid="5425394847942513942">"Mover para baixo"</item>
- <item msgid="7728484337962740316">"Mover para a direita"</item>
- <item msgid="324200556467459329">"Mover para cima"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Não especificado"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index f1784bcc3c58..6f3f644ccfd1 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos \"Voltar\" preditivos"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Ativar animações do sistema para gestos \"Voltar\" preditivos"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuração ativa animações do sistema para gestos preditivos. Ela requer que a política enableOnBackInvokedCallback por app seja definida como verdadeira no arquivo de manifesto."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Mover para esquerda"</item>
- <item msgid="5425394847942513942">"Mover para baixo"</item>
- <item msgid="7728484337962740316">"Mover para direita"</item>
- <item msgid="324200556467459329">"Mover para cima"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Não especificado"</string>
<string name="neuter" msgid="2075249330106127310">"Neutro"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 447bb63a18cc..77b79c9aafd7 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animații pentru gestul înapoi predictiv"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Activează animațiile de sistem pentru gestul înapoi predictiv."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Această setare activează animațiile de sistem pentru animația gesturilor predictive. Necesită setarea valorii true în cazul atributului enableOnBackInvokedCallback pentru fiecare aplicație în fișierul manifest."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Deplasează la stânga"</item>
- <item msgid="5425394847942513942">"Deplasează în jos"</item>
- <item msgid="7728484337962740316">"Deplasează la dreapta"</item>
- <item msgid="324200556467459329">"Deplasează în sus"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nespecificat"</string>
<string name="neuter" msgid="2075249330106127310">"Neutru"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index f10e8e7a144a..c368913c2a44 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Анимации подсказки для жеста \"Назад\""</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Включить системную анимацию подсказки для жеста \"Назад\"."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"С помощью этого параметра можно включить системные анимации подсказок для жестов. Для этого нужно установить значение true для enableOnBackInvokedCallback в файле манифеста приложения."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Переместите палец влево"</item>
- <item msgid="5425394847942513942">"Переместите палец вниз"</item>
- <item msgid="7728484337962740316">"Переместите палец вправо"</item>
- <item msgid="324200556467459329">"Переместите палец вверх"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Не указан"</string>
<string name="neuter" msgid="2075249330106127310">"Средний"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 51bd3c14d829..17090a75f132 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"පුරෝකථනමය පසු සජීවිකරණ"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"පුරෝකථනමය ආපසු සඳහා පද්ධති සජීවිකරණ සබල කරන්න."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"මෙම සැකසීම පුරෝකථනමය ඉංගිත සජීවිකරණය සඳහා පද්ධති සජීවිකරණ සබල කරයි. එයට මැනිෆෙස්ට් ගොනුව තුළ එක් යෙදුමකට enableOnBackInvokedCallback සත්‍ය ලෙස සැකසීම අවශ්‍ය වේ."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"වමට ගෙන යන්න"</item>
- <item msgid="5425394847942513942">"පහළට ගෙන යන්න"</item>
- <item msgid="7728484337962740316">"දකුණට ගෙන යන්න"</item>
- <item msgid="324200556467459329">"ඉහළට ගෙන යන්න"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"විශේෂයෙන් සඳහන් නොකළ"</string>
<string name="neuter" msgid="2075249330106127310">"නපුංසක"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 691872842fd5..06367677c365 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Prediktívne animácie gesta Späť"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Povoliť animácie v systéme pre prediktívne gesto Späť"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Toto nastavenie povoľuje animácie v systéme na účely prediktívnej animácie gest. Vyžaduje nastavenie povolenia enableOnBackInvokedCallback na pravdu v súbore manifestu konkrétnej aplikácie."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Posuňte doľava"</item>
- <item msgid="5425394847942513942">"Posuňte nadol"</item>
- <item msgid="7728484337962740316">"Posuňte doprava"</item>
- <item msgid="324200556467459329">"Presuňte nahor"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nešpecifikované"</string>
<string name="neuter" msgid="2075249330106127310">"Stredný rod"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index cf174e1d73f4..949ed422ea57 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacije poteze za nazaj s predvidevanjem"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogoči sistemske animacije za potezo za nazaj s predvidevanjem."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ta nastavitev omogoča sistemske animacije za animacijo poteze s predvidevanjem. V datoteki manifesta mora biti parameter »enableOnBackInvokedCallback« za posamezno aplikacijo nastavljen na »true«."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Premaknite se levo"</item>
- <item msgid="5425394847942513942">"Premaknite se navzdol"</item>
- <item msgid="7728484337962740316">"Premaknite se desno"</item>
- <item msgid="324200556467459329">"Premaknite se navzgor"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Ni določeno"</string>
<string name="neuter" msgid="2075249330106127310">"Srednji spol"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 7802704e4649..0eff3ab8dc82 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -268,7 +268,7 @@
<string name="mock_location_app_not_set" msgid="6972032787262831155">"Nuk është vendosur asnjë aplikacion që simulon vendndodhjen"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"Aplikacioni për simulimin e vendndodhjes: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"Rrjetet"</string>
- <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikimi i ekranit pa tel"</string>
+ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikimi i ekranit wireless"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Aktivizo regjistrimin Wi-Fi Verbose"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Përshpejtimi i skanimit të Wi‑Fi"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Renditje e rastësishme jo e përhershme e MAC për Wi‑Fi"</string>
@@ -300,7 +300,7 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"Emri i pritësit të ofruesit të DNS-së private"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Fut emrin e pritësit të ofruesit të DNS-së"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Nuk mund të lidhej"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Shfaq opsionet për certifikimin e ekranit pa tel"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Shfaq opsionet për certifikimin e ekranit wireless"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Zvogëlon shkarkimin e baterisë dhe përmirëson cilësinë e funksionimit të rrjetit"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Kur ky modalitet është i aktivizuar, adresa MAC e kësaj pajisjeje mund të ndryshojë çdo herë që lidhet me një rrjet që ka të aktivizuar renditjen e rastësishme të adresave MAC."</string>
@@ -356,7 +356,7 @@
<string name="show_touches" msgid="8437666942161289025">"Shfaq trokitjet"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Shfaq reagimet vizuale për trokitjet"</string>
<string name="show_key_presses" msgid="6360141722735900214">"Shfaq shtypjet e tasteve"</string>
- <string name="show_key_presses_summary" msgid="725387457373015024">"Shfaq reagime vizuale për shtypjen e tasteve fizike"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"Shfaq reagim vizual për shtypjet fizike të tasteve"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Shfaq përditësimet e sipërfaqes"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Ndriço të gjitha sipërfaqet e dritares kur ato të përditësohen"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Shfaq përditësimet e pamjes"</string>
@@ -477,7 +477,7 @@
<string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Karikim i shpejtë"</string>
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Po karikohet ngadalë"</string>
- <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Po karikohet pa tel"</string>
+ <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Po karikohet wireless"</string>
<string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Po karikohet"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Nuk po karikohet"</string>
<string name="battery_info_status_not_charging" msgid="3371084153747234837">"Lidhur, jo në karikim"</string>
@@ -584,7 +584,7 @@
<string name="user_grant_admin_title" msgid="5157031020083343984">"Të bëhet administrator ky përdorues?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorët kanë privilegje të veçanta që nuk i kanë përdoruesit e tjerë. Një administrator mund të menaxhojë të gjithë përdoruesit, të përditësojë ose të rivendosë këtë pajisje, të modifikojë cilësimet, të shikojë të gjitha aplikacionet e instaluara dhe të japë ose të revokojë privilegjet e administratorit për të tjerët."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Bëje administrator"</string>
- <string name="user_setup_dialog_title" msgid="8037342066381939995">"Të konfig. përdoruesi tani?"</string>
+ <string name="user_setup_dialog_title" msgid="8037342066381939995">"Të konfigurohet përdoruesi?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Sigurohu që personi të jetë i gatshëm të marrë pajisjen dhe të caktojë hapësirën e vet"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Të konfigurohet tani profili?"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Konfiguro tani"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Animacionet për gjestin e parashikuar të kthimit prapa"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivizo animacionet e sistemit për gjestin e parashikuar të kthimit prapa."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ky cilësim aktivizon animacionet e sistemit për animacionin e gjestit të parashikuar. Ai kërkon që enableOnBackInvokedCallback për aplikacionin të jetë caktuar si i vërtetë në skedarin e manifestit."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Lëvize majtas"</item>
- <item msgid="5425394847942513942">"Lëvize poshtë"</item>
- <item msgid="7728484337962740316">"Lëvize djathtas"</item>
- <item msgid="324200556467459329">"Lëvize lart"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"E papërcaktuar"</string>
<string name="neuter" msgid="2075249330106127310">"Asnjanëse"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index eb10b550f97b..2ae0fe2e3c10 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Упаривање омогућава приступ контактима и историји позива након повезивања."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кључа."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Није могуће комуницирати са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> је одбио/ла упаривање"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Рачунар"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Анимације за покрет повратка са предвиђањем"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Омогућите анимације система за покрет повратка са предвиђањем."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ово подешавање омогућава анимације система за покрет повратка са предвиђањем. Захтева подешавање дозволе enableOnBackInvokedCallback по апликацији на true у фајлу манифеста."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Померите налево"</item>
- <item msgid="5425394847942513942">"Померите надоле"</item>
- <item msgid="7728484337962740316">"Померите надесно"</item>
- <item msgid="324200556467459329">"Померите нагоре"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Није наведено"</string>
<string name="neuter" msgid="2075249330106127310">"Средњи род"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 256b4e9aacee..e8f045d06c2a 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Förhandsanimationer för bakåtrörelser"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivera systemanimationer som förhandsvisar bakåtrörelser."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Den här inställningen aktiverar systemanimationer som förhandsvisar vart rörelserna leder. Du måste ställa in enableOnBackInvokedCallback som sant per app i manifestfilen."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Flytta åt vänster"</item>
- <item msgid="5425394847942513942">"Flytta nedåt"</item>
- <item msgid="7728484337962740316">"Flytta åt höger"</item>
- <item msgid="324200556467459329">"Flytta uppåt"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Inte angivet"</string>
<string name="neuter" msgid="2075249330106127310">"Neutrum"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index e23dbcb314d5..64119140bb65 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Uhuishaji wa utabiri wa kurudi nyuma"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Ruhusu uhuishaji wa mfumo wa utabiri wa kurudi nyuma."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Mipangilio hii inaruhusu uhuishaji wa mfumo wa uhuishaji wa utabiri wa ishara. Inahitaji kuweka mipangilio kwa kila programu enableOnBackInvokedCallback kuwa true katika faili ya maelezo."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Sogeza kushoto"</item>
- <item msgid="5425394847942513942">"Sogeza chini"</item>
- <item msgid="7728484337962740316">"Sogeza kulia"</item>
- <item msgid="324200556467459329">"Sogeza juu"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"Asilimia <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="not_specified" msgid="5423502443185110328">"Haijabainishwa"</string>
<string name="neuter" msgid="2075249330106127310">"Isiyobainika"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 365c3dafca93..608638483190 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -355,7 +355,7 @@
<string name="pointer_location_summary" msgid="957120116989798464">"திரையின் மேல் அடுக்கானது தற்போது தொடப்பட்டிருக்கும் தரவைக் காண்பிக்கிறது"</string>
<string name="show_touches" msgid="8437666942161289025">"தட்டல்களைக் காட்டு"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"தட்டல்களின் போது காட்சி அறிகுறிகளைக் காட்டும்"</string>
- <string name="show_key_presses" msgid="6360141722735900214">"பட்டன் அழுத்தத்தை காட்டவா"</string>
+ <string name="show_key_presses" msgid="6360141722735900214">"பட்டன் அழுத்தத்தை காட்டு"</string>
<string name="show_key_presses_summary" msgid="725387457373015024">"பட்டன் அழுத்தங்களைக் காட்சி மூலம் உறுதிப்படுத்தும்"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"மேலோட்ட புதுப்பிப்புகளைக் காட்டு"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"சாளரத்தின் பரப்புநிலைகள் புதுப்பிக்கப்படும்போது, அவற்றை முழுவதுமாகக் காட்டும்"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"கணிக்கக்கூடிய பின்செல் சைகைக்கான அனிமேஷன்கள்"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"கணிக்கக்கூடிய பின்செல் சைகைக்காகச் சிஸ்டம் அனிமேஷன்களை இயக்கும்."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"கணிக்கக்கூடிய சைகைக்கான அனிமேஷனுக்காக இந்த அமைப்பு சிஸ்டம் அனிமேஷன்களை இயக்கும். மெனிஃபெஸ்ட் ஃபைலில் ஒவ்வொரு ஆப்ஸுக்கும் enableOnBackInvokedCallbackகை \'சரி\' என அமைக்க வேண்டும்."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"இடதுபுறம் நகர்த்துங்கள்"</item>
- <item msgid="5425394847942513942">"கீழே நகர்த்துங்கள்"</item>
- <item msgid="7728484337962740316">"வலதுபுறம் நகர்த்துங்கள்"</item>
- <item msgid="324200556467459329">"மேலே நகர்த்துங்கள்"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"குறிப்பிடப்படவில்லை"</string>
<string name="neuter" msgid="2075249330106127310">"அஃறிணை"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index d1c464c21378..f43b56a36acc 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -587,7 +587,7 @@
<string name="user_setup_dialog_title" msgid="8037342066381939995">"యూజర్‌ను ఇప్పుడే సెటప్ చేయాలా?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"పరికరాన్ని తీసుకోవడానికి వ్యక్తి అందుబాటులో ఉన్నారని నిర్ధారించుకొని, ఆపై వారికి స్టోరేజ్‌ స్థలాన్ని సెటప్ చేయండి"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ఇప్పుడు ప్రొఫైల్‌ను సెటప్ చేయాలా?"</string>
- <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ఇప్పుడే సెట‌ప్ చేయి"</string>
+ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ఇప్పుడే సెట‌ప్ చేయండి"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"ఇప్పుడు కాదు"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"జోడించండి"</string>
<string name="user_new_user_name" msgid="60979820612818840">"కొత్త యూజర్"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ప్రివ్యూ గల బ్యాక్ యానిమేషన్‌లు"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"ప్రివ్యూ గల బ్యాక్ యానిమేషన్‌ల కోసం సిస్టమ్ యానిమేషన్‌లను ఎనేబుల్ చేయండి."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ఊహించదగిన సంజ్ఞ యానిమేషన్ కోసం ఈ సెట్టింగ్ సిస్టమ్ యానిమేషన్‌లను ఎనేబుల్ చేస్తుంది. దీనికి మ్యానిఫెస్ట్ ఫైల్‌లో ఒక్కో యాప్‌లో enableOnBackInvokedCallback సెట్టింగ్‌ను ఒప్పునకు సెట్ చేయవలసి ఉంటుంది."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ఎడమ వైపుగా జరపండి"</item>
- <item msgid="5425394847942513942">"కిందికి జరపండి"</item>
- <item msgid="7728484337962740316">"కుడి వైపుగా జరపండి"</item>
- <item msgid="324200556467459329">"పైకి జరపండి"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"పేర్కొనబడలేదు"</string>
<string name="neuter" msgid="2075249330106127310">"తటస్థం"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index bc6840bdc2d7..c7b10fba15e2 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"ภาพเคลื่อนไหวของการย้อนกลับที่คาดการณ์ได้"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"เปิดใช้ภาพเคลื่อนไหวของระบบสำหรับการย้อนกลับที่คาดการณ์ได้"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"การตั้งค่านี้จะเปิดใช้การเคลื่อนไหวของระบบสำหรับการเคลื่อนไหวจากท่าทางสัมผัสแบบคาดเดา โดยต้องตั้งค่า enableOnBackInvokedCallback สำหรับแต่ละแอปให้เป็น \"จริง\" ในไฟล์ Manifest"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"ย้ายไปทางซ้าย"</item>
- <item msgid="5425394847942513942">"ย้ายลง"</item>
- <item msgid="7728484337962740316">"ย้ายไปทางขวา"</item>
- <item msgid="324200556467459329">"ย้ายขึ้น"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"ไม่ได้ระบุ"</string>
<string name="neuter" msgid="2075249330106127310">"ไม่มีเพศ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 4360b9fa027c..8222c426541c 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Mga animation ng predictive na pagbalik"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"I-enable ang mga animation ng system para sa predictive na pagbalik."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ine-enable ng setting na ito ang mga animation ng system para sa animation ng predictive na galaw. Kinakailangan nitong itakda sa true ang enableOnBackInvokedCallback sa bawat app sa manifest file."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Ilipat pakaliwa"</item>
- <item msgid="5425394847942513942">"Ilipat pababa"</item>
- <item msgid="7728484337962740316">"Ilipat pakanan"</item>
- <item msgid="324200556467459329">"Ilipat pataas"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Hindi tinukoy"</string>
<string name="neuter" msgid="2075249330106127310">"Walang Kasarian"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 206df8f5a8ce..991c9182ce3c 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Tahmin edilen geri gitme animasyonları"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Tahmin edilen geri gitme için sistem animasyonlarını etkinleştirin"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu ayar, tahmine dayalı hareket animasyonu için sistem animasyonlarını etkinleştirir. Her uygulamanın manifest dosyasında enableOnBackInvokedCallback\'in doğru değerine ayarlanması gerekir."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Sola taşı"</item>
- <item msgid="5425394847942513942">"Aşağı taşı"</item>
- <item msgid="7728484337962740316">"Sağa taşı"</item>
- <item msgid="324200556467459329">"Yukarı taşı"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
<string name="not_specified" msgid="5423502443185110328">"Belirtilmedi"</string>
<string name="neuter" msgid="2075249330106127310">"Cinsiyetsiz"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 2bc80df469db..1cb31853a267 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -355,7 +355,7 @@
<string name="pointer_location_summary" msgid="957120116989798464">"Показувати на екрані жести й натискання"</string>
<string name="show_touches" msgid="8437666942161289025">"Показувати дотики"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Показувати візуальну реакцію на торкання"</string>
- <string name="show_key_presses" msgid="6360141722735900214">"Показувати натиск. клавіш"</string>
+ <string name="show_key_presses" msgid="6360141722735900214">"Показувати натискання клавіш"</string>
<string name="show_key_presses_summary" msgid="725387457373015024">"Показувати візуальний відгук на натискання клавіш"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Показ. оновлення поверхні"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Підсвічувати вікна повністю під час оновлення"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Анімації з підказками для жесту \"Назад\""</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Увімкнути системну анімацію з підказками для жесту \"Назад\"."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Якщо вибрати це налаштування, для жесту \"Назад\" відображатиметься анімація з підказками. У файлі маніфесту атрибуту enableOnBackInvokedCallback додатка потрібно присвоїти значення true."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Перемістіть палець ліворуч"</item>
- <item msgid="5425394847942513942">"Перемістіть палець униз"</item>
- <item msgid="7728484337962740316">"Перемістіть палець праворуч"</item>
- <item msgid="324200556467459329">"Перемістіть палець угору"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Не вказано"</string>
<string name="neuter" msgid="2075249330106127310">"Середній рід"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index b8bef4c14fbb..7e3a164b6c1a 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"پیچھے جانے کے اشارے کی پیش گوئی والی اینیمیشنز"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"پیچھے جانے کے پیش گوئی والے اشارے کے لیے سسٹم اینیمیشنز فعال کریں۔"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏یہ ترتیب پیش گوئی والی اشارے کی اینیمیشن کے لیے سسٹم کی اینیمیشنز کو فعال کرتی ہے۔ اس کے لیے manifest فائل میں فی ایپ enableOnBackInvokedCallback کو درست پر سیٹ کرنے کی ضرورت ہے۔"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"دائيں منتقل کریں"</item>
- <item msgid="5425394847942513942">"نیچے منتقل کریں"</item>
- <item msgid="7728484337962740316">"بائيں منتقل کریں"</item>
- <item msgid="324200556467459329">"اوپر منتقل کریں"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"متعین نہیں ہے"</string>
<string name="neuter" msgid="2075249330106127310">"غیر واضح"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 57c59e1725fe..845b83554e12 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -602,7 +602,7 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yangi foydalanuvchi yaratilmadi"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yangi mehmon yaratilmadi"</string>
<string name="user_nickname" msgid="262624187455825083">"Nik"</string>
- <string name="user_add_user" msgid="7876449291500212468">"Foydalanuvchi"</string>
+ <string name="user_add_user" msgid="7876449291500212468">"Foydalanuvchi kiritish"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Mehmon seansini tiklash"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Taxminiy qaytish animatsiyalari"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Taxminiy qaytish uchun tizim animatsiyalarini yoqish."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu sozlamalar taxminiy qaytish animatsiyalari uchun tizim animatsiyalarini faollashtiradi. Buning uchun har bir ilovaning manifest faylida enableOnBackInvokedCallback parametri “true” qiymatida boʻlishi lozim."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Chapga siljitish"</item>
- <item msgid="5425394847942513942">"Pastga siljitish"</item>
- <item msgid="7728484337962740316">"Oʻngga siljitish"</item>
- <item msgid="324200556467459329">"Tepaga siljitish"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"Koʻrsatilmagan"</string>
<string name="neuter" msgid="2075249330106127310">"Oʻrta"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 9877249adca5..18090352f0a0 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -580,7 +580,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Tiểu sử bị hạn chế"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Thêm người dùng mới?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Bạn có thể chia sẻ thiết bị này với người khác bằng cách tạo thêm người dùng. Mỗi người dùng sẽ có không gian riêng của mình. Họ có thể tùy chỉnh không gian riêng đó bằng các ứng dụng, hình nền, v.v. Người dùng cũng có thể điều chỉnh các tùy chọn cài đặt thiết bị có ảnh hưởng đến tất cả mọi người, chẳng hạn như Wi‑Fi.\n\nKhi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác. Các dịch vụ và các tùy chọn cài đặt hỗ trợ tiếp cận có thể không chuyển sang người dùng mới."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Khi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Khi bạn thêm người dùng mới, người đó cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Đặt người dùng này làm quản trị viên?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Quản trị viên có các đặc quyền mà những người dùng khác không có. Một quản trị viên có thể quản lý toàn bộ người dùng, cập nhật hoặc đặt lại thiết bị này, sửa đổi chế độ cài đặt, xem tất cả các ứng dụng đã cài đặt và cấp hoặc thu hồi đặc quyền của quản trị viên đối với những người khác."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Đặt làm quản trị viên"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Ảnh xem trước thao tác quay lại"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Bật ảnh của hệ thống để xem trước thao tác quay lại"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Cài đặt này cho phép sử dụng ảnh động hệ thống cho ảnh động cử chỉ dự đoán. Nó yêu cầu cài đặt cho mỗi ứng dụng chuyển enableOnBackInvokedCallback thành lệnh true trong tệp kê khai."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Di chuyển sang trái"</item>
- <item msgid="5425394847942513942">"Di chuyển xuống"</item>
- <item msgid="7728484337962740316">"Di chuyển sang phải"</item>
- <item msgid="324200556467459329">"Di chuyển lên"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Chưa xác định"</string>
<string name="neuter" msgid="2075249330106127310">"Vô tính"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index a210e6c02250..7d027512c8ff 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -560,7 +560,7 @@
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"连接时遇到问题。请关闭并重新开启设备"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有线音频设备"</string>
<string name="help_label" msgid="3528360748637781274">"帮助和反馈"</string>
- <string name="storage_category" msgid="2287342585424631813">"存储"</string>
+ <string name="storage_category" msgid="2287342585424631813">"存储空间"</string>
<string name="shared_data_title" msgid="1017034836800864953">"共享数据"</string>
<string name="shared_data_summary" msgid="5516326713822885652">"查看和修改共享数据"</string>
<string name="shared_data_no_blobs_text" msgid="3108114670341737434">"此用户没有共享数据。"</string>
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"预见式返回动画"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"启用系统动画作为预见式返回动画。"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"此设置将启用系统动画作为预测性手势动画。这要求在清单文件中将单个应用的 enableOnBackInvokedCallback 设为 true。"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"左移"</item>
- <item msgid="5425394847942513942">"下移"</item>
- <item msgid="7728484337962740316">"右移"</item>
- <item msgid="324200556467459329">"上移"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="not_specified" msgid="5423502443185110328">"未指定"</string>
<string name="neuter" msgid="2075249330106127310">"中性"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index f78b141eb3f9..c563c86512be 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"預測返回手勢動畫"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"為預測返回手勢啟用系統動畫。"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"此設定會啟用系統動畫作為預測手勢動畫。這必須在資訊清單檔案中將個別應用程式的 enableOnBackInvokedCallback 設定為 true。"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"向左移"</item>
- <item msgid="5425394847942513942">"向下移"</item>
- <item msgid="7728484337962740316">"向右移"</item>
- <item msgid="324200556467459329">"向上移"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"未指定"</string>
<string name="neuter" msgid="2075249330106127310">"中性"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index a66a0293d25b..eb3843ea1f1a 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"預測返回操作動畫"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"為預測返回操作啟用系統動畫。"</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"這項設定會啟用系統動畫做為預測手勢動畫。這必須在資訊清單檔案中將個別應用程式的 enableOnBackInvokedCallback 設為 true。"</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"向左移"</item>
- <item msgid="5425394847942513942">"向下移"</item>
- <item msgid="7728484337962740316">"向右移"</item>
- <item msgid="324200556467459329">"向上移"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"未指定"</string>
<string name="neuter" msgid="2075249330106127310">"中性"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 45b8c543ad72..f4fd35205f1a 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -684,12 +684,6 @@
<string name="back_navigation_animation" msgid="8105467568421689484">"Ukubikezelwa kwasemuva kopopayi"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Nika amandla ukubikezela emuva kopopayi besistimu."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Leli sethingi livumela opopayi besistimu mayelana nokuthinta okubikezelwayo kopopayi. Idinga ukusetha i-app ngayinye ku-enableOnBackInvokedCallback ukuze iqinisekise ifayela le-manifest."</string>
- <string-array name="udfps_accessibility_touch_hints">
- <item msgid="1737722959616802157">"Yisa kwesokunxele"</item>
- <item msgid="5425394847942513942">"Yehlisa"</item>
- <item msgid="7728484337962740316">"Yisa kwesokudla"</item>
- <item msgid="324200556467459329">"Khuphula"</item>
- </string-array>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Akucacisiwe"</string>
<string name="neuter" msgid="2075249330106127310">"Okungenabulili"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
deleted file mode 100644
index 54d5c3d63a5d..000000000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.net;
-
-import android.app.usage.NetworkStats;
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.net.NetworkTemplate;
-import android.util.Log;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-/**
- * Loader for retrieving the network stats summary for all UIDs.
- */
-public class NetworkStatsSummaryLoader extends AsyncTaskLoader<NetworkStats> {
-
- private static final String TAG = "NetworkDetailLoader";
- private final NetworkStatsManager mNetworkStatsManager;
- private final long mStart;
- private final long mEnd;
- private final NetworkTemplate mNetworkTemplate;
-
- private NetworkStatsSummaryLoader(Builder builder) {
- super(builder.mContext);
- mStart = builder.mStart;
- mEnd = builder.mEnd;
- mNetworkTemplate = builder.mNetworkTemplate;
- mNetworkStatsManager = (NetworkStatsManager)
- builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
- }
-
- @Override
- protected void onStartLoading() {
- super.onStartLoading();
- forceLoad();
- }
-
- @Override
- public NetworkStats loadInBackground() {
- try {
- return mNetworkStatsManager.querySummary(mNetworkTemplate, mStart, mEnd);
- } catch (RuntimeException e) {
- Log.e(TAG, "Exception querying network detail.", e);
- return null;
- }
- }
-
- @Override
- protected void onStopLoading() {
- super.onStopLoading();
- cancelLoad();
- }
-
- @Override
- protected void onReset() {
- super.onReset();
- cancelLoad();
- }
-
- public static class Builder {
- private final Context mContext;
- private long mStart;
- private long mEnd;
- private NetworkTemplate mNetworkTemplate;
-
- public Builder(Context context) {
- mContext = context;
- }
-
- public Builder setStartTime(long start) {
- mStart = start;
- return this;
- }
-
- public Builder setEndTime(long end) {
- mEnd = end;
- return this;
- }
-
- /**
- * Set {@link NetworkTemplate} for builder
- */
- public Builder setNetworkTemplate(NetworkTemplate template) {
- mNetworkTemplate = template;
- return this;
- }
-
- public NetworkStatsSummaryLoader build() {
- return new NetworkStatsSummaryLoader(this);
- }
- }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java b/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java
index 6fba0a169219..77789c268f79 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java
@@ -24,5 +24,5 @@ public class UidDetail {
public CharSequence[] detailLabels;
public CharSequence[] detailContentDescriptions;
public Drawable icon;
- public CharSequence packageName;
+ public String packageName;
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index ffe28a6a5202..15620b7023e2 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -23,6 +23,7 @@
>
<!-- Standard permissions granted to the shell. -->
+ <uses-permission android:name="android.permission.CAMERA_HEADLESS_SYSTEM_USER" />
<uses-permission android:name="android.permission.MANAGE_HEALTH_PERMISSIONS" />
<uses-permission android:name="android.permission.MANAGE_HEALTH_DATA" />
<uses-permission android:name="android.permission.health.READ_EXERCISE_ROUTE" />
@@ -852,6 +853,9 @@
<!-- Permission required for accessing all content provider mime types -->
<uses-permission android:name="android.permission.GET_ANY_PROVIDER_TYPE" />
+ <!-- Permission required for CTS-in-sandbox tests -->
+ <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX" />
+
<!-- Permission required for CTS test - CtsWallpaperTestCases -->
<uses-permission android:name="android.permission.ALWAYS_UPDATE_WALLPAPER" />
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 78da5a699759..8f329b3dddd8 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -4,7 +4,6 @@ set noparent
dsandler@android.com
-aaliomer@google.com
aaronjli@google.com
achalke@google.com
acul@google.com
@@ -36,6 +35,7 @@ gallmann@google.com
gwasserman@google.com
hwwang@google.com
hyunyoungs@google.com
+ikateryna@google.com
jaggies@google.com
jamesoleary@google.com
jbolinger@google.com
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml
index 5d1f722aee0c..0480a2e2e909 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml
@@ -11,7 +11,7 @@
<string name="recent_apps_label" msgid="6583276995616385847">"ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
<string name="lockscreen_label" msgid="648347953557887087">"ಲಾಕ್ ಸ್ಕ್ರೀನ್‌"</string>
<string name="quick_settings_label" msgid="2999117381487601865">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು"</string>
- <string name="notifications_label" msgid="6829741046963013567">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳು"</string>
<string name="screenshot_label" msgid="863978141223970162">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
<string name="screenshot_utterance" msgid="1430760563401895074">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
<string name="volume_up_label" msgid="8592766918780362870">"ವಾಲ್ಯೂಮ್ ಜಾಸ್ತಿ"</string>
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index 767756e17747..17c74ba7b12f 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -263,9 +263,11 @@ internal class ExpandableControllerImpl(
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
delegate.onLaunchAnimationStart(isExpandingFullyAbove)
overlay.value = composeViewRoot.rootView.overlay as ViewGroupOverlay
+ cujType?.let { InteractionJankMonitor.getInstance().begin(composeViewRoot, it) }
}
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+ cujType?.let { InteractionJankMonitor.getInstance().end(it) }
delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
overlay.value = null
}
@@ -320,9 +322,8 @@ internal class ExpandableControllerImpl(
}
override fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder? {
- // TODO(b/252723237): Add support for jank monitoring when animating from a
- // Composable.
- return null
+ val type = cuj?.cujType ?: return null
+ return InteractionJankMonitor.Configuration.Builder.withView(type, composeViewRoot)
}
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt
index 31e7d7c7c6ba..73b366ef57bc 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt
@@ -72,15 +72,16 @@ internal class PunchHole(
}
private fun DrawScope.drawHole(bounds: Element) {
+ val boundsSize = bounds.lastSize.toSize()
if (shape == RectangleShape) {
- drawRect(Color.Black, blendMode = BlendMode.DstOut)
+ drawRect(Color.Black, size = boundsSize, blendMode = BlendMode.DstOut)
return
}
// TODO(b/290184746): Cache outline if the size of bounds does not change.
drawOutline(
shape.createOutline(
- bounds.lastSize.toSize(),
+ boundsSize,
layoutDirection,
this,
),
diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags
index 75de94321bfe..e2d889168516 100644
--- a/packages/SystemUI/proguard_common.flags
+++ b/packages/SystemUI/proguard_common.flags
@@ -1,16 +1,8 @@
-# Preserve line number information for debugging stack traces.
--keepattributes SourceFile,LineNumberTable
-
-keep class com.android.systemui.VendorServices
# the `#inject` methods are accessed via reflection to work on ContentProviders
-keepclassmembers class * extends com.android.systemui.dagger.SysUIComponent { void inject(***); }
-# Needed for builds to properly initialize KeyFrames from xml scene
--keepclassmembers class * extends androidx.constraintlayout.motion.widget.Key {
- public <init>();
-}
-
# Needed to ensure callback field references are kept in their respective
# owning classes when the downstream callback registrars only store weak refs.
# TODO(b/264686688): Handle these cases with more targeted annotations.
@@ -59,7 +51,6 @@
public <init>(android.content.Context, android.util.AttributeSet);
}
--keep class ** extends androidx.preference.PreferenceFragment
-keep class com.android.systemui.tuner.*
# The plugins and core log subpackages act as shared libraries that might be referenced in
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
new file mode 100644
index 000000000000..7abf9aebc686
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This file is needed when flag lockscreen.enable_landscape is on
+ Required for landscape lockscreen on small screens. -->
+<com.android.keyguard.KeyguardPasswordView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/keyguard_password_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ android:layout_gravity="center_horizontal|bottom"
+ android:gravity="bottom">
+
+ <!-- Layout here is visually identical to the previous keyguard_password_view.
+ I.E., 'constraints here effectively the same as the previous linear layout' -->
+ <androidx.constraintlayout.motion.widget.MotionLayout
+ android:id="@+id/password_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layoutDirection="ltr"
+ android:orientation="vertical"
+ androidprv:layoutDescription="@xml/keyguard_password_scene">
+
+ <!-- Guideline need to align password right of centre,
+ when on small screen landscape layout -->
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/password_center_guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ androidprv:layout_constraintGuide_percent="0.5" />
+
+ <LinearLayout
+ android:id="@+id/keyguard_bouncer_message_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layoutDirection="ltr"
+ android:orientation="vertical"
+ androidprv:layout_constraintTop_toTopOf="parent">
+
+ <include layout="@layout/keyguard_bouncer_message_area" />
+
+ <com.android.systemui.bouncer.ui.BouncerMessageView
+ android:id="@+id/bouncer_message_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/passwordEntry_container"
+ android:layout_width="280dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:theme="?attr/passwordStyle"
+ androidprv:layout_constraintBottom_toTopOf="@+id/keyguard_selector_fade_container"
+ androidprv:layout_constraintEnd_toEndOf="parent"
+ androidprv:layout_constraintHorizontal_bias="0.5"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintTop_toBottomOf="@+id/keyguard_bouncer_message_container"
+ androidprv:layout_constraintVertical_bias="0.7777">
+
+ <EditText
+ android:id="@+id/passwordEntry"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/keyguard_accessibility_password"
+ android:gravity="center_horizontal"
+ android:imeOptions="flagForceAscii|actionDone"
+ android:inputType="textPassword"
+ android:maxLength="500"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textCursorDrawable="@null"
+ android:textSize="16sp"
+ android:textStyle="normal" />
+
+ <ImageView
+ android:id="@+id/switch_ime_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|center_vertical"
+ android:layout_marginBottom="12dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_ime_switch_button"
+ android:padding="8dip"
+ android:src="@drawable/ic_lockscreen_ime"
+ android:tint="?android:attr/textColorPrimary"
+ android:visibility="gone" />
+ </FrameLayout>
+
+ <include
+ android:id="@+id/keyguard_selector_fade_container"
+ layout="@layout/keyguard_eca"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:orientation="vertical"
+ androidprv:layout_constraintBottom_toBottomOf="parent" />
+
+ </androidx.constraintlayout.motion.widget.MotionLayout>
+
+</com.android.keyguard.KeyguardPasswordView> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml
new file mode 100644
index 000000000000..b562d7b5ee48
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_motion_layout.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This file is needed when flag lockscreen.enable_landscape is on
+ Required for landscape lockscreen on small screens. -->
+<com.android.keyguard.KeyguardPatternView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/keyguard_pattern_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal|bottom"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+
+ <!-- Layout here is visually identical to the previous keyguard_pattern_view.
+ I.E., 'constraints here effectively the same as the previous linear layout' -->
+ <androidx.constraintlayout.motion.widget.MotionLayout
+ android:id="@+id/pattern_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layoutDirection="ltr"
+ android:orientation="vertical"
+ android:maxWidth = "@dimen/biometric_auth_pattern_view_max_size"
+ androidprv:layoutDescription="@xml/keyguard_pattern_scene">
+
+ <!-- Guideline need to align pattern right of centre,
+ when on small screen landscape layout -->
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/pattern_center_guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ androidprv:layout_constraintGuide_percent="0.5" />
+
+ <LinearLayout
+ android:id="@+id/keyguard_bouncer_message_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layoutDirection="ltr"
+ android:orientation="vertical"
+ androidprv:layout_constraintTop_toTopOf="parent">
+
+ <include layout="@layout/keyguard_bouncer_message_area" />
+
+ <com.android.systemui.bouncer.ui.BouncerMessageView
+ android:id="@+id/bouncer_message_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+
+ </LinearLayout>
+
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/pattern_top_guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ androidprv:layout_constraintGuide_percent="0" />
+
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPatternView"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginBottom="8dp"
+ androidprv:layout_constraintVertical_bias="1.0"
+ androidprv:layout_constraintDimensionRatio="1.0"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintBottom_toTopOf="@+id/keyguard_selector_fade_container"
+ androidprv:layout_constraintEnd_toEndOf="parent"
+ androidprv:layout_constraintVertical_chainStyle="packed"
+ androidprv:layout_constraintTop_toBottomOf="@id/pattern_top_guideline"/>
+
+ <include
+ android:id="@+id/keyguard_selector_fade_container"
+ layout="@layout/keyguard_eca"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/keyguard_eca_bottom_margin"
+ android:layout_marginTop="@dimen/keyguard_eca_top_margin"
+ android:orientation="vertical"
+ androidprv:layout_constraintBottom_toBottomOf="parent"
+ androidprv:layout_constraintTop_toBottomOf="@+id/lockPatternView" />
+
+ </androidx.constraintlayout.motion.widget.MotionLayout>
+
+</com.android.keyguard.KeyguardPatternView> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 84f7bb5b08a8..ce53b7ed3a98 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -28,7 +28,7 @@
<string name="keyguard_enter_password" msgid="6483623792371009758">"Fut fjalëkalimin"</string>
<string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Karta e pavlefshme."</string>
<string name="keyguard_charged" msgid="5478247181205188995">"I karikuar"</string>
- <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me valë"</string>
+ <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet në mënyrë wireless"</string>
<string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet"</string>
<string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me shpejtësi"</string>
@@ -41,7 +41,7 @@
<string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Shto një kartë SIM."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"Karta SIM mungon ose është e palexueshme. Shto një kartë SIM."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Kartë SIM e papërdorshme."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Karta jote SIM është çaktivizuar përgjithmonë.\n Kontakto me ofruesin e shërbimit me valë për një kartë tjetër SIM."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Karta jote SIM është çaktivizuar përgjithmonë.\n Kontakto me ofruesin e shërbimit wireless për një tjetër kartë SIM."</string>
<string name="keyguard_sim_locked_message" msgid="7095293254587575270">"Karta SIM është e kyçur."</string>
<string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"Karta SIM është e kyçur me PUK."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"Karta SIM po shkyçet…"</string>
diff --git a/packages/SystemUI/res-keyguard/xml/keyguard_password_scene.xml b/packages/SystemUI/res-keyguard/xml/keyguard_password_scene.xml
new file mode 100644
index 000000000000..092e10d25c00
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/xml/keyguard_password_scene.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<MotionScene
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:motion="http://schemas.android.com/apk/res-auto"
+ xmlns:androidprv="http://schemas.android.com/apk/res-auto">
+
+ <Transition
+ motion:constraintSetStart="@id/single_constraints"
+ motion:constraintSetEnd="@+id/split_constraints"
+ motion:duration="0"
+ motion:autoTransition="none" />
+
+ <!-- No changes to default layout -->
+ <ConstraintSet android:id="@+id/single_constraints" />
+
+ <ConstraintSet android:id="@+id/split_constraints">
+
+ <Constraint
+ android:id="@+id/keyguard_bouncer_message_container"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ androidprv:layout_constraintEnd_toStartOf="@+id/password_center_guideline"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintTop_toTopOf="parent"
+ androidprv:layout_constraintBottom_toTopOf="@+id/keyguard_selector_fade_container"
+ androidprv:layout_constraintVertical_chainStyle="spread_inside" />
+ <Constraint
+ android:id="@+id/passwordEntry_container"
+ android:layout_width="280dp"
+ android:layout_height="wrap_content"
+ androidprv:layout_constraintVertical_bias="0.5"
+ androidprv:layout_constraintHorizontal_bias="0.5"
+ androidprv:layout_constraintEnd_toEndOf="parent"
+ androidprv:layout_constraintStart_toStartOf="@+id/password_center_guideline"
+ androidprv:layout_constraintBottom_toBottomOf="parent"
+ androidprv:layout_constraintTop_toTopOf="parent"/>
+ <Constraint
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/keyguard_eca_top_margin"
+ android:layout_marginBottom="@dimen/keyguard_eca_bottom_margin"
+ androidprv:layout_constraintBottom_toBottomOf="parent"
+ androidprv:layout_constraintEnd_toStartOf="@+id/password_center_guideline"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintTop_toBottomOf="@+id/keyguard_bouncer_message_container" />
+
+ </ConstraintSet>
+</MotionScene> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml b/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml
new file mode 100644
index 000000000000..6112411402c4
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<MotionScene
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:motion="http://schemas.android.com/apk/res-auto"
+ xmlns:androidprv="http://schemas.android.com/apk/res-auto">
+
+ <Transition
+ motion:constraintSetStart="@id/single_constraints"
+ motion:constraintSetEnd="@+id/split_constraints"
+ motion:duration="0"
+ motion:autoTransition="none"/>
+
+ <!-- No changes to default layout -->
+ <ConstraintSet android:id="@+id/single_constraints"/>
+
+ <ConstraintSet android:id="@+id/split_constraints">
+
+ <Constraint
+ android:id="@+id/keyguard_bouncer_message_container"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ androidprv:layout_constraintEnd_toStartOf="@+id/pattern_center_guideline"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintTop_toTopOf="parent" />
+ <Constraint
+ android:id="@+id/lockPatternView"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ androidprv:layout_constraintDimensionRatio="1.0"
+ androidprv:layout_constraintVertical_bias="0.5"
+ androidprv:layout_constraintBottom_toBottomOf="parent"
+ androidprv:layout_constraintEnd_toEndOf="parent"
+ androidprv:layout_constraintStart_toStartOf="@+id/pattern_center_guideline"
+ androidprv:layout_constraintTop_toTopOf="parent"
+ android:layout_marginBottom="0dp" />
+ <Constraint
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ androidprv:layout_constraintBottom_toBottomOf="parent"
+ androidprv:layout_constraintEnd_toStartOf="@+id/pattern_center_guideline"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ android:layout_marginBottom="@dimen/keyguard_eca_bottom_margin"
+ android:layout_marginTop="@dimen/keyguard_eca_top_margin" />
+
+ </ConstraintSet>
+</MotionScene> \ No newline at end of file
diff --git a/packages/SystemUI/res-product/values-sq/strings.xml b/packages/SystemUI/res-product/values-sq/strings.xml
index 619f22fe3978..f7421c1a2801 100644
--- a/packages/SystemUI/res-product/values-sq/strings.xml
+++ b/packages/SystemUI/res-product/values-sq/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"Drejtvendose përsëri telefonin për karikim më të shpejtë"</string>
- <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Drejtvendose përsëri telefonin për ta karikuar me valë"</string>
+ <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"Drejtvendose përsëri telefonin për karikim wireless"</string>
<string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Pajisja Android TV së shpejti do të fiket. Shtyp një buton për ta mbajtur të ndezur."</string>
<string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"Pajisja së shpejti do të fiket. Shtype për ta mbajtur të ndezur."</string>
<string name="keyguard_missing_sim_message" product="tablet" msgid="408124574073032188">"Nuk ka kartë SIM në tablet."</string>
diff --git a/packages/SystemUI/res/layout/battery_percentage_view.xml b/packages/SystemUI/res/layout/battery_percentage_view.xml
index 82facd0d7217..8b5aeaac424a 100644
--- a/packages/SystemUI/res/layout/battery_percentage_view.xml
+++ b/packages/SystemUI/res/layout/battery_percentage_view.xml
@@ -27,4 +27,5 @@
android:gravity="center_vertical|start"
android:paddingStart="@dimen/battery_level_padding_start"
android:importantForAccessibility="no"
+ android:includeFontPadding="false"
/>
diff --git a/packages/SystemUI/res/layout/battery_status_chip.xml b/packages/SystemUI/res/layout/battery_status_chip.xml
index ff68ac0f9a71..74371839e247 100644
--- a/packages/SystemUI/res/layout/battery_status_chip.xml
+++ b/packages/SystemUI/res/layout/battery_status_chip.xml
@@ -25,7 +25,8 @@
<LinearLayout
android:id="@+id/rounded_container"
android:layout_width="wrap_content"
- android:layout_height="@dimen/ongoing_appops_chip_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/ongoing_appops_chip_height"
android:layout_gravity="center"
android:background="@drawable/statusbar_chip_bg"
android:clipToOutline="true"
@@ -36,7 +37,7 @@
<com.android.systemui.battery.BatteryMeterView
android:id="@+id/battery_meter_view"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index 3a15ae4f17ff..60a78d6346f1 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -118,34 +118,37 @@ frame when animating QS <-> QQS transition
app:layout_constraintStart_toEndOf="@id/date"
app:layout_constraintTop_toTopOf="@id/clock" />
- <LinearLayout
+ <FrameLayout
android:id="@+id/shade_header_system_icons"
android:layout_width="wrap_content"
android:layout_height="@dimen/shade_header_system_icons_height"
- android:clickable="true"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:paddingStart="@dimen/shade_header_system_icons_padding_start"
- android:paddingEnd="@dimen/shade_header_system_icons_padding_end"
- android:paddingTop="@dimen/shade_header_system_icons_padding_top"
- android:paddingBottom="@dimen/shade_header_system_icons_padding_bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/privacy_container"
app:layout_constraintTop_toTopOf="@id/clock">
-
- <com.android.systemui.statusbar.phone.StatusIconContainer
- android:id="@+id/statusIcons"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:paddingEnd="@dimen/signal_cluster_battery_padding" />
-
- <com.android.systemui.battery.BatteryMeterView
- android:id="@+id/batteryRemainingIcon"
+ <LinearLayout
+ android:id="@+id/hover_system_icons_container"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:textAppearance="@style/TextAppearance.QS.Status" />
- </LinearLayout>
+ android:layout_height="match_parent"
+ android:layout_gravity="right|center_vertical"
+ android:paddingStart="@dimen/hover_system_icons_container_padding_start"
+ android:paddingEnd="@dimen/hover_system_icons_container_padding_end"
+ android:paddingTop="@dimen/hover_system_icons_container_padding_top"
+ android:paddingBottom="@dimen/hover_system_icons_container_padding_bottom">
+
+ <com.android.systemui.statusbar.phone.StatusIconContainer
+ android:id="@+id/statusIcons"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:paddingEnd="@dimen/signal_cluster_battery_padding" />
+
+ <com.android.systemui.battery.BatteryMeterView
+ android:id="@+id/batteryRemainingIcon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:textAppearance="@style/TextAppearance.QS.Status" />
+ </LinearLayout>
+ </FrameLayout>
<FrameLayout
android:id="@+id/privacy_container"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 59fcf0ea366c..5a70b79cb176 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -79,6 +79,7 @@
android:id="@+id/status_bar_start_side_except_heads_up"
android:layout_height="wrap_content"
android:layout_width="match_parent"
+ android:layout_gravity="center_vertical|start"
android:clipChildren="false">
<ViewStub
android:id="@+id/operator_name_stub"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 206a7eeda5c1..27db1c95d2f4 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Skuif af"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Beweeg links"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Beweeg regs"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Vergrotingwisselaar"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Vergroot die hele skerm"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Vergroot \'n deel van die skerm"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent-aandag is aan"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stel versteknotasapp in Instellings"</string>
<string name="install_app" msgid="5066668100199613936">"Installeer app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Sinkroniseer wedersyds na eksterne skerm?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Aktiveer skerm"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoon en kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Onlangse appgebruik"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Sien onlangse toegang"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 09157f8a7b6d..a68ec1513356 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ወደ ታች ውሰድ"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ወደ ግራ ውሰድ"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ወደ ቀኝ ውሰድ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"የማጉላት ማብሪያ/ማጥፊያ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገፅ እይታን ያጉሉ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"የማያ ገጹን ክፍል አጉላ"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"የረዳት ትኩረት በርቷል"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"በቅንብሮች ውስጥ ነባሪ የማስታወሻዎች መተግበሪያን ያቀናብሩ"</string>
<string name="install_app" msgid="5066668100199613936">"መተግበሪያን ጫን"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ወደ ውጫዊ ማሳያ ይንጸባረቅ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ማሳያን አንቃ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ማይክሮፎን እና ካሜራ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"የቅርብ ጊዜ የመተግበሪያ አጠቃቀም"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"የቅርብ ጊዜ መዳረሻን አሳይ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 31b7cbe31cc2..42e60c50d95d 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"نقل للأسفل"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"نقل لليسار"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"نقل لليمين"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"مفتاح تبديل وضع التكبير"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"تكبير الشاشة كلها"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"تكبير جزء من الشاشة"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"‏ميزة لفت انتباه \"مساعد Google\" مفعّلة."</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"يمكنك ضبط تطبيق تدوين الملاحظات التلقائي في \"الإعدادات\"."</string>
<string name="install_app" msgid="5066668100199613936">"تثبيت التطبيق"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"هل تريد بث محتوى جهازك على الشاشة الخارجية؟"</string>
+ <string name="enable_display" msgid="8308309634883321977">"تفعيل العرض"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"الميكروفون والكاميرا"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"آخر استخدام في التطبيقات"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"عرض آخر استخدام في التطبيقات"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 732d19d09283..7026e0c4d754 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"তললৈ নিয়ক"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"বাওঁফাললৈ নিয়ক"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"সোঁফাললৈ নিয়ক"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"বিবৰ্ধনৰ ছুইচ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"পূৰ্ণ স্ক্ৰীন বিবৰ্ধন কৰক"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্ৰীনৰ কিছু অংশ বিবৰ্ধন কৰক"</string>
@@ -1132,7 +1140,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ক আটাইবোৰ ডিভাইচৰ লগ এক্সেছ কৰাৰ অনুমতি প্ৰদান কৰিবনে?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"কেৱল এবাৰ এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"অনুমতি নিদিব"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপ্‌সমূহে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এই লগসমূহ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমান লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি দিয়ক। \n\nআপুনি যদি এই এপ্‌টোক আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তথাপিও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব। আপোনাৰ ডিভাইচৰ নিৰ্মাতাই তথাপিও হয়তো আপোনাৰ ডিভাইচটোত থকা কিছু লগ অথবা তথ্য এক্সেছ কৰিব পাৰিব।"</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপ্‌সমূহে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এই লগসমূহ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমানৰ লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি দিয়ক। \n\nআপুনি যদি এই এপ্‌টোক আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তথাপিও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব। আপোনাৰ ডিভাইচৰ নিৰ্মাতাই তথাপিও হয়তো আপোনাৰ ডিভাইচটোত থকা কিছু লগ অথবা তথ্য এক্সেছ কৰিব পাৰিব।"</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"অধিক জানক"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>ত অধিক জানক"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistantএ আপোনাৰ কথা শুনি আছে"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ছেটিঙত টোকাৰ ডিফ’ল্ট এপ্ ছেট কৰক"</string>
<string name="install_app" msgid="5066668100199613936">"এপ্‌টো ইনষ্টল কৰক"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"বাহ্যিক ডিছপ্লে’লৈ মিৰ’ৰ কৰিবনে?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ডিছপ্লে’ সক্ষম কৰক"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"মাইক্ৰ’ফ’ন আৰু কেমেৰা"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"শেহতীয়া এপৰ ব্যৱহাৰ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"শেহতীয়া এক্সেছ চাওক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 080f450432fc..68a8b87865b7 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Aşağı köçürün"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Sola köçürün"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Sağa köçürün"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Böyütmə dəyişdiricisi"</string>
<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>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent aktivdir"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlarda defolt qeydlər tətbiqi ayarlayın"</string>
<string name="install_app" msgid="5066668100199613936">"Tətbiqi quraşdırın"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Xarici displeyə əks etdirilsin?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Displeyi aktivləşdirin"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon və kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Son tətbiq istifadəsi"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Son girişə baxın"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index b524c343548f..37aa8231a77d 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Pomerite nadole"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Pomerite nalevo"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Pomerite nadesno"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prelazak na drugi režim uvećanja"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Pomoćnik je u aktivnom stanju"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Podesite podrazumevanu aplikaciju za beleške u Podešavanjima"</string>
<string name="install_app" msgid="5066668100199613936">"Instaliraj aplikaciju"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Želite li da preslikate na spoljnji ekran?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Omogući ekran"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavno koristila aplikacija"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Prikaži nedavni pristup"</string>
@@ -1186,10 +1192,10 @@
<string name="privacy_dialog_manage_permissions" msgid="2543451567190470413">"Upravljaj pristupom"</string>
<string name="privacy_dialog_active_call_usage" msgid="7858746847946397562">"Koristi telefonski poziv"</string>
<string name="privacy_dialog_recent_call_usage" msgid="1214810644978167344">"Nedavno korišćeno u telefonskom pozivu"</string>
- <string name="privacy_dialog_active_app_usage" msgid="631997836335929880">"Koristi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="privacy_dialog_active_app_usage" msgid="631997836335929880">"Koriste <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="privacy_dialog_recent_app_usage" msgid="4883417856848222450">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="privacy_dialog_active_app_usage_1" msgid="9047570143069220911">"Koristi <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string>
+ <string name="privacy_dialog_active_app_usage_1" msgid="9047570143069220911">"Koriste <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string>
- <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
+ <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koriste <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index dd8199edb123..69fce40145ea 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Перамясціць ніжэй"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Перамясціць улева"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Перамясціць управа"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Пераключальнік павелічэння"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Павялічыць увесь экран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Павялічыць частку экрана"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Памочнік гатовы выконваць каманды"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайце ў Наладах стандартную праграму для нататак"</string>
<string name="install_app" msgid="5066668100199613936">"Усталяваць праграму"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Адлюстраваць на знешнім дысплеі?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Уключыць дысплэй"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Мікрафон і камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Нядаўна выкарыстоўваліся праграмамі"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Паглядзець нядаўні доступ"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 896756dc9b37..3c0dd63762d5 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Преместване надолу"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Преместване наляво"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Преместване надясно"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Превключване на увеличението"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличаване на целия екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличаване на част от екрана"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Функцията за активиране на Асистент е включена"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартно приложение за бележки от настройките"</string>
<string name="install_app" msgid="5066668100199613936">"Инсталиране на приложението"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Да се дублира ли на външния екран?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Активиране на екрана"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Скорошно използване на приложението"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Вижте скорошния достъп"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 5c1b445fc1d9..0975b987d06a 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"নিচে নামান"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"বাঁদিকে সরান"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ডানদিকে সরান"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"বড় করে দেখার সুইচ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"সম্পূর্ণ স্ক্রিন বড় করে দেখা"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্রিনের কিছুটা অংশ বড় করুন"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"অ্যাসিস্ট্যান্ট আপনার কথা শোনার জন্য চালু করা আছে"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"\'সেটিংস\' থেকে ডিফল্ট নোট নেওয়ার অ্যাপ সেট করুন"</string>
<string name="install_app" msgid="5066668100199613936">"অ্যাপ ইনস্টল করুন"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"এক্সটার্নাল ডিসপ্লে আয়না?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ডিসপ্লে চালু করুন"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"মাইক্রোফোন ও ক্যামেরা"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"সম্প্রতি ব্যবহার করা অ্যাপ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"সাম্প্রতিক অ্যাক্সেস দেখুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 63f62f173ec5..021ba8aba8c3 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Pomjeranje prema dolje"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Pomjeranje lijevo"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Pomjeranje desno"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prekidač za uvećavanje"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećavanje prikaza preko cijelog ekrana"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećavanje dijela ekrana"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Pažnja Asistenta je uključena"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u Postavkama"</string>
<string name="install_app" msgid="5066668100199613936">"Instaliraj aplikaciju"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Preslikati na vanjski ekran?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Omogući ekran"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavno korištenje aplikacije"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Prikaži nedavni pristup"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index f54a0acca100..ab2c25bc8262 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mou cap avall"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mou cap a l\'esquerra"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mou cap a la dreta"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Canvia al mode d\'ampliació"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Amplia la pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplia una part de la pantalla"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"L\'Assistent està activat"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defineix l\'aplicació de notes predeterminada a Configuració"</string>
<string name="install_app" msgid="5066668100199613936">"Instal·la l\'aplicació"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vols replicar-ho a la pantalla externa?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Activa la pantalla"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micròfon i càmera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Ús recent de l\'aplicació"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Mostra l\'accés recent"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 1bfe1f4ecdad..9bde3bb1eadd 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -112,7 +112,7 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"Začít"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Nahrávání obrazovky"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Nahrávání obrazovky a zvuku"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"Zobrazovat klepnutí na obrazovku"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"Zobrazovat klepnutí na displej"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"Zastavit"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky se uložila"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Přesunout dolů"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Přesunout doleva"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Přesunout doprava"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Přepínač zvětšení"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zvětšit celou obrazovku"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zvětšit část obrazovky"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Pozornost Asistenta je zapnutá"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Výchozí aplikaci pro poznámky nastavíte v Nastavení"</string>
<string name="install_app" msgid="5066668100199613936">"Nainstalovat aplikaci"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Zrcadlit na externí displej?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Aktivovat displej"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon a fotoaparát"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedávné použití aplikacemi"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobrazit nedávný přístup"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 17853e7228d3..94ab18922558 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -174,12 +174,12 @@
<string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Konfigurer"</string>
<string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Ikke nu"</string>
<string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Dette er påkrævet for at forbedre sikkerheden og ydeevnen"</string>
- <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Konfigurer oplåsning med fingeraftryk igen"</string>
- <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Oplåsning med fingeraftryk"</string>
- <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Konfigurer oplåsning med fingeraftryk"</string>
- <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Hvis du vil konfigurere oplåsning med fingeraftryk igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere oplåsning med fingeraftryk igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string>
- <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Hvis du vil konfigurere oplåsning med fingeraftryk igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere oplåsning med fingeraftryk igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string>
- <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Oplåsning med fingeraftryk kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string>
+ <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Konfigurer fingeroplåsning igen"</string>
+ <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Fingeroplåsning"</string>
+ <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Konfigurer fingeroplåsning"</string>
+ <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Hvis du vil konfigurere fingeroplåsning igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere fingeroplåsning igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string>
+ <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Hvis du vil konfigurere fingeroplåsning igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere fingeroplåsning igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string>
+ <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Fingeroplåsning kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string>
<string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Konfigurer ansigtsoplåsning igen"</string>
<string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Ansigtsoplåsning"</string>
<string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Konfigurer ansigtsoplåsning"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Flyt ned"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Flyt til venstre"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Flyt til højre"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Skift forstørrelsestilstand"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstør hele skærmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstør en del af skærmen"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent lytter"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Angiv standardapp til noter i Indstillinger"</string>
<string name="install_app" msgid="5066668100199613936">"Installer app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vil du spejle til ekstern skærm?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Aktivér skærm"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon og kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Seneste brug af apps"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se seneste adgang"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 822ab277ba85..4ae8f27d1339 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Nach unten bewegen"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Nach links bewegen"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Nach rechts bewegen"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Vergrößerungsschalter"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ganzen Bildschirm vergrößern"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Teil des Bildschirms vergrößern"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant-Aktivierung an"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standard-Notizen-App in den Einstellungen einrichten"</string>
<string name="install_app" msgid="5066668100199613936">"App installieren"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Auf externen Bildschirm spiegeln?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Anzeige aktivieren"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon &amp; Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Kürzliche App-Nutzung"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Kürzliche Zugriffe ansehen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c33b7534198c..b279abfa0423 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Μετακίνηση κάτω"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Μετακίνηση αριστερά"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Μετακίνηση δεξιά"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Εναλλαγή μεγιστοποίησης"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Μεγέθυνση πλήρους οθόνης"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Μεγέθυνση μέρους της οθόνης"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Ο Βοηθός βρίσκεται σε αναμονή"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ορίστε την προεπιλεγμένη εφαρμογή σημειώσεων στις Ρυθμίσεις"</string>
<string name="install_app" msgid="5066668100199613936">"Εγκατάσταση εφαρμογής"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Κατοπτρισμός σε εξωτερική οθόνη;"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Ενεργοποίηση οθόνης"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Μικρόφωνο και Κάμερα"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Πρόσφατη χρήση εφαρμογής"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Εμφάνιση πρόσφατης πρόσβασης"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 901459dea907..e036eb739358 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 01aa63784bbd..060bb99480b5 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -863,6 +863,10 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
+ <string name="accessibility_control_increase_window_width" msgid="6992249470832493283">"Increase width of magnifier"</string>
+ <string name="accessibility_control_decrease_window_width" msgid="5740401560105929681">"Decrease width of magnifier"</string>
+ <string name="accessibility_control_increase_window_height" msgid="2200966116612324260">"Increase height of magnifier"</string>
+ <string name="accessibility_control_decrease_window_height" msgid="2054479949445332761">"Decrease height of magnifier"</string>
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 901459dea907..e036eb739358 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 901459dea907..e036eb739358 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Move down"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Move left"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Move right"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Magnification switch"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index c496aeea9325..936bbeb795b1 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -863,6 +863,10 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎Move down‎‏‎‎‏‎"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎Move left‎‏‎‎‏‎"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎Move right‎‏‎‎‏‎"</string>
+ <string name="accessibility_control_increase_window_width" msgid="6992249470832493283">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎Increase width of magnifier‎‏‎‎‏‎"</string>
+ <string name="accessibility_control_decrease_window_width" msgid="5740401560105929681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‏‎Decrease width of magnifier‎‏‎‎‏‎"</string>
+ <string name="accessibility_control_increase_window_height" msgid="2200966116612324260">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎Increase height of magnifier‎‏‎‎‏‎"</string>
+ <string name="accessibility_control_decrease_window_height" msgid="2054479949445332761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎Decrease height of magnifier‎‏‎‎‏‎"</string>
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎Magnification switch‎‏‎‎‏‎"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎Magnify full screen‎‏‎‎‏‎"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎Magnify part of screen‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3653839f5a00..15b3001bee25 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover hacia abajo"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover hacia la izquierda"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover hacia la derecha"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Interruptor de ampliación"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistente está prestando atención"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la app de notas predeterminada en Configuración"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"¿Quieres duplicar a la pantalla externa?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Habilitar pantalla"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono y cámara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso reciente en apps"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver accesos recientes"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 0680821c1729..fa435363b02f 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover hacia abajo"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover hacia la izquierda"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover hacia la derecha"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Botón para cambiar el modo de ampliación"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"El Asistente está activado"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la aplicación de notas predeterminada en Ajustes"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar aplicación"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"¿Replicar en pantalla externa?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Habilitar pantalla"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono y cámara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso reciente en aplicaciones"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acceso reciente"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 988d4d745494..ad80a590f06e 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Teisalda alla"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Teisalda vasakule"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Teisalda paremale"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Suurenduse lüliti"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Täisekraani suurendamine"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekraanikuva osa suurendamine"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent on aktiveeritud"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Määrake seadetes märkmete vaikerakendus."</string>
<string name="install_app" msgid="5066668100199613936">"Installi rakendus"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Kas peegeldada välisekraanile?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Luba ekraan"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon ja kaamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Rakenduste hiljutine kasutamine"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Kuva hiljutine juurdepääs"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 71cb074dc599..b417c10c4063 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Eraman behera"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Eraman ezkerrera"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Eraman eskuinera"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Lupa aplikatzeko botoia"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Handitu pantaila osoa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Handitu pantailaren zati bat"</string>
@@ -1080,7 +1088,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Oraingoz ez da automatikoki konektatuko wifira"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ikusi guztiak"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Sarea aldatzeko, deskonektatu Etherneta"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Gailuaren funtzionamendua hobetzeko, aplikazioek eta zerbitzuek wifi-sareak bilatzen jarraituko dute, baita wifi-konexioa desaktibatuta dagoenean ere. Aukera hori aldatzeko, joan wifi-sareen bilaketaren ezarpenetara. "<annotation id="link">"Aldatu"</annotation></string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Gailuaren funtzionamendua hobetzeko, aplikazioek eta zerbitzuek wifi-sareak bilatzen jarraituko dute, baita wifi-konexioa desaktibatuta dagoenean ere. Aukera hori aldatzeko, joan wifi-sareak bilatzeko eginbidearen ezarpenetara. "<annotation id="link">"Aldatu"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Desaktibatu hegaldi modua"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak lauza hau gehitu nahi du Ezarpen bizkorrak menuan:"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Gehitu lauza"</string>
@@ -1132,7 +1140,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Gailuko erregistro guztiak erabiltzeko baimena eman nahi diozu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioari?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Eman behin erabiltzeko baimena"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ez eman baimenik"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak erabiltzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak erabiltzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak atzitu ahalko ditu. Gainera, baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk atzitu ahal izatea."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak erabiltzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak erabiltzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak erabili ahalko ditu. Gainera, baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk erabili ahal izatea."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lortu informazio gehiago"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lortu informazio gehiago <xliff:g id="URL">%s</xliff:g> helbidean"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Laguntzailea zerbitzuak arreta jarrita dauka"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ezarri oharren aplikazio lehenetsia ezarpenetan"</string>
<string name="install_app" msgid="5066668100199613936">"Instalatu aplikazioa"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Kanpoko pantailan islatu nahi duzu?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Gaitu pantaila"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonoa eta kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azken erabilera"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ikusi azkenaldiko sarbidea"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 8902103c4399..1135816ff494 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"انتقال به پایین"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"انتقال به راست"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"انتقال به چپ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"کلید درشت‌نمایی"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"درشت‌نمایی تمام‌صفحه"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"درشت‌نمایی بخشی از صفحه"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"توجه «دستیار» روشن است"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"برنامه پیش‌فرض یادداشت را در «تنظیمات» تنظیم کنید"</string>
<string name="install_app" msgid="5066668100199613936">"نصب برنامه"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"در نمایشگر خارجی پخش شود؟"</string>
+ <string name="enable_display" msgid="8308309634883321977">"فعال کردن نمایشگر"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"میکروفون و دوربین"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"استفاده اخیر از برنامه"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"دیدن دسترسی اخیر"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 7e2ab650f037..eef5a47e0fe4 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Siirrä alas"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Siirrä vasemmalle"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Siirrä oikealle"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Suurennusvalinta"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Koko näytön suurennus"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Suurenna osa näytöstä"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant on aktiivinen"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Aseta oletusmuistiinpanosovellus Asetuksista"</string>
<string name="install_app" msgid="5066668100199613936">"Asenna sovellus"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Peilataanko ulkoiselle näytölle?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Ota näyttö käyttöön"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoni ja kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Sovellusten viimeaikainen käyttö"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Katso viimeaikainen käyttö"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index a863623df8d1..f4f41055b9bd 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Déplacer vers le bas"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Déplacer vers la gauche"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Déplacer vers la droite"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Commutateur d\'agrandissement"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir la totalité de l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant à l\'écoute"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'application de prise de notes par défaut dans les Paramètres"</string>
<string name="install_app" msgid="5066668100199613936">"Installer l\'application"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Dupliquer l\'écran sur un moniteur externe?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Activer l\'écran"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone et appareil photo"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applications"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Afficher l\'accès récent"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a3920de7bf9e..81a8363dba60 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Déplacer vers le bas"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Déplacer vers la gauche"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Déplacer vers la droite"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Changer de mode d\'agrandissement"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir tout l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant à l\'écoute"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir une appli de notes par défaut dans les paramètres"</string>
<string name="install_app" msgid="5066668100199613936">"Installer l\'appli"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirroring sur écran externe ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Activer l\'écran"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micro et caméra"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applis"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consulter les accès récents"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 344c0d4191f6..509de37e262b 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover cara abaixo"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover cara á esquerda"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover cara á dereita"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Interruptor do modo de ampliación"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplía parte da pantalla"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"A atención do Asistente está activada"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Establece a aplicación de notas predeterminada en Configuración"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar aplicación"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Queres proxectar contido nunha pantalla externa?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Activar pantalla"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono e cámara"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente por parte de aplicacións"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acceso recente"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index a32c78fce8bb..55fa871a75c3 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"નીચે ખસેડો"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ડાબી બાજુ ખસેડો"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"જમણી બાજુ ખસેડો"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"મોટું કરવાની સુવિધાવાળી સ્વિચ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"પૂર્ણ સ્ક્રીનને મોટી કરો"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant સક્રિય છે"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"સેટિંગમાં નોંધની ડિફૉલ્ટ ઍપ સેટ કરો"</string>
<string name="install_app" msgid="5066668100199613936">"ઍપ ઇન્સ્ટૉલ કરો"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"શું બાહ્ય ડિસ્પ્લે પર મિરર કરીએ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ડિસ્પ્લે ચાલુ કરો"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"માઇક્રોફોન અને કૅમેરા"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"તાજેતરનો ઍપનો વપરાશ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"તાજેતરનો ઍક્સેસ મેનેજ કરો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index c73b8f79c873..173c6073d9ae 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -299,7 +299,7 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"वर्क ऐप्लिकेशन"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"रोकी गई"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"नाइट लाइट"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"शाम को चालू की जाएगी"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"शाम को चालू होगी"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"सुबह तक चालू रहेगी"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g> पर चालू की जाएगी"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> तक"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"नीचे ले जाएं"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"बाईं ओर ले जाएं"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"दाईं ओर ले जाएं"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ज़ूम करने की सुविधा वाला स्विच"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फ़ुल स्क्रीन को ज़ूम करें"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीन के किसी हिस्से को ज़ूम करें"</string>
@@ -905,8 +913,8 @@
<string name="controls_providers_title" msgid="6879775889857085056">"कंट्रोल जोड़ने के लिए ऐप्लिकेशन चुनें"</string>
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string>
- <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ना है?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> यह चुन सकता है कि इस पैनल पर कौनसे कंट्रोल और कॉन्टेंट दिखे."</string>
+ <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ऐप्लिकेशन को जोड़ना है?"</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> ऐप्लिकेशन यह चुन सकता है कि इस पैनल पर कौनसे कंट्रोल और कॉन्टेंट दिखे."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> के लिए कंट्रोल हटाने हैं?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1129,7 +1137,7 @@
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
- <string name="log_access_confirmation_title" msgid="4843557604739943395">"क्या <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> को डिवाइस लॉग का ऐक्सेस देना है?"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> को डिवाइस लॉग ऐक्सेस करने की अनुमति देनी है?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"एक बार ऐक्सेस करने की अनुमति दें"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमति न दें"</string>
<string name="log_access_confirmation_body" msgid="6883031912003112634">"डिवाइस लॉग में आपके डिवाइस पर की गई कार्रवाइयां रिकॉर्ड होती हैं. ऐप्लिकेशन, इन लॉग का इस्तेमाल गड़बड़ियां ढूंढने और उन्हें ठीक करने के लिए कर सकते हैं.\n\nकुछ लॉग में संवेदनशील जानकारी हो सकती है. इसलिए, सिर्फ़ भरोसेमंद ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस दें. \n\nअगर इस ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस नहीं दिया जाता है, तब भी यह डिवाइस पर मौजूद अपने लॉग ऐक्सेस कर सकता है. डिवाइस को बनाने वाली कंपनी फिर भी डिवाइस के कुछ लॉग या जानकारी ऐक्सेस कर सकती है."</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant आपकी बातें सुन रही है"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग में जाकर, नोट लेने की सुविधा देने वाले ऐप्लिकेशन को डिफ़ॉल्ट के तौर पर सेट करें"</string>
<string name="install_app" msgid="5066668100199613936">"ऐप्लिकेशन इंस्टॉल करें"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"बाहरी डिसप्ले को अन्य डिवाइस पर दिखाना है?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"डिसप्ले चालू करें"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफ़ोन और कैमरा"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"हाल ही में इस्तेमाल करने वाला ऐप्लिकेशन"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"हाल में ऐक्सेस करने वाले ऐप"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index f9b220ddb9f1..42acd4855e76 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Premjesti dolje"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Premjesti ulijevo"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Premjesti udesno"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prebacivanje povećavanja"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povećajte cijeli zaslon"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povećaj dio zaslona"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Pažnja Asistenta je aktivirana"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u postavkama"</string>
<string name="install_app" msgid="5066668100199613936">"Instalacija"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Želite li zrcaliti na vanjski zaslon?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Omogući zaslon"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavna upotreba aplikacije"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Pogledajte nedavni pristup"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0d40770bb939..e27733f02c29 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mozgatás lefelé"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mozgatás balra"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mozgatás jobbra"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Nagyításváltó"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"A teljes képernyő felnagyítása"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Képernyő bizonyos részének nagyítása"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"A Segéd figyel"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Állítson be alapértelmezett jegyzetkészítő alkalmazást a Beállításokban"</string>
<string name="install_app" msgid="5066668100199613936">"Alkalmazás telepítése"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Tükrözi a kijelzőt a külső képernyőre?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Képernyő engedélyezése"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon és kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Legutóbbi alkalmazáshasználat"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Legutóbbi hozzáférés"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index e64a8de3b638..d2a5d751b5ab 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -399,7 +399,7 @@
<string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ավելացնելով նոր օգտատեր՝ դուք դուրս կգաք հյուրի ռեժիմից։ Հյուրի ընթացիկ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն։"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Սահմանաչափը սպառված է"</string>
<string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Հնարավոր է ստեղծել միայն մեկ օգտատեր։}one{Կարող եք առավելագույնը # օգտատեր ավելացնել։}other{Կարող եք առավելագույնը # օգտատեր ավելացնել։}}"</string>
- <string name="user_remove_user_title" msgid="9124124694835811874">"Հեռացնե՞լ օգտատիրոջը:"</string>
+ <string name="user_remove_user_title" msgid="9124124694835811874">"Հեռացնե՞լ օգտատիրոջը"</string>
<string name="user_remove_user_message" msgid="6702834122128031833">"Այս օգտատիրոջ բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"Հեռացնել"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Սկսե՞լ տեսագրումը կամ հեռարձակումը <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածով"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Տեղափոխել ներքև"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Տեղափոխել ձախ"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Տեղափոխել աջ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Խոշորացման փոփոխություն"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Խոշորացնել ամբողջ էկրանը"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Խոշորացնել էկրանի որոշակի հատվածը"</string>
@@ -1130,7 +1138,7 @@
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Հասանելի դարձնե՞լ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> հավելվածին սարքի բոլոր մատյանները"</string>
- <string name="log_access_confirmation_allow" msgid="752147861593202968">"Թույլատրել մեկանգամյա մուտքը"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Թույլատրել մեկանգամյա մուտք"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Չթույլատրել"</string>
<string name="log_access_confirmation_body" msgid="6883031912003112634">"Այն, ինչ տեղի է ունենում ձեր սարքում, գրանցվում է սարքի մատյաններում։ Հավելվածները կարող են դրանք օգտագործել անսարքությունները հայտնաբերելու և վերացնելու նպատակով։\n\nՔանի որ որոշ մատյաններ անձնական տեղեկություններ են պարունակում, խորհուրդ ենք տալիս հասանելի դարձնել ձեր սարքի բոլոր մատյանները միայն այն հավելվածներին, որոնց վստահում եք։ \n\nԵթե այս հավելվածին նման թույլտվություն չեք տվել, դրան նախկինի պես հասանելի կլինեն իր մատյանները։ Հնարավոր է՝ ձեր սարքի արտադրողին ևս հասանելի լինեն սարքի որոշ մատյաններ և տեղեկություններ։"</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Իմանալ ավելին"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Օգնականը լսում է"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Կարգավորեք նշումների կանխադրված հավելված Կարգավորումներում"</string>
<string name="install_app" msgid="5066668100199613936">"Տեղադրել հավելվածը"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Հայելապատճենե՞լ արտաքին էկրանին"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Միացնել էկրանը"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Խոսափող և տեսախցիկ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Հավելվածի վերջին օգտագործումը"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Տեսնել վերջին օգտագործումը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d2a974784026..f908c33533a9 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Pindahkan ke bawah"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Pindahkan ke kiri"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Pindahkan ke kanan"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Tombol pembesaran"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Memperbesar tampilan layar penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Perbesar sebagian layar"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Asisten sedang memerhatikan"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setel aplikasi catatan default di Setelan"</string>
<string name="install_app" msgid="5066668100199613936">"Instal aplikasi"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Cerminkan ke layar eksternal?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Aktifkan layar"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon &amp; Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Penggunaan aplikasi baru-baru ini"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Lihat akses terbaru"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index d5bb28a87afd..1fb1304daf7f 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Færa niður"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Færa til vinstri"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Færa til hægri"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Stækkunarrofi"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Stækka allan skjáinn"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Stækka hluta skjásins"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Hjálparinn er að hlusta"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stilltu sjálfgefið glósuforrit í stillingunum"</string>
<string name="install_app" msgid="5066668100199613936">"Setja upp forrit"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Spegla yfir á ytri skjá?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Virkja skjá"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Hljóðnemi og myndavél"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nýlega notað af forriti"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Sjá nýlegan aðgang"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 9f6228d549b7..bab86e37654d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -174,17 +174,17 @@
<string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Configura"</string>
<string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Non ora"</string>
<string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"L\'operazione è necessaria per migliorare la sicurezza e le prestazioni"</string>
- <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Riconfigura lo sblocco con l\'impronta"</string>
- <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Sblocco con l\'impronta"</string>
- <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Configura lo sblocco con l\'impronta"</string>
- <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Per riconfigurare lo sblocco con l\'impronta, i modelli e le immagini dell\'impronta correnti verranno eliminati.\n\nDopo la cancellazione, dovrai riconfigurare la funzionalità per usare l\'impronta per sbloccare il telefono o verificare la tua identità."</string>
- <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Per riconfigurare lo sblocco con l\'impronta, il modello e le immagini dell\'impronta correnti verranno eliminati.\n\nDopo la cancellazione, dovrai riconfigurare la funzionalità per usare l\'impronta per sbloccare il telefono o verificare la tua identità."</string>
- <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Impossibile configurare lo sblocco con l\'impronta. Vai alle Impostazioni e riprova."</string>
- <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Riconfigura lo sblocco con il volto"</string>
- <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Sblocco con il volto"</string>
- <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Configura lo sblocco con il volto"</string>
- <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Per riconfigurare lo sblocco con il volto, l\'attuale modello del volto verrà eliminato.\n\nDovrai riconfigurare questa funzionalità per usare il volto per sbloccare il telefono."</string>
- <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Impossibile configurare lo sblocco con il volto. Vai alle Impostazioni e riprova."</string>
+ <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Riconfigura lo Sblocco con l\'Impronta"</string>
+ <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Sblocco con l\'Impronta"</string>
+ <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Configura lo Sblocco con l\'Impronta"</string>
+ <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Per riconfigurare lo Sblocco con l\'Impronta, i modelli e le immagini dell\'impronta correnti verranno eliminati.\n\nDopo la cancellazione, dovrai riconfigurare la funzionalità per usare l\'impronta per sbloccare il telefono o verificare la tua identità."</string>
+ <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Per riconfigurare lo Sblocco con l\'Impronta, il modello e le immagini dell\'impronta correnti verranno eliminati.\n\nDopo la cancellazione, dovrai riconfigurare la funzionalità per usare l\'impronta per sbloccare il telefono o verificare la tua identità."</string>
+ <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Impossibile configurare lo Sblocco con l\'Impronta. Vai alle Impostazioni e riprova."</string>
+ <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Riconfigura lo Sblocco con il Volto"</string>
+ <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Sblocco con il Volto"</string>
+ <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Configura lo Sblocco con il Volto"</string>
+ <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Per riconfigurare lo Sblocco con il Volto, l\'attuale modello del volto verrà eliminato.\n\nDovrai riconfigurare questa funzionalità per usare il volto per sbloccare il telefono."</string>
+ <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Impossibile configurare lo Sblocco con il Volto. Vai alle Impostazioni e riprova."</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tocca il sensore di impronte"</string>
<string name="fingerprint_dialog_authenticated_confirmation" msgid="1603899612957562862">"Premi l\'icona Sblocca per continuare"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Impossibile riconoscere il volto. Usa l\'impronta."</string>
@@ -192,7 +192,7 @@
<skip />
<string name="keyguard_face_failed" msgid="9044619102286917151">"Volto non riconosciuto"</string>
<string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Usa l\'impronta"</string>
- <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Sblocco con il volto non disponibile"</string>
+ <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Sblocco con il Volto non disponibile"</string>
<string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth collegato."</string>
<string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentuale della batteria sconosciuta."</string>
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connesso a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
@@ -256,7 +256,7 @@
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Geolocalizzazione"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Salvaschermo"</string>
- <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accesso alla fotocamera"</string>
+ <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accesso alla videocamera"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Accesso al microfono"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponibile"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloccato"</string>
@@ -367,7 +367,7 @@
<string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Sbloccato con il volto"</string>
<string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Volto riconosciuto"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string>
- <string name="accesssibility_keyguard_retry" msgid="8880238862712870676">"Scorri verso l\'alto per riprovare lo sblocco con il volto"</string>
+ <string name="accesssibility_keyguard_retry" msgid="8880238862712870676">"Scorri verso l\'alto per riprovare lo Sblocco con il Volto"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Sposta giù"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Sposta a sinistra"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Sposta a destra"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Opzione Ingrandimento"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ingrandisci l\'intero schermo"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ingrandisci parte dello schermo"</string>
@@ -1086,7 +1094,7 @@
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Aggiungi riquadro"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Non aggiungerlo"</string>
<string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Seleziona utente"</string>
- <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{C\'è # app attiva}many{Ci sono # app attive}other{Ci sono # app attive}}"</string>
+ <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app è attiva}many{# di app sono attive}other{# app sono attive}}"</string>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuove informazioni"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"App attive"</string>
<string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Queste app sono attive e in esecuzione, anche quando non le utilizzi. Questo migliora la loro funzionalità, ma influisce sulla durata della batteria."</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"L\'assistente è attivo"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Imposta l\'app per le note predefinita nelle Impostazioni"</string>
<string name="install_app" msgid="5066668100199613936">"Installa app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vuoi eseguire il mirroring al display esterno?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Attiva display"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfono e fotocamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente da app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Vedi accesso recente"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 44ad4452e808..294f77f78e73 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"הזזה למטה"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"הזזה שמאלה"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"הזזה ימינה"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"מעבר למצב הגדלה"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"הגדלה של המסך המלא"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"הגדלת חלק מהמסך"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"‏Assistant מאזינה"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"צריך להגדיר את אפליקציית ברירת המחדל לפתקים ב\'הגדרות\'"</string>
<string name="install_app" msgid="5066668100199613936">"התקנת האפליקציה"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"לשקף למסך חיצוני?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"הפעלת המסך"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"מיקרופון ומצלמה"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"נעשה שימוש לאחרונה באפליקציות"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"צפייה בהרשאות הגישה האחרונות"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 5bd77fc5df48..9daaabcf7352 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"下に移動"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"左に移動"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"右に移動"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"拡大スイッチ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"画面全体を拡大します"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"画面の一部を拡大します"</string>
@@ -906,7 +914,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# 件のコントロールを追加しました。}other{# 件のコントロールを追加しました。}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"削除済み"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> を追加しますか?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> はここに表示されるコントロールとコンテンツを選択できます。"</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"ここに表示されるコントロールとコンテンツを <xliff:g id="APPNAME">%s</xliff:g> が選択できるようになります。"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> のコントロールを削除しますか?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"お気に入りに追加済み"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"お気に入りに追加済み、位置: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"アシスタントは起動済みです"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"[設定] でデフォルトのメモアプリを設定してください"</string>
<string name="install_app" msgid="5066668100199613936">"アプリをインストール"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"外部ディスプレイにミラーリングしますか?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ディスプレイを有効にする"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"マイクとカメラ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"最近のアプリの使用状況"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"最近のアクセスを表示"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index e0aa8ca955c7..4d3f4c739fe1 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ქვემოთ გადატანა"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"მარცხნივ გადატანა"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"მარჯვნივ გადატანა"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"გადიდების გადართვა"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"გაადიდეთ სრულ ეკრანზე"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ეკრანის ნაწილის გადიდება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 917383bc4979..0e54c222f332 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Төмен қарай жылжыту"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Солға жылжыту"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Оңға жылжыту"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Ұлғайту режиміне ауыстырғыш"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толық экранды ұлғайту"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экранның бөлігін ұлғайту"</string>
@@ -927,7 +935,7 @@
<string name="controls_favorite_load_none" msgid="7687593026725357775">"Үйлесімді басқару элементтері қолжетімді емес."</string>
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Басқа"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"Құрылғы басқару элементтеріне қосу"</string>
- <string name="controls_dialog_ok" msgid="2770230012857881822">"Енгізу"</string>
+ <string name="controls_dialog_ok" msgid="2770230012857881822">"Қосу"</string>
<string name="controls_dialog_remove" msgid="3775288002711561936">"Жою"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ұсынған"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Құрылғы құлыпталды."</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant қосулы."</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден әдепкі жазба қолданбасын орнатыңыз."</string>
<string name="install_app" msgid="5066668100199613936">"Қолданбаны орнату"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Сыртқы экран арқылы да көрсету керек пе?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Дисплейді қосу"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон және камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Соңғы рет қолданбаның датчикті пайдалануы"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Соңғы рет пайдаланғандар"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 92c2c1b35c73..564af36ec4e2 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ផ្លាស់ទី​ចុះ​ក្រោម"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ផ្លាស់ទី​ទៅ​ឆ្វេង"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ផ្លាស់ទីទៅ​ស្តាំ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ប៊ូតុងបិទបើកការ​ពង្រីក"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ពង្រីក​ពេញអេក្រង់"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ពង្រីក​ផ្នែកនៃ​អេក្រង់"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"ភាពប្រុងប្រៀប​របស់ Google Assistant ត្រូវបានបើក"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"កំណត់កម្មវិធីកំណត់ចំណាំលំនាំដើមនៅក្នុងការកំណត់"</string>
<string name="install_app" msgid="5066668100199613936">"ដំឡើង​កម្មវិធី"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"បញ្ចាំងទៅ​ឧបករណ៍បញ្ចាំង​ខាងក្រៅឬ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"បើក​ឧបករណ៍បញ្ចាំង"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"មីក្រូហ្វូន និងកាមេរ៉ា"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ការប្រើប្រាស់កម្មវិធីថ្មីៗនេះ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"មើលការចូលប្រើនាពេលថ្មីៗនេះ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 6c0f833b563b..65162130470b 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -232,7 +232,7 @@
<string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"ಮೊಬೈಲ್ ಡೇಟಾವನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"ಡೇಟಾ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="data_usage_disabled_dialog" msgid="7933201635215099780">"ಡೇಟಾ ಬಳಕೆಯು ನೀವು ಹೊಂದಿಸಿರುವ ಮಿತಿಯನ್ನು ತಲುಪಿದೆ. ಹೀಗಾಗಿ ನೀವು ಈಗ ಮೊಬೈಲ್ ಡೇಟಾ ಬಳಸುತ್ತಿಲ್ಲ.\n\nನೀವು ಮುಂದುವರಿದರೆ, ಡೇಟಾ ಬಳಕೆಗೆ ಶುಲ್ಕ ತೆರಬೇಕಾಗಬಹುದು."</string>
- <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"ಮುಂದುವರಿಸು"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"ಮುಂದುವರಿಸಿ"</string>
<string name="accessibility_location_active" msgid="2845747916764660369">"ಸ್ಥಳ ವಿನಂತಿಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
<string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ಸೆನ್ಸರ್‌ಗಳು ಆಫ್ ಆಗಿವೆ"</string>
<string name="accessibility_clear_all" msgid="970525598287244592">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
@@ -504,7 +504,7 @@
<string name="screen_pinning_description_gestural" msgid="7246323931831232068">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಮೇಲೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಅನ್‌ಪಿನ್ ಮಾಡಲು ಹೋಲ್ಡ್ ಮಾಡಿ."</string>
<string name="screen_pinning_description_accessible" msgid="7386449191953535332">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅವಲೋಕನವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ."</string>
<string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್‌ಪಿನ್ ಮಾಡಲು ಮುಖಪುಟವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿಹಿಡಿಯಿರಿ."</string>
- <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"ವೈಯಕ್ತಿಕ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು (ಉದಾ, ಸಂಪರ್ಕಗಳು ಮತ್ತು ಇಮೇಲ್ ವಿಷಯ)."</string>
+ <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"ವೈಯಕ್ತಿಕ ಡೇಟಾವನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಬಹುದು(ಉದಾ, ಸಂಪರ್ಕಗಳು ಮತ್ತು ಇಮೇಲ್ ಕಂಟೆಂಟ್‍)."</string>
<string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"ಪಿನ್ ಮಾಡಲಾದ ಆ್ಯಪ್ ಇತರ ಆ್ಯಪ್‌ಗಳನ್ನು ತೆರೆಯಬಹುದು."</string>
<string name="screen_pinning_toast" msgid="8177286912533744328">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನ್‌‌ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಸಮಗ್ರ ನೋಟ ಬಟನ್‌ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ &amp; ಒತ್ತಿಹಿಡಿಯಿರಿ"</string>
<string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಮುಖಪುಟ ಬಟನ್‌ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ &amp; ಒತ್ತಿಹಿಡಿಯಿರಿ"</string>
@@ -651,7 +651,7 @@
<string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"ಮುಖಪುಟ"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"ಇತ್ತೀಚಿನವುಗಳು"</string>
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"ಹಿಂದೆ"</string>
- <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳು"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"ಕೀಬೋರ್ಡ್‌ ಲೇಔಟ್‌ ಬದಲಾಯಿಸಿ"</string>
<string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ಪಠ್ಯ ತೆರವುಗೊಳಿಸಿ"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ಕೆಳಗೆ ಸರಿಸಿ"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ಝೂಮ್ ಮಾಡುವ ಸ್ವಿಚ್"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ಹಿಗ್ಗಿಸಿ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ಸ್ಕ್ರೀನ್‌ನ ಅರ್ಧಭಾಗವನ್ನು ಝೂಮ್ ಮಾಡಿ"</string>
@@ -1129,7 +1137,7 @@
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ಅಪರಿಚಿತ"</string>
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
- <string name="log_access_confirmation_title" msgid="4843557604739943395">"ಎಲ್ಲಾ ಸಾಧನದ ಲಾಗ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="log_access_confirmation_title" msgid="4843557604739943395">"ಎಲ್ಲಾ ಸಾಧನದ ಲಾಗ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"ಒಂದು ಬಾರಿಯ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"ಅನುಮತಿಸಬೇಡಿ"</string>
<string name="log_access_confirmation_body" msgid="6883031912003112634">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸಾಧನದ ಲಾಗ್‌ಗಳು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತವೆ. ಸಮಸ್ಯೆಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಮತ್ತು ಪರಿಹರಿಸಲು ಆ್ಯಪ್‌ಗಳು ಈ ಲಾಗ್ ಅನ್ನು ಬಳಸಬಹುದು.\n\nಕೆಲವು ಲಾಗ್‌ಗಳು ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು, ಆದ್ದರಿಂದ ನಿಮ್ಮ ವಿಶ್ವಾಸಾರ್ಹ ಆ್ಯಪ್‌ಗಳಿಗೆ ಮಾತ್ರ ಸಾಧನದ ಎಲ್ಲಾ ಲಾಗ್‌ಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ. \n\nಎಲ್ಲಾ ಸಾಧನ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನೀವು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸದಿದ್ದರೆ, ಅದು ಆಗಲೂ ತನ್ನದೇ ಆದ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ನಿಮ್ಮ ಸಾಧನ ತಯಾರಕರಿಗೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕೆಲವು ಲಾಗ್‌ಗಳು ಅಥವಾ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು ಈಗಲೂ ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ನಿಮ್ಮ ಮಾತನ್ನು ಆಲಿಸುತ್ತಿದೆ"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಡೀಫಾಲ್ಟ್ ಟಿಪ್ಪಣಿಗಳ ಆ್ಯಪ್ ಅನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="install_app" msgid="5066668100199613936">"ಆ್ಯಪ್ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ಬಾಹ್ಯ ಡಿಸ್‌ಪ್ಲೇಗೆ ಪ್ರತಿಬಿಂಬಿಸಬೇಕೆ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ಡಿಸ್‌ಪ್ಲೇ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಕ್ಯಾಮರಾ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್ ಬಳಕೆ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ಇತ್ತೀಚಿನ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ನೋಡಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 491c4e47073f..62d6bd61216c 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"아래로 이동"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"왼쪽으로 이동"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"오른쪽으로 이동"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"확대 전환"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"전체 화면 확대"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"화면 일부 확대"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"어시스턴트가 대기 중임"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"설정에서 기본 메모 앱 설정"</string>
<string name="install_app" msgid="5066668100199613936">"앱 설치"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"외부 디스플레이로 미러링하시겠습니까?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"디스플레이 사용 설정"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"마이크 및 카메라"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"최근 앱 사용"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"최근 액세스 보기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 77e4e9c7c844..2eddca253a25 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Төмөн жылдыруу"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Солго жылдыруу"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Оңго жылдыруу"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Чоңойтуу режимине которулуу"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толук экранда ачуу"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экрандын бир бөлүгүн чоңойтуу"</string>
@@ -906,7 +914,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# көзөмөл кошулду.}other{# көзөмөл кошулду.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> кошулсунбу?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> бул жерде көрсөтүлө турган башкаруу элементтерин жана контентти тандай алат."</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> бул жерде көрүнө турган нерселерди тандайт."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> башкаруу элементтери өчүрүлсүнбү?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Сүйүктүүлөргө <xliff:g id="NUMBER">%d</xliff:g>-позицияга кошулду"</string>
@@ -1132,7 +1140,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> колдонмосуна түзмөктөгү бардык таржымалдарды жеткиликтүү кыласызбы?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Бир жолу жеткиликтүү кылуу"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Тыюу салуу"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Түзмөктө аткарылган бардык аракеттер түзмөктүн таржымалдарында сакталып калат. Колдонмолор бул таржымалдарды колдонуп, маселелерди оңдошот.\n\nАйрым таржымалдарда купуя маалымат болушу мүмкүн, андыктан ишенимдүү колдонмолорго гана түзмөктөгү бардык таржымалдарды пайдаланууга уруксат бериңиз. \n\nЭгер бул колдонмого түзмөктөгү бардык таржымалдарга кирүүгө тыюу салсаңыз, ал өзүнүн таржымалдарын пайдалана берет. Түзмөктү өндүрүүчү түзмөгүңүздөгү айрым таржымалдарды же маалыматты көрө берет."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Түзмөктө жасалган аракеттердин баары таржымалдарда сакталат. Колдонмолор алардын жардамы менен мүмкүн болгон мүчүлүштүктөрдү таап, оңдоп турат.\n\nАйрым таржымалдарда купуя маалымат камтылышы мүмкүн болгондуктан, түзмөктөгү бардык таржымалдарды ишенимдүү колдонмолорго гана жеткиликтүү кылыңыз. \n\nЭгер бул колдонмого түзмөктөгү айрым таржымалдарды гана жеткиликтүү кылсаңыз, ал мурункудай эле өзүнүн таржымалдарын көрө берет. Түзмөгүңүздөгү айрым таржымалдар же нерселер анын өндүрүүчүсүнө көрүнүшү мүмкүн."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Кеңири маалымат"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Кеңири маалымат: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ачуу"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Жардамчы иштетилди"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден демейки кыска жазуулар колдонмосун тууралаңыз"</string>
<string name="install_app" msgid="5066668100199613936">"Колдонмону орнотуу"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Тышкы экранга чыгарасызбы?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Экранды иштетүү"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон жана камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Жакында колдонмолордо иштетилген"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Акыркы пайдалануусун көрүү"</string>
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
index d800d49634d2..85fb3ac577bc 100644
--- a/packages/SystemUI/res/values-land/config.xml
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -42,4 +42,8 @@
<!-- Whether we use large screen shade header which takes only one row compared to QS header -->
<bool name="config_use_large_screen_shade_header">true</bool>
+ <!-- Whether to force split shade.
+ For now, this value has effect only when flag lockscreen.enable_landscape is enabled.
+ TODO (b/293290851) - change this comment/resource when flag is enabled -->
+ <bool name="force_config_use_split_notification_shade">true</bool>
</resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 0667cd8b12d6..259b9adf0209 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -88,4 +88,7 @@
overlaid -->
<dimen name="global_actions_button_size">72dp</dimen>
<dimen name="global_actions_button_padding">26dp</dimen>
+
+ <dimen name="keyguard_indication_margin_bottom">8dp</dimen>
+ <dimen name="lock_icon_margin_bottom">24dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index ec1744168592..3f3cc27b4a32 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ຍ້າຍລົງ"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ຍ້າຍໄປຊ້າຍ"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ຍ້າຍໄປຂວາ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ສະຫຼັບການຂະຫຍາຍ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ຂະຫຍາຍເຕັມຈໍ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍ"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"ການເອີ້ນໃຊ້ຜູ້ຊ່ວຍເປີດຢູ່"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ຕັ້ງຄ່າແອັບຈົດບັນທຶກເລີ່ມຕົ້ນໃນການຕັ້ງຄ່າ"</string>
<string name="install_app" msgid="5066668100199613936">"ຕິດຕັ້ງແອັບ"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ສາຍໃສ່ຈໍສະແດງຜົນພາຍນອກບໍ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ເປີດການນຳໃຊ້ຈໍສະແດງຜົນ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ໄມໂຄຣໂຟນ ແລະ ກ້ອງຖ່າຍຮູບ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ການໃຊ້ແອັບຫຼ້າສຸດ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ເບິ່ງສິດເຂົ້າເຖິງຫຼ້າສຸດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index e418e1828bfa..808c732c49c8 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Perkelti žemyn"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Perkelti kairėn"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Perkelti dešinėn"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Didinimo jungiklis"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Viso ekrano didinimas"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Didinti ekrano dalį"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Padėjėjas klauso"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nustatykite numatytąją užrašų programą Nustatymuose"</string>
<string name="install_app" msgid="5066668100199613936">"Įdiegti programą"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Bendrinti ekrano vaizdą išoriniame ekrane?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Įgalinti ekraną"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonas ir fotoaparatas"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Pastarasis programos naudojimas"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Žr. pastarąją prieigą"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4b5fea3050f2..52ccc16e0ac7 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Pārvietot uz leju"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Pārvietot pa kreisi"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Pārvietot pa labi"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Palielinājuma slēdzis"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Palielināt visu ekrānu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Palielināt ekrāna daļu"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistents klausās"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Iestatījumos iestatiet noklusējuma piezīmju lietotni."</string>
<string name="install_app" msgid="5066668100199613936">"Instalēt lietotni"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vai spoguļot ārējā displejā?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Iespējot displeju"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofons un kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nesen izmantoja lietotnes"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Skatīt neseno piekļuvi"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 80aa943505ff..7d218baff314 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -299,13 +299,13 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Работни апликации"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Паузирано"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Ноќно светло"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Вклуч. на зајдисонце"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"На зајдисонце"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До изгрејсонце"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Вклучување: <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Темна тема"</string>
<string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Штедач на батерија"</string>
- <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Вклуч. на зајдисонце"</string>
+ <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"На зајдисонце"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрејсонце"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Се вклучува во <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Премести надолу"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Премести налево"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Премести надесно"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Прекинувач за зголемување"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Зголемете го целиот екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Зголемувајте дел од екранот"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Вниманието на „Помошникот“ е вклучено"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Поставете стандардна апликација за белешки во „Поставки“"</string>
<string name="install_app" msgid="5066668100199613936">"Инсталирајте ја апликацијата"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Да се синхронизира на надворешниот екран?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Овозможи екран"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Неодамнешно користење на апликација"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Видете го скорешниот пристап"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 021607d5508b..b5feddbd5068 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -299,7 +299,7 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"ഔദ്യോഗിക ആപ്പുകൾ"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"തൽക്കാലം നിർത്തി"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"നൈറ്റ് ലൈറ്റ്"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"സൂര്യാസ്‌തമയത്തിന്"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"അസ്‌തമയത്തിന്"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"സൂര്യോദയം വരെ"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g>-ന്"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> വരെ"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"താഴേക്ക് നീക്കുക"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ഇടത്തേക്ക് നീക്കുക"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"വലത്തേക്ക് നീക്കുക"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"മാഗ്നിഫിക്കേഷൻ മോഡ് മാറുക"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"സ്ക്രീൻ പൂർണ്ണമായും മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"സ്‌ക്രീനിന്റെ ഭാഗം മാഗ്നിഫൈ ചെയ്യുക"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant സജീവമാണ്"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ക്രമീകരണത്തിൽ കുറിപ്പുകൾക്കുള്ള ഡിഫോൾട്ട് ആപ്പ് സജ്ജീകരിക്കുക"</string>
<string name="install_app" msgid="5066668100199613936">"ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യൂ"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ബാഹ്യ ഡിസ്‌പ്ലേയിലേക്ക് മിറർ ചെയ്യണോ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ഡിസ്‌പ്ലേ പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"മൈക്രോഫോണും ക്യാമറയും"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"അടുത്തിടെയുള്ള ആപ്പ് ഉപയോഗം"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"അടുത്തിടെയുള്ള ആക്‌സസ് കാണുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 9c7cf8ba932d..4bf4f6ae6443 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Доош зөөх"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Зүүн тийш зөөх"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Баруун тийш зөөх"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Томруулах сэлгэлт"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Бүтэн дэлгэцийг томруулах"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Дэлгэцийн нэг хэсгийг томруулах"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Туслах анхаарлаа хандуулж байна"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Тохиргоонд тэмдэглэлийн өгөгдмөл апп тохируулна уу"</string>
<string name="install_app" msgid="5066668100199613936">"Аппыг суулгах"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Гадны дэлгэцэд тусгал үүсгэх үү?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Дэлгэцийг идэвхжүүлэх"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон болон камер"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Аппын саяхны ашиглалт"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Саяхны хандалтыг харах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 72c5cb63fb52..eb30836b0460 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"खाली हलवा"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"डावीकडे हलवा"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"उजवीकडे हलवा"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"मॅग्निफिकेशन स्विच"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फुल स्क्रीन मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant चे लक्ष हे आता अ‍ॅक्टिव्ह आहे"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग्ज मध्ये डीफॉल्ट टिपा अ‍ॅप सेट करा"</string>
<string name="install_app" msgid="5066668100199613936">"अ‍ॅप इंस्टॉल करा"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"बाह्य डिस्प्लेवर मिरर करायचे आहे का?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"डिस्प्ले सुरू करा"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"मायक्रोफोन आणि कॅमेरा"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"अलीकडील अ‍ॅप वापर"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"अलीकडील अ‍ॅक्सेस पहा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index fd4e6b51001c..f57a66517274 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Alih ke bawah"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Alih ke kiri"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Alih ke kanan"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Suis pembesaran"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Besarkan skrin penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Besarkan sebahagian skrin"</string>
@@ -906,7 +914,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g>boleh memilih kawalan dan kandungan yang dipaparkan di sini."</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> boleh memilih kawalan dan kandungan yang dipaparkan di sini."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Alih keluar kawalan untuk <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 5d249dec93b0..bfb43ff2eae4 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -100,7 +100,7 @@
<string name="screenrecord_title" msgid="4257171601439507792">"ဖန်သားပြင်ရိုက်ကူးစက်"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
- <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"စတင် ရိုက်သံဖမ်းမလား။"</string>
+ <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"ရိုက်သံဖမ်းခြင်း စတင်မလား။"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"ရုပ်သံဖမ်းနေစဉ် Android သည် သင့်ဖန်သားပြင်တွင် မြင်နိုင်သည့် (သို့) သင့်စက်တွင် ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"အက်ပ်တစ်ခုကို ရုပ်သံဖမ်းနေစဉ် Android သည် ယင်းအက်ပ်တွင် ပြထားသည့် (သို့) ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"ရုပ်သံ စဖမ်းရန်"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"အောက်သို့ရွှေ့ရန်"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ဘယ်ဘက်သို့ရွှေ့ရန်"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ညာဘက်သို့ရွှေ့ရန်"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ချဲ့ရန် ခလုတ်"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ဖန်သားပြင်အပြည့် ချဲ့သည်"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်းကို ချဲ့ပါ"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant နားထောင်နေသည်"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ဆက်တင်များတွင် မူရင်းမှတ်စုများအက်ပ် သတ်မှတ်ပါ"</string>
<string name="install_app" msgid="5066668100199613936">"အက်ပ် ထည့်သွင်းရန်"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ပြင်ပဖန်သားပြင်သို့ စကရင်ပွားမလား။"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ဖန်သားပြင်ကို ဖွင့်ရန်"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"မိုက်ခရိုဖုန်းနှင့် ကင်မရာ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"လတ်တလော အက်ပ်အသုံးပြုမှု"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"လတ်တလောအသုံးပြုမှုကို ကြည့်ရန်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 17846751a258..6923671c399b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Flytt ned"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Flytt til venstre"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Flytt til høyre"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Forstørringsbryter"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstørr hele skjermen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstørr en del av skjermen"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistentoppmerksomhet er på"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Du kan velge en standardapp for notater i Innstillinger"</string>
<string name="install_app" msgid="5066668100199613936">"Installer appen"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vil du speile til en ekstern skjerm?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Slå på skjermen"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon og kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nylig appbruk"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se nylig tilgang"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 94ac4b7fcfc4..934718449155 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -299,13 +299,13 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"कामसम्बन्धी एपहरू"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"पज गरिएको छ"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Night Light"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"सूर्यास्तमा सक्रिय"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"सर्यास्त हुँदा अन हुन्छ"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"सूर्योदयसम्म"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g> मा सक्रिय"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> सम्म"</string>
<string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"अँध्यारो थिम"</string>
<string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"ब्याट्री सेभर"</string>
- <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"सूर्यास्तमा सक्रिय"</string>
+ <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"सर्यास्त हुँदा अन हुन्छ"</string>
<string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयसम्म"</string>
<string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> मा सक्रिय"</string>
<string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> सम्म"</string>
@@ -396,7 +396,7 @@
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
<string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथि मोड"</string>
<string name="guest_notification_session_active" msgid="5567273684713471450">"तपाईं अतिथि मोड चलाउँदै हुनुहुन्छ"</string>
- <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने तपाईं अतिथि मोडबाट बाहिरिनु हुने छ र हालको अतिथि सत्रका सबै एप तथा डेटा मेटिने छ।"</string>
+ <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"तपाईंले नयाँ प्रयोगकर्ता हाल्नुभयो भने तपाईं अतिथि मोडबाट बाहिरिनु हुने छ र हालको अतिथि सत्रका सबै एप तथा डेटा मेटिने छ।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
<string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{एउटा प्रोफाइल मात्र बनाउन सकिन्छ।}other{तपाईं बढीमा # जना प्रयोगकर्ता सामेल गराउन सक्नुहुन्छ।}}"</string>
<string name="user_remove_user_title" msgid="9124124694835811874">"प्रयोगकर्ता हटाउन चाहनुहुन्छ?"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"तल सार्नुहोस्"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"बायाँ सार्नुहोस्"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"दायाँ सार्नुहोस्"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"म्याग्निफिकेसन स्विच"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"पूरै स्क्रिन जुम इन गर्नुहोस्"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रिनको केही भाग म्याग्निफाइ गर्नुहोस्"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"सहायकले सुनिरहेको छ"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिङमा गई नोट बनाउने डिफल्ट एप तोक्नुहोस्"</string>
<string name="install_app" msgid="5066668100199613936">"एप इन्स्टल गर्नुहोस्"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"बाह्य डिस्प्लेमा मिरर गर्ने हो?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"डिस्प्ले अन गर्नुहोस्"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफोन तथा क्यामेरा"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"एपको हालसालैको प्रयोग"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"हालसालै एक्सेस गर्ने एप हेर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index f15eda0eaec0..a42337f895c7 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Omlaag verplaatsen"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Naar links verplaatsen"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Naar rechts verplaatsen"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Vergrotingsschakelaar"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Volledig scherm vergroten"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Deel van het scherm vergroten"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent-aandacht aan"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standaard notitie-app instellen in Instellingen"</string>
<string name="install_app" msgid="5066668100199613936">"App installeren"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Spiegelen naar extern scherm?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Scherm aanzetten"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfoon en camera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app-gebruik"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Recente toegang bekijken"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 8e34628e67de..24aef78e987b 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ତଳକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ବାମକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ଡାହାଣକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ସ୍ୱିଚ୍"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ମ୍ୟାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ଆଟେନସନ ଚାଲୁ ଅଛି"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ସେଟିଂସରେ ଡିଫଲ୍ଟ ନୋଟ୍ସ ଆପ ସେଟ କରନ୍ତୁ"</string>
<string name="install_app" msgid="5066668100199613936">"ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେକୁ ମିରର କରିବେ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ଡିସପ୍ଲେକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ମାଇକ୍ରୋଫୋନ ଏବଂ କେମେରା"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ବର୍ତ୍ତମାନର ଆପ ବ୍ୟବହାର"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ବର୍ତ୍ତମାନର ଆକ୍ସେସ ଦେଖନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0861ca3ac1be..2ebc398fe7ce 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ਹੇਠਾਂ ਲਿਜਾਓ"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ਖੱਬੇ ਲਿਜਾਓ"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ਸੱਜੇ ਲਿਜਾਓ"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਸਵਿੱਚ"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰੋ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ਸਕ੍ਰੀਨ ਦੇ ਹਿੱਸੇ ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ਧਿਆਨ ਸੁਵਿਧਾ ਨੂੰ ਚਾਲੂ ਹੈ"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਨੋਟ ਐਪ ਨੂੰ ਸੈੱਟ ਕਰੋ"</string>
<string name="install_app" msgid="5066668100199613936">"ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"ਕੀ ਬਾਹਰੀ ਡਿਸਪਲੇ \'ਤੇ ਪ੍ਰਤਿਬਿੰਬਿਤ ਕਰਨਾ ਹੈ?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ਡਿਸਪਲੇ ਚਾਲੂ ਕਰੋ"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਕੈਮਰਾ"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ਹਾਲ ਹੀ ਵਿੱਚ ਵਰਤੀ ਗਈ ਐਪ"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ਹਾਲੀਆ ਪਹੁੰਚ ਦੇਖੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fff57dba3b7c..b495a5768b4b 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Przesuń w dół"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Przesuń w lewo"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Przesuń w prawo"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Przełączanie powiększenia"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Powiększanie pełnego ekranu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Powiększ część ekranu"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Asystent jest aktywny"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ustaw domyślną aplikację do obsługi notatek w Ustawieniach"</string>
<string name="install_app" msgid="5066668100199613936">"Zainstaluj aplikację"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Powielić na wyświetlaczu zewnętrznym?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Włącz wyświetlacz"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i aparat"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikacje korzystające w ostatnim czasie"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobacz ostatni dostęp"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 431863e62ecf..abfc9412b904 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -109,7 +109,7 @@
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sons do dispositivo, como música, chamadas e toques"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Microfone"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Áudio e microfone do dispositivo"</string>
- <string name="screenrecord_continue" msgid="4055347133700593164">"Início"</string>
+ <string name="screenrecord_continue" msgid="4055347133700593164">"Iniciar"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Gravando tela"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Gravando tela e áudio"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques na tela"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover para baixo"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Chave de ampliação"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
@@ -906,7 +914,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> pode escolher quais controles e conteúdos aparecem aqui."</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"O app <xliff:g id="APPNAME">%s</xliff:g> pode escolher quais controles e conteúdos aparecem aqui."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controles do app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -1130,7 +1138,7 @@
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
- <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acesso único"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
<string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os dele. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Atenção do Assistente ativada"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defina o app de notas padrão nas Configurações"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar o app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Espelhar para a tela externa?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Ativar tela"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente do app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consultar acessos recentes"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1c0ff6b1a105..85cd09aa3f5d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover para baixo"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Interruptor de ampliação"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar o ecrã inteiro"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte do ecrã"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 431863e62ecf..abfc9412b904 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -109,7 +109,7 @@
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sons do dispositivo, como música, chamadas e toques"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Microfone"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Áudio e microfone do dispositivo"</string>
- <string name="screenrecord_continue" msgid="4055347133700593164">"Início"</string>
+ <string name="screenrecord_continue" msgid="4055347133700593164">"Iniciar"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Gravando tela"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Gravando tela e áudio"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques na tela"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mover para baixo"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mover para a esquerda"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mover para a direita"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Chave de ampliação"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
@@ -906,7 +914,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> pode escolher quais controles e conteúdos aparecem aqui."</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"O app <xliff:g id="APPNAME">%s</xliff:g> pode escolher quais controles e conteúdos aparecem aqui."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controles do app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -1130,7 +1138,7 @@
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
- <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acesso único"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
<string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os dele. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Atenção do Assistente ativada"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defina o app de notas padrão nas Configurações"</string>
<string name="install_app" msgid="5066668100199613936">"Instalar o app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Espelhar para a tela externa?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Ativar tela"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente do app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consultar acessos recentes"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 513abc28a33d..1f57dfe09d64 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Mută în jos"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Mută la stânga"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Mută spre dreapta"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Comutator de mărire"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Mărește tot ecranul"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Mărește o parte a ecranului"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistentul este atent"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setează aplicația prestabilită de note din Setări"</string>
<string name="install_app" msgid="5066668100199613936">"Instalează aplicația"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Oglindești pe ecranul extern?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Activează ecranul"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Microfon și cameră"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilizare recentă în aplicații"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Vezi accesarea recentă"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 694ccdf1aeb1..1ea9d34e548f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Переместить вниз"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Переместить влево"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Переместить вправо"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Переключатель режима увеличения"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличение всего экрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличить часть экрана"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Ассистент готов слушать"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартное приложение для заметок в настройках."</string>
<string name="install_app" msgid="5066668100199613936">"Установить приложение"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Дублировать на внешний дисплей?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Включить дисплей"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Недавнее использование приложениями"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Посмотреть недавний доступ"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 7ac474d67c8f..3f2978cbac52 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"පහළට ගෙන යන්න"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"වමට ගෙන යන්න"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"දකුණට ගෙන යන්න"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"විශාලන ස්විචය"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"පූර්ණ තිරය විශාලනය කරන්න"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"තිරයේ කොටසක් විශාලනය කරන්න"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"සහයක අවධානය යොමු කරයි"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"සැකසීම් තුළ පෙරනිමි සටහන් යෙදුම සකසන්න"</string>
<string name="install_app" msgid="5066668100199613936">"යෙදුම ස්ථාපනය කරන්න"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"බාහිර සංදර්ශකයට දර්පණය කරන්න ද?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"සංදර්ශකය සබල කරන්න"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"මයික්‍රොෆෝනය සහ කැමරාව"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"මෑත යෙදුම් භාවිතය"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"මෑත ප්‍රවේශය බලන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 92813d026370..ba94b1af65cd 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -299,7 +299,7 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Pracovné aplikácie"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Pozastavené"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Nočný režim"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Zapne sa pri západe slnka"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Zap. pri záp. slnka"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do východu slnka"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Od <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Posunúť nadol"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Posunúť doľava"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Posunúť doprava"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Prepínač zväčenia"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zväčšenie celej obrazovky"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zväčšiť časť obrazovky"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Pozornosť Asistenta je zapnutá"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nastavte predvolenú aplikáciu na poznámky v Nastaveniach"</string>
<string name="install_app" msgid="5066668100199613936">"Inštalovať aplikáciu"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Chcete zrkadliť na externú obrazovku?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Povoliť obrazovku"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofón a fotoaparát"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedávne využitie aplikácie"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobraziť nedávny prístup"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 065035480574..8baa3b6a107d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Premakni navzdol"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Premakni levo"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Premakni desno"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Stikalo za povečavo"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povečanje celotnega zaslona"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povečava dela zaslona"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Zaznavanje pomočnika je vklopljeno."</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nastavite privzeto aplikacijo za zapiske v nastavitvah."</string>
<string name="install_app" msgid="5066668100199613936">"Namesti aplikacijo"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Želite zrcaliti v zunanji zaslon?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Omogoči zaslon"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon in fotoaparat"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavna uporaba v aplikacijah"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ogled nedavnih dostopov"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 08d3c55381da..ec1a6ccd11ac 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -299,7 +299,7 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Aplikacionet e punës"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Vendosur në pauzë"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Drita e natës"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Në perëndim të diellit"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Aktiv në perëndim"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Deri në lindje të diellit"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Aktive në <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Deri në <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -382,7 +382,7 @@
<string name="interruption_level_none_twoline" msgid="8579382742855486372">"Heshtje\ne plotë"</string>
<string name="interruption_level_priority_twoline" msgid="8523482736582498083">"Vetëm\nme prioritet"</string>
<string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Vetëm\nalarmet"</string>
- <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet me valë • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
+ <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet në mënyrë wireless • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet shpejt • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet ngadalë • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Lëvize poshtë"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Lëvize majtas"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Lëvize djathtas"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Ndërrimi i zmadhimit"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zmadho ekranin e plotë"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zmadho një pjesë të ekranit"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Vëmendja e \"Asistentit\" aktive"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Cakto aplikacionin e parazgjedhur të shënimeve te \"Cilësimet\""</string>
<string name="install_app" msgid="5066668100199613936">"Instalo aplikacionin"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Të pasqyrohet në ekranin e jashtëm?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Aktivizo ekranin"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoni dhe kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Përdorimi i fundit i aplikacionit"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Shiko qasjen e fundit"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1856303313f5..fc67121e7b5d 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Померите надоле"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Померите налево"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Померите надесно"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Прелазак на други режим увећања"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Помоћник је у активном стању"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Подесите подразумевану апликацију за белешке у Подешавањима"</string>
<string name="install_app" msgid="5066668100199613936">"Инсталирај апликацију"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Желите ли да пресликате на спољњи екран?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Омогући екран"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Недавно користила апликација"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Прикажи недавни приступ"</string>
@@ -1186,10 +1192,10 @@
<string name="privacy_dialog_manage_permissions" msgid="2543451567190470413">"Управљај приступом"</string>
<string name="privacy_dialog_active_call_usage" msgid="7858746847946397562">"Користи телефонски позив"</string>
<string name="privacy_dialog_recent_call_usage" msgid="1214810644978167344">"Недавно коришћено у телефонском позиву"</string>
- <string name="privacy_dialog_active_app_usage" msgid="631997836335929880">"Користи <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="privacy_dialog_active_app_usage" msgid="631997836335929880">"Користе <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="privacy_dialog_recent_app_usage" msgid="4883417856848222450">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="privacy_dialog_active_app_usage_1" msgid="9047570143069220911">"Користи <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string>
+ <string name="privacy_dialog_active_app_usage_1" msgid="9047570143069220911">"Користе <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string>
- <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Користи <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
+ <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Користе <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 76b6f1db9e45..98c830189526 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Flytta nedåt"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Flytta åt vänster"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Flytta åt höger"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Förstoringsreglage"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Förstora hela skärmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Förstora en del av skärmen"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistenten är aktiverad"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ställ in en standardapp för anteckningar i inställningarna"</string>
<string name="install_app" msgid="5066668100199613936">"Installera appen"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Vill du spegla till extern skärm?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Aktivera skärm"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon och kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Senaste appanvändning"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se senaste åtkomst"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 17135446878f..0bc5750d9a77 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Sogeza chini"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Sogeza kushoto"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Sogeza kulia"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Swichi ya ukuzaji"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Kuza skrini nzima"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Kuza sehemu ya skrini"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Programu ya Mratibu imewashwa"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Teua programu chaguomsingi ya madokezo katika Mipangilio"</string>
<string name="install_app" msgid="5066668100199613936">"Sakinisha programu"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Ungependa kuonyesha kwenye skrini ya nje?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Washa skrini"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Maikrofoni na Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Matumizi ya programu hivi majuzi"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Angalia ufikiaji wa majuzi"</string>
diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml
index 588638f3dea5..e63229aea70b 100644
--- a/packages/SystemUI/res/values-sw600dp-land/config.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/config.xml
@@ -36,4 +36,8 @@
<integer name="power_menu_lite_max_columns">3</integer>
<integer name="power_menu_lite_max_rows">2</integer>
+ <!-- Whether to force split shade.
+ For now, this value has effect only when flag lockscreen.enable_landscape is enabled.
+ TODO (b/293290851) - change this comment/resource when flag is enabled -->
+ <bool name="force_config_use_split_notification_shade">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 915dcdb9755f..1e54fc9e1445 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -80,10 +80,10 @@
<dimen name="large_screen_shade_header_height">42dp</dimen>
<!-- start padding is smaller to account for status icon margins coming from drawable itself -->
- <dimen name="shade_header_system_icons_padding_start">3dp</dimen>
- <dimen name="shade_header_system_icons_padding_end">4dp</dimen>
- <dimen name="shade_header_system_icons_padding_top">2dp</dimen>
- <dimen name="shade_header_system_icons_padding_bottom">2dp</dimen>
+ <dimen name="hover_system_icons_container_padding_start">3dp</dimen>
+ <dimen name="hover_system_icons_container_padding_end">4dp</dimen>
+ <dimen name="hover_system_icons_container_padding_top">2dp</dimen>
+ <dimen name="hover_system_icons_container_padding_bottom">2dp</dimen>
<!-- Lockscreen shade transition values -->
<dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index c0e4c3d716ee..f3954d6a06c2 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"கீழே நகர்த்து"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"இடப்புறம் நகர்த்து"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"வலப்புறம் நகர்த்து"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"பெரிதாக்கல் ஸ்விட்ச்"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"முழுத்திரையைப் பெரிதாக்கும்"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"திரையின் ஒரு பகுதியைப் பெரிதாக்கும்"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"அசிஸ்டண்ட்டின் கவனம் இயக்கத்தில் உள்ளது"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"குறிப்பு எடுப்பதற்கான இயல்புநிலை ஆப்ஸை அமைப்புகளில் அமையுங்கள்"</string>
<string name="install_app" msgid="5066668100199613936">"ஆப்ஸை நிறுவுங்கள்"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"வெளிப்புறக் காட்சிக்கு மிரர் செய்யவா?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"காட்சியை இயக்கு"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"மைக்ரோஃபோனும் கேமராவும்"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"சமீபத்திய ஆப்ஸ் பயன்பாடு"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"சமீபத்திய அணுகலைக் காட்டு"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 22a329b4e648..1d221f42c852 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"కిందకి పంపండి"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ఎడమవైపుగా జరపండి"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"కుడివైపుగా జరపండి"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"మ్యాగ్నిఫికేషన్ స్విచ్"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్‌ను మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మ్యాగ్నిఫై చేయండి"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant అటెన్షన్ ఆన్‌లో ఉంది"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"సెట్టింగ్‌లలో ఆటోమేటిక్‌గా ఉండేలా ఒక నోట్స్ యాప్‌ను సెట్ చేసుకోండి"</string>
<string name="install_app" msgid="5066668100199613936">"యాప్‌ను ఇన్‌స్టాల్ చేయండి"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"బాహ్య డిస్‌ప్లే‌ను మిర్రర్ చేయాలా?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"డిస్‌ప్లే‌ను ఎనేబుల్ చేయండి"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"మైక్రోఫోన్ &amp; కెమెరా"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"ఇటీవలి యాప్ వినియోగం"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ఇటీవలి యాక్సెస్‌ను చూడండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 3887b9f8b9c4..df4ab83ee5b1 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"ย้ายลง"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"ย้ายไปทางซ้าย"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"ย้ายไปทางขวา"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"เปลี่ยนโหมดการขยาย"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ขยายเป็นเต็มหน้าจอ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ขยายบางส่วนของหน้าจอ"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"การเรียกใช้งาน Assistant เปิดอยู่"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"กำหนดแอปการจดบันทึกเริ่มต้นในการตั้งค่า"</string>
<string name="install_app" msgid="5066668100199613936">"ติดตั้งแอป"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"มิเรอร์ไปยังจอแสดงผลภายนอกไหม"</string>
+ <string name="enable_display" msgid="8308309634883321977">"เปิดใช้จอแสดงผล"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"ไมโครโฟนและกล้อง"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"การใช้แอปครั้งล่าสุด"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"ดูการเข้าถึงล่าสุด"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 2fdee7220e6c..a6535fdee5d5 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Ibaba"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Ilipat pakaliwa"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Ilipat pakanan"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Switch ng pag-magnify"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"I-magnify ang buong screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"I-magnify ang isang bahagi ng screen"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b01fee15ec5a..a8a9ba4725f2 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Aşağı taşı"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Sola taşı"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Sağa taşı"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Büyütme moduna geçin"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekran büyütme"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekranın bir parçasını büyütün"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistan dinliyor"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlar\'ı kullanarak varsayılan notlar ayarlayın"</string>
<string name="install_app" msgid="5066668100199613936">"Uygulamayı yükle"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Harici ekrana yansıtılsın mı?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Ekranı etkinleştir"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon ve Kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Son uygulama kullanımı"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Son erişimi göster"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index db3441352422..48c45ae68414 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -299,7 +299,7 @@
<string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Робочі додатки"</string>
<string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Призупинено"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"Нічний екран"</string>
- <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Вмикається ввечері"</string>
+ <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Запуск увечері"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"До сходу сонця"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Вмикається о <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"До <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -754,7 +754,7 @@
<string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"вилучити опцію"</string>
<string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"додати опцію в кінець"</string>
<string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Перемістити опцію"</string>
- <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додати опцію"</string>
+ <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додати панель"</string>
<string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Перемістити на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додати на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>"</string>
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Перемістити вниз"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Перемістити ліворуч"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Перемістити праворуч"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Перемикач режиму збільшення"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Збільшення всього екрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Збільшити частину екрана"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Асистента активовано"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Призначте стандартний додаток для нотаток у налаштуваннях"</string>
<string name="install_app" msgid="5066668100199613936">"Установити додаток"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Дублювати на зовнішньому екрані?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Увімкнути екран"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Мікрофон і камера"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Нещодавнє використання додатками"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Переглянути нещодавній доступ"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 8115e2e086ca..de38ca103ac8 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"نیچے منتقل کریں"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"بائیں منتقل کریں"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"دائیں منتقل کریں"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"میگنیفکیشن پر سوئچ کریں"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"فُل اسکرین کو بڑا کریں"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"اسکرین کا حصہ بڑا کریں"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"اسسٹنٹ کی توجہ آن ہے"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ترتیبات میں ڈیفالٹ نوٹس ایپ سیٹ کریں"</string>
<string name="install_app" msgid="5066668100199613936">"ایپ انسٹال کریں"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"بیرونی ڈسپلے پر مرر کریں؟"</string>
+ <string name="enable_display" msgid="8308309634883321977">"ڈسپلے کو فعال کریں"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"مائیکروفون اور کیمرا"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"حالیہ ایپ کا استعمال"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"حالیہ رسائی دیکھیں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 30e0618c1563..e5703b292a1d 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Pastga siljitish"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Chapga siljitish"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Oʻngga siljitish"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Kattalashtirish rejimini almashtirish"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ekranni toʻliq kattalashtirish"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran qismini kattalashtirish"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent diqqati yoniq"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standart qaydlar ilovasini Sozlamalar orqali tanlang"</string>
<string name="install_app" msgid="5066668100199613936">"Ilovani oʻrnatish"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Tashqi displeyda aks ettirilsinmi?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Displeyni yoqish"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon va kamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Ilovadan oxirgi foydalanish"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Oxirgi ruxsatni koʻrish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f4c62a5297fe..f022aea90797 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Di chuyển xuống"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Di chuyển sang trái"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Di chuyển sang phải"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Nút chuyển phóng to"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Phóng to toàn màn hình"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Phóng to một phần màn hình"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Trợ lý đang bật"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Đặt ứng dụng ghi chú mặc định trong phần Cài đặt"</string>
<string name="install_app" msgid="5066668100199613936">"Cài đặt ứng dụng"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Đồng bộ hoá hai chiều sang màn hình ngoài?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Bật màn hình"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Micrô và máy ảnh"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Hoạt động sử dụng gần đây của ứng dụng"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Xem hoạt động truy cập gần đây"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f3ade0390797..6876b1cf623b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"下移"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"左移"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"右移"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"切换放大模式"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整个屏幕"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分屏幕"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"已开启 Google 助理感知功能"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在设置中设置默认记事应用"</string>
<string name="install_app" msgid="5066668100199613936">"安装应用"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"镜像到外接显示屏?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"启用显示屏"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"麦克风和摄像头"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"近期应用对手机传感器的使用情况"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期使用情况"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index efc567107d8f..31f2a8532d0e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"向下移"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"向左移"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"向右移"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"放大開關"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大成個畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分螢幕畫面"</string>
@@ -1130,7 +1138,7 @@
<string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
<string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
<string name="log_access_confirmation_title" msgid="4843557604739943395">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string>
- <string name="log_access_confirmation_allow" msgid="752147861593202968">"允許存取一次"</string>
+ <string name="log_access_confirmation_allow" msgid="752147861593202968">"允許單次存取"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允許"</string>
<string name="log_access_confirmation_body" msgid="6883031912003112634">"裝置記錄會記下裝置的活動。應用程式可透過這些記錄找出並修正問題。\n\n部分記錄可能包含敏感資料,因此請只允許信任的應用程式存取所有裝置記錄。\n\n如果不允許此應用程式存取所有裝置記錄,此應用程式仍能存取自己的記錄,且裝置製造商可能仍可存取裝置上的部分記錄或資料。"</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"瞭解詳情"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"「Google 助理」感應功能已開啟"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設筆記應用程式"</string>
<string name="install_app" msgid="5066668100199613936">"安裝應用程式"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"要鏡像投射至外部顯示屏嗎?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"啟用顯示屏"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"麥克風和相機"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"近期應用程式使用情況"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期存取記錄"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index af84a3122289..81ce876faf3c 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"向下移"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"向左移"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"向右移"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"切換放大模式"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整個螢幕畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大局部螢幕畫面"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Google 助理感知功能已開啟"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設記事應用程式"</string>
<string name="install_app" msgid="5066668100199613936">"安裝應用程式"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"要以鏡像方式投放至外部螢幕嗎?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"啟用螢幕"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"麥克風和相機"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"最近曾使用感應器的應用程式"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期存取記錄"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 11cf44b4e2e6..63f32227d7e7 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -863,6 +863,14 @@
<string name="accessibility_control_move_down" msgid="5390922476900974512">"Yehlisa"</string>
<string name="accessibility_control_move_left" msgid="8156206978511401995">"Yisa kwesokunxele"</string>
<string name="accessibility_control_move_right" msgid="8926821093629582888">"Yisa kwesokudla"</string>
+ <!-- no translation found for accessibility_control_increase_window_width (6992249470832493283) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_width (5740401560105929681) -->
+ <skip />
+ <!-- no translation found for accessibility_control_increase_window_height (2200966116612324260) -->
+ <skip />
+ <!-- no translation found for accessibility_control_decrease_window_height (2054479949445332761) -->
+ <skip />
<string name="magnification_mode_switch_description" msgid="2698364322069934733">"Iswishi yokukhulisa"</string>
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Khulisa isikrini esigcwele"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Khulisa ingxenye eyesikrini"</string>
@@ -1170,10 +1178,8 @@
<string name="assistant_attention_content_description" msgid="6830215897604642875">"Ukunaka kwe-Assistant kuvuliwe"</string>
<string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setha i-app yamanothi azenzakalelayo Kumsethingi"</string>
<string name="install_app" msgid="5066668100199613936">"Faka i-app"</string>
- <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) -->
- <skip />
- <!-- no translation found for enable_display (8308309634883321977) -->
- <skip />
+ <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Fanisa nesibonisi sangaphandle?"</string>
+ <string name="enable_display" msgid="8308309634883321977">"Nika amandla isibonisi"</string>
<string name="privacy_dialog_title" msgid="7839968133469098311">"Imakrofoni Nekhamera"</string>
<string name="privacy_dialog_summary" msgid="2458769652125995409">"Ukusetshenziswa kwakamuva kwe-app"</string>
<string name="privacy_dialog_more_button" msgid="7610604080293562345">"Bona ukufinyelela kwakamuva"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index c13480672102..c72f5657176b 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -592,6 +592,11 @@
<!-- Whether to use the split 2-column notification shade -->
<bool name="config_use_split_notification_shade">false</bool>
+ <!-- Whether to force split shade.
+ For now, this value has effect only when flag lockscreen.enable_landscape is enabled.
+ TODO (b/293290851) - change this comment/resource when flag is enabled -->
+ <bool name="force_config_use_split_notification_shade">false</bool>
+
<!-- Whether we use large screen shade header which takes only one row compared to QS header -->
<bool name="config_use_large_screen_shade_header">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b086ed8960b1..ae3138ef0c52 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -496,10 +496,10 @@
<dimen name="large_screen_shade_header_min_height">@dimen/qs_header_row_min_height</dimen>
<dimen name="large_screen_shade_header_left_padding">@dimen/qs_horizontal_margin</dimen>
<dimen name="shade_header_system_icons_height">@dimen/large_screen_shade_header_min_height</dimen>
- <dimen name="shade_header_system_icons_padding_start">0dp</dimen>
- <dimen name="shade_header_system_icons_padding_end">0dp</dimen>
- <dimen name="shade_header_system_icons_padding_top">0dp</dimen>
- <dimen name="shade_header_system_icons_padding_bottom">0dp</dimen>
+ <dimen name="hover_system_icons_container_padding_start">0dp</dimen>
+ <dimen name="hover_system_icons_container_padding_end">0dp</dimen>
+ <dimen name="hover_system_icons_container_padding_top">0dp</dimen>
+ <dimen name="hover_system_icons_container_padding_bottom">0dp</dimen>
<!-- The top margin of the panel that holds the list of notifications.
On phones it's always 0dp but it's overridden in Car UI
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index 8200e5c84186..905923039f8b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -17,6 +17,7 @@
package com.android.systemui.shared.rotation;
import static android.content.pm.PackageManager.FEATURE_PC;
+import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.internal.view.RotationPolicy.NATURAL_ROTATION;
@@ -37,6 +38,8 @@ import android.content.IntentFilter;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -67,6 +70,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
import java.io.PrintWriter;
import java.util.Optional;
+import java.util.concurrent.Executor;
import java.util.function.Supplier;
/**
@@ -119,6 +123,8 @@ public class RotationButtonController {
private final int mIconCwStart0ResId;
@DrawableRes
private final int mIconCwStart90ResId;
+ /** Defaults to mainExecutor if not set via {@link #setBgExecutor(Executor)}. */
+ private Executor mBgExecutor;
@DrawableRes
private int mIconResId;
@@ -178,6 +184,8 @@ public class RotationButtonController {
mAccessibilityManager = AccessibilityManager.getInstance(context);
mTaskStackListener = new TaskStackListenerImpl();
mWindowRotationProvider = windowRotationProvider;
+
+ mBgExecutor = context.getMainExecutor();
}
public void setRotationButton(RotationButton rotationButton,
@@ -193,6 +201,10 @@ public class RotationButtonController {
return mContext;
}
+ public void setBgExecutor(Executor bgExecutor) {
+ mBgExecutor = bgExecutor;
+ }
+
/**
* Called during Taskbar initialization.
*/
@@ -219,8 +231,11 @@ public class RotationButtonController {
mListenersRegistered = true;
- updateDockedState(mContext.registerReceiver(mDockedReceiver,
- new IntentFilter(Intent.ACTION_DOCK_EVENT)));
+ mBgExecutor.execute(() -> {
+ final Intent intent = mContext.registerReceiver(mDockedReceiver,
+ new IntentFilter(Intent.ACTION_DOCK_EVENT));
+ mContext.getMainExecutor().execute(() -> updateDockedState(intent));
+ });
if (registerRotationWatcher) {
try {
@@ -246,11 +261,13 @@ public class RotationButtonController {
mListenersRegistered = false;
- try {
- mContext.unregisterReceiver(mDockedReceiver);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Docked receiver already unregistered", e);
- }
+ mBgExecutor.execute(() -> {
+ try {
+ mContext.unregisterReceiver(mDockedReceiver);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Docked receiver already unregistered", e);
+ }
+ });
if (mRotationWatcherRegistered) {
try {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index 8738d3300e93..bfd43dc258c8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -257,7 +257,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mInputMethodManager, emergencyButtonController, mMainExecutor, mResources,
mFalsingCollector, mKeyguardViewController,
- mFeatureFlags);
+ mDevicePostureController, mFeatureFlags);
} else if (keyguardInputView instanceof KeyguardPINView) {
((KeyguardPINView) keyguardInputView).setIsLockScreenLandscapeEnabled(
mFeatureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 59ee0d817ef3..d30f4971f8de 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.WindowInsets.Type.ime;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
@@ -27,10 +28,13 @@ import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FO
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED;
import static com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Insets;
@@ -46,12 +50,16 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.constraintlayout.motion.widget.MotionLayout;
import com.android.app.animation.Interpolators;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.TextViewInputDisabler;
import com.android.systemui.DejankUtils;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.DevicePostureController;
+
+
/**
* Displays an alphanumeric (latin-1) key entry for the user to enter
* an unlock password
@@ -68,10 +76,14 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
private TextView mPasswordEntry;
private TextViewInputDisabler mPasswordEntryDisabler;
-
private Interpolator mLinearOutSlowInInterpolator;
private Interpolator mFastOutLinearInInterpolator;
private DisappearAnimationListener mDisappearAnimationListener;
+ @Nullable private MotionLayout mContainerMotionLayout;
+ private boolean mAlreadyUsingSplitBouncer = false;
+ private boolean mIsLockScreenLandscapeEnabled = false;
+ @DevicePostureController.DevicePostureInt
+ private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
private static final int[] DISABLE_STATE_SET = {-android.R.attr.state_enabled};
private static final int[] ENABLE_STATE_SET = {android.R.attr.state_enabled};
@@ -89,6 +101,21 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
context, android.R.interpolator.fast_out_linear_in);
}
+ /**
+ * Use motion layout (new bouncer implementation) if LOCKSCREEN_ENABLE_LANDSCAPE flag is
+ * enabled
+ */
+ public void setIsLockScreenLandscapeEnabled() {
+ mIsLockScreenLandscapeEnabled = true;
+ findContainerLayout();
+ }
+
+ private void findContainerLayout() {
+ if (mIsLockScreenLandscapeEnabled) {
+ mContainerMotionLayout = findViewById(R.id.password_container);
+ }
+ }
+
@Override
protected void resetState() {
}
@@ -124,6 +151,40 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
}
}
+ void onDevicePostureChanged(@DevicePostureController.DevicePostureInt int posture) {
+ if (mLastDevicePosture == posture) return;
+ mLastDevicePosture = posture;
+
+ if (mIsLockScreenLandscapeEnabled) {
+ boolean useSplitBouncerAfterFold =
+ mLastDevicePosture == DEVICE_POSTURE_CLOSED
+ && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
+
+ if (mAlreadyUsingSplitBouncer != useSplitBouncerAfterFold) {
+ updateConstraints(useSplitBouncerAfterFold);
+ }
+ }
+
+ }
+
+ @Override
+ protected void updateConstraints(boolean useSplitBouncer) {
+ mAlreadyUsingSplitBouncer = useSplitBouncer;
+ KeyguardSecurityViewFlipper.LayoutParams params =
+ (KeyguardSecurityViewFlipper.LayoutParams) getLayoutParams();
+
+ if (useSplitBouncer) {
+ if (mContainerMotionLayout == null) return;
+ mContainerMotionLayout.jumpToState(R.id.split_constraints);
+ params.maxWidth = Integer.MAX_VALUE;
+ } else {
+ mContainerMotionLayout.jumpToState(R.id.single_constraints);
+ params.maxWidth = getResources()
+ .getDimensionPixelSize(R.dimen.keyguard_security_width);
+ }
+
+ setLayoutParams(params);
+ }
@Override
protected void onFinishInflate() {
@@ -131,6 +192,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
mPasswordEntry = findViewById(getPasswordTextViewId());
mPasswordEntryDisabler = new TextViewInputDisabler(mPasswordEntry);
+
+ // EditText cursor can fail screenshot tests, so disable it when testing
+ if (ActivityManager.isRunningInTestHarness()) {
+ mPasswordEntry.setCursorVisible(false);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index 5dbd01407a43..ab8cd531c307 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -16,6 +16,8 @@
package com.android.keyguard;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE;
+
import android.content.res.Resources;
import android.os.UserHandle;
import android.text.Editable;
@@ -41,6 +43,7 @@ import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import java.util.List;
@@ -49,8 +52,10 @@ public class KeyguardPasswordViewController
extends KeyguardAbsKeyInputViewController<KeyguardPasswordView> {
private static final int DELAY_MILLIS_TO_REEVALUATE_IME_SWITCH_ICON = 500; // 500ms
-
private final KeyguardSecurityCallback mKeyguardSecurityCallback;
+ private final DevicePostureController mPostureController;
+ private final DevicePostureController.Callback mPostureCallback = posture ->
+ mView.onDevicePostureChanged(posture);
private final InputMethodManager mInputMethodManager;
private final DelayableExecutor mMainExecutor;
private final KeyguardViewController mKeyguardViewController;
@@ -106,14 +111,19 @@ public class KeyguardPasswordViewController
@Main Resources resources,
FalsingCollector falsingCollector,
KeyguardViewController keyguardViewController,
+ DevicePostureController postureController,
FeatureFlags featureFlags) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, falsingCollector,
emergencyButtonController, featureFlags);
mKeyguardSecurityCallback = keyguardSecurityCallback;
mInputMethodManager = inputMethodManager;
+ mPostureController = postureController;
mMainExecutor = mainExecutor;
mKeyguardViewController = keyguardViewController;
+ if (featureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE)) {
+ view.setIsLockScreenLandscapeEnabled();
+ }
mShowImeAtScreenOn = resources.getBoolean(R.bool.kg_show_ime_at_screen_on);
mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());
mSwitchImeButton = mView.findViewById(R.id.switch_ime_button);
@@ -127,6 +137,9 @@ public class KeyguardPasswordViewController
mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ mView.onDevicePostureChanged(mPostureController.getDevicePosture());
+ mPostureController.addCallback(mPostureCallback);
+
// Set selected property on so the view can send accessibility events.
mPasswordEntry.setSelected(true);
mPasswordEntry.setOnEditorActionListener(mOnEditorActionListener);
@@ -164,6 +177,7 @@ public class KeyguardPasswordViewController
protected void onViewDetached() {
super.onViewDetached();
mPasswordEntry.setOnEditorActionListener(null);
+ mPostureController.removeCallback(mPostureCallback);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 2bdf46e1309d..56706b5a7135 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -15,9 +15,13 @@
*/
package com.android.keyguard;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED;
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -29,6 +33,7 @@ import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import androidx.constraintlayout.motion.widget.MotionLayout;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
@@ -75,7 +80,10 @@ public class KeyguardPatternView extends KeyguardInputView
BouncerKeyguardMessageArea mSecurityMessageDisplay;
private View mEcaView;
- private ConstraintLayout mContainer;
+ @Nullable private MotionLayout mContainerMotionLayout;
+ @Nullable private ConstraintLayout mContainerConstraintLayout;
+ private boolean mAlreadyUsingSplitBouncer = false;
+ private boolean mIsLockScreenLandscapeEnabled = false;
@DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
public KeyguardPatternView(Context context) {
@@ -98,16 +106,44 @@ public class KeyguardPatternView extends KeyguardInputView
mContext, android.R.interpolator.fast_out_linear_in));
}
+ /**
+ * Use motion layout (new bouncer implementation) if LOCKSCREEN_ENABLE_LANDSCAPE flag is
+ * enabled, instead of constraint layout (old bouncer implementation)
+ */
+ public void setIsLockScreenLandscapeEnabled(boolean isLockScreenLandscapeEnabled) {
+ mIsLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled;
+ findContainerLayout();
+ }
+
+ private void findContainerLayout() {
+ if (mIsLockScreenLandscapeEnabled) {
+ mContainerMotionLayout = findViewById(R.id.pattern_container);
+ } else {
+ mContainerConstraintLayout = findViewById(R.id.pattern_container);
+ }
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
updateMargins();
}
void onDevicePostureChanged(@DevicePostureInt int posture) {
- if (mLastDevicePosture != posture) {
- mLastDevicePosture = posture;
- updateMargins();
+ if (mLastDevicePosture == posture) return;
+ mLastDevicePosture = posture;
+
+ if (mIsLockScreenLandscapeEnabled) {
+ boolean useSplitBouncerAfterFold =
+ mLastDevicePosture == DEVICE_POSTURE_CLOSED
+ && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE
+ && getResources().getBoolean(R.bool.update_bouncer_constraints);
+
+ if (mAlreadyUsingSplitBouncer != useSplitBouncerAfterFold) {
+ updateConstraints(useSplitBouncerAfterFold);
+ }
}
+
+ updateMargins();
}
private void updateMargins() {
@@ -115,12 +151,36 @@ public class KeyguardPatternView extends KeyguardInputView
float halfOpenPercentage =
mContext.getResources().getFloat(R.dimen.half_opened_bouncer_height_ratio);
- ConstraintSet cs = new ConstraintSet();
- cs.clone(mContainer);
- cs.setGuidelinePercent(R.id.pattern_top_guideline,
- mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED
- ? halfOpenPercentage : 0.0f);
- cs.applyTo(mContainer);
+ if (mIsLockScreenLandscapeEnabled) {
+ ConstraintSet cs = mContainerMotionLayout.getConstraintSet(R.id.single_constraints);
+ cs.setGuidelinePercent(R.id.pattern_top_guideline,
+ mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
+ cs.applyTo(mContainerMotionLayout);
+ } else {
+ ConstraintSet cs = new ConstraintSet();
+ cs.clone(mContainerConstraintLayout);
+ cs.setGuidelinePercent(R.id.pattern_top_guideline,
+ mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f);
+ cs.applyTo(mContainerConstraintLayout);
+ }
+ }
+
+ /**
+ * Updates the keyguard view's constraints (single or split constraints).
+ * Split constraints are only used for small landscape screens.
+ * Only called when flag LANDSCAPE_ENABLE_LOCKSCREEN is enabled.
+ */
+ @Override
+ protected void updateConstraints(boolean useSplitBouncer) {
+ mAlreadyUsingSplitBouncer = useSplitBouncer;
+ if (useSplitBouncer) {
+ mContainerMotionLayout.jumpToState(R.id.split_constraints);
+ mContainerMotionLayout.setMaxWidth(Integer.MAX_VALUE);
+ } else {
+ mContainerMotionLayout.jumpToState(R.id.single_constraints);
+ mContainerMotionLayout.setMaxWidth(getResources()
+ .getDimensionPixelSize(R.dimen.biometric_auth_pattern_view_max_size));
+ }
}
@Override
@@ -130,7 +190,6 @@ public class KeyguardPatternView extends KeyguardInputView
mLockPatternView = findViewById(R.id.lockPatternView);
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
- mContainer = findViewById(R.id.pattern_container);
}
@Override
@@ -209,7 +268,7 @@ public class KeyguardPatternView extends KeyguardInputView
getAnimationListener(InteractionJankMonitor.CUJ_LOCKSCREEN_PATTERN_DISAPPEAR));
DisappearAnimationUtils disappearAnimationUtils = needsSlowUnlockTransition
- ? mDisappearAnimationUtilsLocked : mDisappearAnimationUtils;
+ ? mDisappearAnimationUtilsLocked : mDisappearAnimationUtils;
disappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(),
() -> {
enableClipping(true);
@@ -220,7 +279,7 @@ public class KeyguardPatternView extends KeyguardInputView
if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
mDisappearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
(long) (200 * durationMultiplier),
- - mDisappearAnimationUtils.getStartTranslation() * 3,
+ -mDisappearAnimationUtils.getStartTranslation() * 3,
false /* appearing */,
mDisappearAnimationUtils.getInterpolator(),
null /* finishRunnable */);
@@ -229,9 +288,16 @@ public class KeyguardPatternView extends KeyguardInputView
}
private void enableClipping(boolean enable) {
- setClipChildren(enable);
- mContainer.setClipToPadding(enable);
- mContainer.setClipChildren(enable);
+ if (mContainerConstraintLayout != null) {
+ setClipChildren(enable);
+ mContainerConstraintLayout.setClipToPadding(enable);
+ mContainerConstraintLayout.setClipChildren(enable);
+ }
+ if (mContainerMotionLayout != null) {
+ setClipChildren(enable);
+ mContainerMotionLayout.setClipToPadding(enable);
+ mContainerMotionLayout.setClipChildren(enable);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index a30b4479fe95..98312b11e9d6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -18,6 +18,7 @@ package com.android.keyguard;
import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL;
import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL_UNLOCKED;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE;
import android.content.res.ColorStateList;
import android.os.AsyncTask;
@@ -205,6 +206,8 @@ public class KeyguardPatternViewController
mLatencyTracker = latencyTracker;
mFalsingCollector = falsingCollector;
mEmergencyButtonController = emergencyButtonController;
+ view.setIsLockScreenLandscapeEnabled(
+ featureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE));
mLockPatternView = mView.findViewById(R.id.lockPatternView);
mPostureController = postureController;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
index 4cc90c244cf2..f18504c28609 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+
import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE;
import android.util.Log;
@@ -154,9 +155,9 @@ public class KeyguardSecurityViewFlipperController
private int getLayoutIdFor(SecurityMode securityMode) {
// TODO (b/297863911, b/297864907) - implement motion layout for other bouncers
switch (securityMode) {
- case Pattern: return R.layout.keyguard_pattern_view;
+ case Pattern: return R.layout.keyguard_pattern_motion_layout;
case PIN: return R.layout.keyguard_pin_motion_layout;
- case Password: return R.layout.keyguard_password_view;
+ case Password: return R.layout.keyguard_password_motion_layout;
case SimPin: return R.layout.keyguard_sim_pin_view;
case SimPuk: return R.layout.keyguard_sim_puk_view;
default:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index 3990b10267e1..c64ae0106b4a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
import android.util.Property;
import android.view.View;
@@ -124,7 +125,16 @@ public class KeyguardVisibilityHelper {
true /* animate */);
log("keyguardFadingAway transition w/ Y Aniamtion");
} else if (statusBarState == KEYGUARD) {
- if (keyguardFadingAway) {
+ // Sometimes, device will be unlocked and then locked very quickly.
+ // keyguardFadingAway hasn't been set to false cause unlock animation hasn't finished
+ // So we should not animate keyguard fading away in this case (when oldState is SHADE)
+ if (oldStatusBarState != SHADE) {
+ log("statusBarState == KEYGUARD && oldStatusBarState != SHADE");
+ } else {
+ log("statusBarState == KEYGUARD && oldStatusBarState == SHADE");
+ }
+
+ if (keyguardFadingAway && oldStatusBarState != SHADE) {
mKeyguardViewVisibilityAnimating = true;
AnimationProperties animProps = new AnimationProperties()
.setDelay(0)
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index 1d37809a382e..c52288190a7c 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -134,8 +134,6 @@ public class LockIconView extends FrameLayout implements Dumpable {
mLockIcon.setPadding(mLockIconPadding, mLockIconPadding, mLockIconPadding,
mLockIconPadding);
- // mSensorProps coordinates assume portrait mode which is OK b/c the keyguard is always in
- // portrait.
mSensorRect.set(mLockIconCenter.x - mRadius,
mLockIconCenter.y - mRadius,
mLockIconCenter.x + mRadius,
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 464909127277..214b1228b87a 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -18,6 +18,7 @@ package com.android.keyguard;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
+
import static com.android.keyguard.LockIconView.ICON_FINGERPRINT;
import static com.android.keyguard.LockIconView.ICON_LOCK;
import static com.android.keyguard.LockIconView.ICON_UNLOCK;
@@ -44,6 +45,7 @@ import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -422,7 +424,13 @@ public class LockIconViewController implements Dumpable {
private void updateConfiguration() {
WindowManager windowManager = mContext.getSystemService(WindowManager.class);
Rect bounds = windowManager.getCurrentWindowMetrics().getBounds();
+ WindowInsets insets = windowManager.getCurrentWindowMetrics().getWindowInsets();
mWidthPixels = bounds.right;
+ if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE)) {
+ // Assumed to be initially neglected as there are no left or right insets in portrait
+ // However, on landscape, these insets need to included when calculating the midpoint
+ mWidthPixels -= insets.getSystemWindowInsetLeft() + insets.getSystemWindowInsetRight();
+ }
mHeightPixels = bounds.bottom;
mBottomPaddingPx = mResources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom);
mDefaultPaddingPx = mResources.getDimensionPixelSize(R.dimen.lock_icon_padding);
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index 87ea4111d8c8..6ca1c3de0b63 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -356,11 +356,13 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
if (mPercentageStyleId != 0) { // Only set if specified as attribute
mBatteryPercentView.setTextAppearance(mPercentageStyleId);
}
+ float fontHeight = mBatteryPercentView.getPaint().getFontMetricsInt(null);
+ mBatteryPercentView.setLineHeight(TypedValue.COMPLEX_UNIT_PX, fontHeight);
if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
updatePercentText();
addView(mBatteryPercentView, new LayoutParams(
LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT));
+ (int) Math.ceil(fontHeight)));
}
} else {
if (showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 9ffb770378c5..026435623042 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -23,6 +23,7 @@ import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_
import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING;
import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
@@ -104,6 +105,8 @@ import com.android.systemui.util.concurrency.Execution;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.SystemClock;
+import kotlin.Unit;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
@@ -114,8 +117,6 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Provider;
-import kotlin.Unit;
-
import kotlinx.coroutines.ExperimentalCoroutinesApi;
/**
@@ -255,11 +256,12 @@ public class UdfpsController implements DozeReceiver, Dumpable {
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+ final int touchConfigId = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_selected_udfps_touch_detection);
pw.println("mSensorProps=(" + mSensorProps + ")");
pw.println("Using new touch detection framework: " + mFeatureFlags.isEnabled(
Flags.UDFPS_NEW_TOUCH_DETECTION));
- pw.println("Using ellipse touch detection: " + mFeatureFlags.isEnabled(
- Flags.UDFPS_ELLIPSE_DETECTION));
+ pw.println("touchConfigId: " + touchConfigId);
}
public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
index f43285f9004a..f2d4f8912c3f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -17,6 +17,9 @@
package com.android.systemui.biometrics.dagger
import com.android.systemui.biometrics.UdfpsUtils
+import android.content.res.Resources
+import com.android.internal.R
+import com.android.systemui.biometrics.EllipseOverlapDetectorParams
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.biometrics.data.repository.FacePropertyRepositoryImpl
import com.android.systemui.biometrics.data.repository.FaceSettingsRepository
@@ -25,8 +28,8 @@ import com.android.systemui.biometrics.data.repository.FingerprintPropertyReposi
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepositoryImpl
import com.android.systemui.biometrics.data.repository.PromptRepository
import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl
-import com.android.systemui.biometrics.data.repository.RearDisplayStateRepository
-import com.android.systemui.biometrics.data.repository.RearDisplayStateRepositoryImpl
+import com.android.systemui.biometrics.data.repository.DisplayStateRepository
+import com.android.systemui.biometrics.data.repository.DisplayStateRepositoryImpl
import com.android.systemui.biometrics.domain.interactor.CredentialInteractor
import com.android.systemui.biometrics.domain.interactor.CredentialInteractorImpl
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
@@ -37,6 +40,9 @@ import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteracto
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractor
import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractorImpl
+import com.android.systemui.biometrics.udfps.BoundingBoxOverlapDetector
+import com.android.systemui.biometrics.udfps.EllipseOverlapDetector
+import com.android.systemui.biometrics.udfps.OverlapDetector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.util.concurrency.ThreadFactory
import dagger.Binds
@@ -63,16 +69,19 @@ interface BiometricsModule {
@Binds
@SysUISingleton
- fun fingerprintRepository(impl: FingerprintPropertyRepositoryImpl):
- FingerprintPropertyRepository
+ fun fingerprintRepository(
+ impl: FingerprintPropertyRepositoryImpl
+ ): FingerprintPropertyRepository
+
@Binds
@SysUISingleton
- fun rearDisplayStateRepository(impl: RearDisplayStateRepositoryImpl): RearDisplayStateRepository
+ fun displayStateRepository(impl: DisplayStateRepositoryImpl): DisplayStateRepository
@Binds
@SysUISingleton
- fun providesPromptSelectorInteractor(impl: PromptSelectorInteractorImpl):
- PromptSelectorInteractor
+ fun providesPromptSelectorInteractor(
+ impl: PromptSelectorInteractorImpl
+ ): PromptSelectorInteractor
@Binds
@SysUISingleton
@@ -88,8 +97,9 @@ interface BiometricsModule {
@Binds
@SysUISingleton
- fun providesSideFpsOverlayInteractor(impl: SideFpsOverlayInteractorImpl):
- SideFpsOverlayInteractor
+ fun providesSideFpsOverlayInteractor(
+ impl: SideFpsOverlayInteractorImpl
+ ): SideFpsOverlayInteractor
companion object {
/** Background [Executor] for HAL related operations. */
@@ -102,6 +112,30 @@ interface BiometricsModule {
@Provides
fun providesUdfpsUtils(): UdfpsUtils = UdfpsUtils()
+
+ @Provides
+ @SysUISingleton
+ fun providesOverlapDetector(): OverlapDetector {
+ val selectedOption =
+ Resources.getSystem().getInteger(R.integer.config_selected_udfps_touch_detection)
+ val values =
+ Resources.getSystem()
+ .getStringArray(R.array.config_udfps_touch_detection_options)[selectedOption]
+ .split(",")
+ .map { it.toFloat() }
+
+ return if (values[0] == 1f) {
+ EllipseOverlapDetector(
+ EllipseOverlapDetectorParams(
+ minOverlap = values[3],
+ targetSize = values[2],
+ stepSize = values[4].toInt()
+ )
+ )
+ } else {
+ BoundingBoxOverlapDetector(values[2])
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/UdfpsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/UdfpsModule.kt
deleted file mode 100644
index f7f910391566..000000000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/UdfpsModule.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics.dagger
-
-import android.content.res.Resources
-import com.android.internal.R
-import com.android.systemui.biometrics.EllipseOverlapDetectorParams
-import com.android.systemui.biometrics.udfps.BoundingBoxOverlapDetector
-import com.android.systemui.biometrics.udfps.EllipseOverlapDetector
-import com.android.systemui.biometrics.udfps.OverlapDetector
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import dagger.Module
-import dagger.Provides
-
-/** Dagger module for all things UDFPS. TODO(b/260558624): Move to BiometricsModule. */
-@Module
-interface UdfpsModule {
- companion object {
-
- @Provides
- @SysUISingleton
- fun providesOverlapDetector(featureFlags: FeatureFlags): OverlapDetector {
- if (featureFlags.isEnabled(Flags.UDFPS_ELLIPSE_DETECTION)) {
- val selectedOption =
- Resources.getSystem()
- .getInteger(R.integer.config_selected_udfps_touch_detection)
- val values =
- Resources.getSystem()
- .getStringArray(R.array.config_udfps_touch_detection_options)[
- selectedOption]
- .split(",")
- .map { it.toFloat() }
-
- return if (values[0] == 1f) {
- EllipseOverlapDetector(
- EllipseOverlapDetectorParams(
- minOverlap = values[3],
- targetSize = values[2],
- stepSize = values[4].toInt()
- )
- )
- } else {
- BoundingBoxOverlapDetector(values[2])
- }
- } else {
- return BoundingBoxOverlapDetector(1f)
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
index d17d961b5279..7a9efcf78999 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
@@ -18,7 +18,14 @@ package com.android.systemui.biometrics.data.repository
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
+import android.hardware.display.DisplayManager
+import android.hardware.display.DisplayManager.DisplayListener
+import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
+import android.os.Handler
+import android.view.DisplayInfo
import com.android.internal.util.ArrayUtils
+import com.android.systemui.biometrics.shared.model.DisplayRotation
+import com.android.systemui.biometrics.shared.model.toDisplayRotation
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
@@ -32,21 +39,26 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
-/** Provide current rear display state. */
-interface RearDisplayStateRepository {
+/** Repository for the current state of the display */
+interface DisplayStateRepository {
/** Provides the current rear display state. */
val isInRearDisplayMode: StateFlow<Boolean>
+
+ /** Provides the current display rotation */
+ val currentRotation: StateFlow<DisplayRotation>
}
@SysUISingleton
-class RearDisplayStateRepositoryImpl
+class DisplayStateRepositoryImpl
@Inject
constructor(
@Application applicationScope: CoroutineScope,
- @Application context: Context,
+ @Application val context: Context,
deviceStateManager: DeviceStateManager,
+ displayManager: DisplayManager,
+ @Main handler: Handler,
@Main mainExecutor: Executor
-) : RearDisplayStateRepository {
+) : DisplayStateRepository {
override val isInRearDisplayMode: StateFlow<Boolean> =
conflatedCallbackFlow {
val sendRearDisplayStateUpdate = { state: Boolean ->
@@ -79,7 +91,43 @@ constructor(
initialValue = false,
)
+ private fun getDisplayRotation(): DisplayRotation {
+ val cachedDisplayInfo = DisplayInfo()
+ context.display?.getDisplayInfo(cachedDisplayInfo)
+ return cachedDisplayInfo.rotation.toDisplayRotation()
+ }
+
+ override val currentRotation: StateFlow<DisplayRotation> =
+ conflatedCallbackFlow {
+ val callback =
+ object : DisplayListener {
+ override fun onDisplayRemoved(displayId: Int) {}
+
+ override fun onDisplayAdded(displayId: Int) {}
+
+ override fun onDisplayChanged(displayId: Int) {
+ val rotation = getDisplayRotation()
+ trySendWithFailureLogging(
+ rotation,
+ TAG,
+ "Error sending display rotation to $rotation"
+ )
+ }
+ }
+ displayManager.registerDisplayListener(
+ callback,
+ handler,
+ EVENT_FLAG_DISPLAY_CHANGED
+ )
+ awaitClose { displayManager.unregisterDisplayListener(callback) }
+ }
+ .stateIn(
+ applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = getDisplayRotation(),
+ )
+
companion object {
- const val TAG = "RearDisplayStateRepositoryImpl"
+ const val TAG = "DisplayStateRepositoryImpl"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
index 2e734a315194..f36a3ec89e3f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
@@ -19,7 +19,8 @@ package com.android.systemui.biometrics.domain.interactor
import android.content.Context
import android.content.res.Configuration
import android.view.Display
-import com.android.systemui.biometrics.data.repository.RearDisplayStateRepository
+import com.android.systemui.biometrics.data.repository.DisplayStateRepository
+import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application
@@ -50,6 +51,9 @@ interface DisplayStateInteractor {
/** Whether the device is currently folded. */
val isFolded: Flow<Boolean>
+ /** Current rotation of the display */
+ val currentRotation: StateFlow<DisplayRotation>
+
/** Called on configuration changes, used to keep the display state in sync */
fun onConfigurationChanged(newConfig: Configuration)
}
@@ -61,7 +65,7 @@ constructor(
@Application applicationScope: CoroutineScope,
@Application context: Context,
@Main mainExecutor: Executor,
- rearDisplayStateRepository: RearDisplayStateRepository,
+ displayStateRepository: DisplayStateRepository,
displayRepository: DisplayRepository,
) : DisplayStateInteractor {
private var screenSizeFoldProvider: ScreenSizeFoldProvider = ScreenSizeFoldProvider(context)
@@ -98,7 +102,10 @@ constructor(
)
override val isInRearDisplayMode: StateFlow<Boolean> =
- rearDisplayStateRepository.isInRearDisplayMode
+ displayStateRepository.isInRearDisplayMode
+
+ override val currentRotation: StateFlow<DisplayRotation> =
+ displayStateRepository.currentRotation
override fun onConfigurationChanged(newConfig: Configuration) {
screenSizeFoldProvider.onConfigurationChange(newConfig)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/DisplayRotation.kt b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/DisplayRotation.kt
new file mode 100644
index 000000000000..10a3e915fe80
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/DisplayRotation.kt
@@ -0,0 +1,21 @@
+package com.android.systemui.biometrics.shared.model
+
+import android.view.Surface
+
+/** Shadows [Surface.Rotation] for kotlin use within SysUI. */
+enum class DisplayRotation {
+ ROTATION_0,
+ ROTATION_90,
+ ROTATION_180,
+ ROTATION_270,
+}
+
+/** Converts [Surface.Rotation] to corresponding [DisplayRotation] */
+fun Int.toDisplayRotation(): DisplayRotation =
+ when (this) {
+ Surface.ROTATION_0 -> DisplayRotation.ROTATION_0
+ Surface.ROTATION_90 -> DisplayRotation.ROTATION_90
+ Surface.ROTATION_180 -> DisplayRotation.ROTATION_180
+ Surface.ROTATION_270 -> DisplayRotation.ROTATION_270
+ else -> throw IllegalArgumentException("Invalid DisplayRotation value: $this")
+ }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index d616dcca338f..02847c283738 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -252,6 +252,18 @@ object BiometricViewBinder {
}
}
+ // set padding
+ launch {
+ viewModel.promptPadding.collect { promptPadding ->
+ view.setPadding(
+ promptPadding.left,
+ promptPadding.top,
+ promptPadding.right,
+ promptPadding.bottom
+ )
+ }
+ }
+
// configure & hide/disable buttons
launch {
viewModel.credentialKind
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 6269700d5419..267afae118e6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -15,16 +15,21 @@
*/
package com.android.systemui.biometrics.ui.viewmodel
+import android.content.Context
+import android.graphics.Rect
import android.hardware.biometrics.BiometricPrompt
import android.util.Log
import android.view.HapticFeedbackConstants
import android.view.MotionEvent
+import com.android.systemui.biometrics.Utils
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
import com.android.systemui.biometrics.shared.model.BiometricModalities
import com.android.systemui.biometrics.shared.model.BiometricModality
+import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.PromptKind
import com.android.systemui.biometrics.ui.binder.Spaghetti
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
import com.android.systemui.statusbar.VibratorHelper
@@ -49,6 +54,7 @@ constructor(
private val displayStateInteractor: DisplayStateInteractor,
private val promptSelectorInteractor: PromptSelectorInteractor,
private val vibrator: VibratorHelper,
+ @Application context: Context,
private val featureFlags: FeatureFlags,
) {
/** Models UI of [BiometricPromptLayout.iconView] */
@@ -135,6 +141,23 @@ constructor(
!isOverlayTouched && size.isNotSmall
}
+ /** Padding for prompt UI elements */
+ val promptPadding: Flow<Rect> =
+ combine(size, displayStateInteractor.currentRotation) { size, rotation ->
+ if (size != PromptSize.LARGE) {
+ val navBarInsets = Utils.getNavbarInsets(context)
+ if (rotation == DisplayRotation.ROTATION_90) {
+ Rect(0, 0, navBarInsets.right, 0)
+ } else if (rotation == DisplayRotation.ROTATION_270) {
+ Rect(navBarInsets.left, 0, 0, 0)
+ } else {
+ Rect(0, 0, 0, navBarInsets.bottom)
+ }
+ } else {
+ Rect(0, 0, 0, 0)
+ }
+ }
+
/** Title for the prompt. */
val title: Flow<String> =
promptSelectorInteractor.prompt.map { it?.title ?: "" }.distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
index 364b5e78a9b0..1985c37e1d5d 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -129,7 +129,12 @@ class PatternBouncerViewModel(
buildList {
var dot = previousDot
while (dot != hitDot) {
- add(dot)
+ // Move along the direction of the line connecting the previously
+ // selected dot and current hit dot, and see if they were skipped over
+ // but fall on that line.
+ if (dot.isOnLineSegment(previousDot, hitDot)) {
+ add(dot)
+ }
dot =
PatternDotViewModel(
x =
@@ -208,6 +213,34 @@ class PatternBouncerViewModel(
}
}
+/**
+ * Determines whether [this] dot is present on the line segment connecting [first] and [second]
+ * dots.
+ */
+private fun PatternDotViewModel.isOnLineSegment(
+ first: PatternDotViewModel,
+ second: PatternDotViewModel
+): Boolean {
+ val anotherPoint = this
+ // No need to consider any points outside the bounds of two end points
+ val isWithinBounds =
+ anotherPoint.x.isBetween(first.x, second.x) && anotherPoint.y.isBetween(first.y, second.y)
+ if (!isWithinBounds) {
+ return false
+ }
+
+ // Uses the 2 point line equation: (y-y1)/(x-x1) = (y2-y1)/(x2-x1)
+ // which can be rewritten as: (y-y1)*(x2-x1) = (x-x1)*(y2-y1)
+ // This is true for any point on the line passing through these two points
+ return (anotherPoint.y - first.y) * (second.x - first.x) ==
+ (anotherPoint.x - first.x) * (second.y - first.y)
+}
+
+/** Is [this] Int between [a] and [b] */
+private fun Int.isBetween(a: Int, b: Int): Boolean {
+ return (this in a..b) || (this in b..a)
+}
+
data class PatternDotViewModel(
val x: Int,
val y: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 7ee0ff4568be..3a942bd8203f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -37,7 +37,6 @@ import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
import com.android.systemui.biometrics.dagger.BiometricsModule;
-import com.android.systemui.biometrics.dagger.UdfpsModule;
import com.android.systemui.bouncer.ui.BouncerViewModule;
import com.android.systemui.classifier.FalsingModule;
import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule;
@@ -207,7 +206,6 @@ import javax.inject.Named;
TelephonyRepositoryModule.class,
TemporaryDisplayModule.class,
TunerModule.class,
- UdfpsModule.class,
UserModule.class,
UtilModule.class,
NoteTaskModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 7e8f68225070..be28ded638a5 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -107,7 +107,7 @@ object Flags {
// TODO(b/268005230): Tracking Bug
@JvmField
- val SENSITIVE_REVEAL_ANIM = unreleasedFlag("sensitive_reveal_anim", teamfood = true)
+ val SENSITIVE_REVEAL_ANIM = releasedFlag("sensitive_reveal_anim")
// TODO(b/280783617): Tracking Bug
@Keep
@@ -115,7 +115,7 @@ object Flags {
val BUILDER_EXTRAS_OVERRIDE =
sysPropBooleanFlag(
"persist.sysui.notification.builder_extras_override",
- default = false
+ default = true
)
/** Only notify group expansion listeners when a change happens. */
@@ -662,7 +662,6 @@ object Flags {
// 2200 - biometrics (udfps, sfps, BiometricPrompt, etc.)
// TODO(b/259264861): Tracking Bug
@JvmField val UDFPS_NEW_TOUCH_DETECTION = releasedFlag("udfps_new_touch_detection")
- @JvmField val UDFPS_ELLIPSE_DETECTION = releasedFlag("udfps_ellipse_detection")
// 2300 - stylus
@JvmField val TRACK_STYLUS_EVER_USED = releasedFlag("track_stylus_ever_used")
@@ -774,7 +773,8 @@ object Flags {
// TODO(b/290213663): Tracking Bug
@JvmField
- val ONE_WAY_HAPTICS_API_MIGRATION = unreleasedFlag("oneway_haptics_api_migration")
+ val ONE_WAY_HAPTICS_API_MIGRATION =
+ unreleasedFlag("oneway_haptics_api_migration", teamfood = true)
/** TODO(b/296223317): Enables the new keyguard presentation containing a clock. */
@JvmField
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 2b4dc8108418..991572003e4d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2208,14 +2208,21 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// we explicitly re-set state.
if (mShowing && mKeyguardStateController.isShowing()) {
if (mPM.isInteractive() && !mHiding) {
- // It's already showing, and we're not trying to show it while the screen is off.
- // We can simply reset all of the views, but don't hide the bouncer in case the user
- // is currently interacting with it.
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing (instead, resetting) because it is "
- + "already showing, we're interactive, and we were not previously hiding. "
- + "It should be safe to short-circuit here.");
- resetStateLocked(/* hideBouncer= */ false);
- return;
+ if (mKeyguardStateController.isKeyguardGoingAway()) {
+ Log.e(TAG, "doKeyguard: we're still showing, but going away. Re-show the "
+ + "keyguard rather than short-circuiting and resetting.");
+ } else {
+ // It's already showing, and we're not trying to show it while the screen is
+ // off. We can simply reset all of the views, but don't hide the bouncer in case
+ // the user is currently interacting with it.
+ if (DEBUG) Log.d(TAG,
+ "doKeyguard: not showing (instead, resetting) because it is "
+ + "already showing, we're interactive, we were not "
+ + "previously hiding. It should be safe to short-circuit "
+ + "here.");
+ resetStateLocked(/* hideBouncer= */ false);
+ return;
+ }
} else {
// We are trying to show the keyguard while the screen is off or while we were in
// the middle of hiding - this results from race conditions involving locking while
@@ -2740,13 +2747,18 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
setUnlockAndWakeFromDream(false, WakeAndUnlockUpdateReason.SHOW);
setPendingLock(false);
- // Force if we we're showing in the middle of hiding, to ensure we end up in the correct
- // state.
- setShowingLocked(true, mHiding /* force */);
- if (mHiding) {
- Log.d(TAG, "Forcing setShowingLocked because mHiding=true, which means we're "
- + "showing in the middle of hiding.");
+ final boolean hidingOrGoingAway =
+ mHiding || mKeyguardStateController.isKeyguardGoingAway();
+ if (hidingOrGoingAway) {
+ Log.d(TAG, "Forcing setShowingLocked because one of these is true:"
+ + "mHiding=" + mHiding
+ + ", keyguardGoingAway=" + mKeyguardStateController.isKeyguardGoingAway()
+ + ", which means we're showing in the middle of hiding.");
}
+
+ // Force if we we're showing in the middle of unlocking, to ensure we end up in the
+ // correct state.
+ setShowingLocked(true, hidingOrGoingAway /* force */);
mHiding = false;
if (!mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
@@ -2954,7 +2966,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
+ " fadeoutDuration=" + fadeoutDuration);
synchronized (KeyguardViewMediator.this) {
-
// Tell ActivityManager that we canceled the keyguard animation if
// handleStartKeyguardExitAnimation was called, but we're not hiding the keyguard,
// unless we're animating the surface behind the keyguard and will be hiding the
@@ -3222,10 +3233,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// Post layout changes to the next frame, so we don't hang at the end of the animation.
DejankUtils.postAfterTraversal(() -> {
- if (!mPM.isInteractive()) {
- Log.e(TAG, "exitKeyguardAndFinishSurfaceBehindRemoteAnimation#postAfterTraversal" +
- "Not interactive after traversal. Don't hide the keyguard. This means we " +
- "re-locked the device during unlock.");
+ if (!mPM.isInteractive() && !mPendingLock) {
+ Log.e(TAG, "exitKeyguardAndFinishSurfaceBehindRemoteAnimation#postAfterTraversal:"
+ + "mPM.isInteractive()=" + mPM.isInteractive()
+ + "mPendingLock=" + mPendingLock + "."
+ + "One of these being false means we re-locked the device during unlock. "
+ + "Do not proceed to finish keyguard exit and unlock.");
+ finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 44acf4f0fd2d..a9c71adc095d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -79,12 +79,6 @@ object KeyguardBottomAreaViewBinder {
//If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt]
@Deprecated("Deprecated as part of b/278057014")
interface Binding {
- /**
- * Returns a collection of [ViewPropertyAnimator] instances that can be used to animate the
- * indication areas.
- */
- fun getIndicationAreaAnimators(): List<ViewPropertyAnimator>
-
/** Notifies that device configuration has changed. */
fun onConfigurationChanged()
@@ -281,10 +275,6 @@ object KeyguardBottomAreaViewBinder {
}
return object : Binding {
- override fun getIndicationAreaAnimators(): List<ViewPropertyAnimator> {
- return listOf(ambientIndicationArea).mapNotNull { it?.animate() }
- }
-
override fun onConfigurationChanged() {
configurationBasedDimensions.value = loadFromResources(view)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
index 9c6e953ad2d5..100099d3988e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
@@ -73,7 +73,13 @@ constructor(
val mBottomPaddingPx =
context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom)
val bounds = windowManager.currentWindowMetrics.bounds
- val widthPixels = bounds.right.toFloat()
+ val insets = windowManager.currentWindowMetrics.windowInsets
+ var widthPixels = bounds.right.toFloat()
+ if (featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE)) {
+ // Assumed to be initially neglected as there are no left or right insets in portrait.
+ // However, on landscape, these insets need to included when calculating the midpoint.
+ widthPixels -= (insets.systemWindowInsetLeft + insets.systemWindowInsetRight).toFloat()
+ }
val heightPixels = bounds.bottom.toFloat()
val defaultDensity =
DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() /
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
index b1dd373a7657..c7b0cb995acc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
@@ -39,7 +39,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.media.controls.ui.KeyguardMediaController
import com.android.systemui.shade.NotificationPanelView
import com.android.systemui.shade.NotificationPanelViewController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.Utils
import dagger.Lazy
import javax.inject.Inject
@@ -55,6 +55,7 @@ constructor(
private val keyguardViewConfigurator: Lazy<KeyguardViewConfigurator>,
private val notificationPanelViewController: Lazy<NotificationPanelViewController>,
private val keyguardMediaController: KeyguardMediaController,
+ private val splitShadeStateController: SplitShadeStateController
) : KeyguardSection() {
private val statusViewId = R.id.keyguard_status_view
@@ -104,7 +105,7 @@ constructor(
connect(statusViewId, END, PARENT_ID, END)
val margin =
- if (LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)) {
+ if (splitShadeStateController.shouldUseSplitNotificationShade(context.resources)) {
context.resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)
} else {
context.resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index dddbedac3dcc..e79fc74ffc86 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -22,12 +22,14 @@ import android.app.Notification
import android.app.Notification.EXTRA_SUBSTITUTE_APP_NAME
import android.app.PendingIntent
import android.app.StatusBarManager
+import android.app.UriGrantsManager
import android.app.smartspace.SmartspaceAction
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
import android.app.smartspace.SmartspaceSession
import android.app.smartspace.SmartspaceTarget
import android.content.BroadcastReceiver
+import android.content.ContentProvider
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
@@ -700,10 +702,13 @@ class MediaDataManager(
Log.d(TAG, "adding track for $userId from browser: $desc")
}
+ val currentEntry = mediaEntries.get(packageName)
+ val appUid = currentEntry?.appUid ?: Process.INVALID_UID
+
// Album art
var artworkBitmap = desc.iconBitmap
if (artworkBitmap == null && desc.iconUri != null) {
- artworkBitmap = loadBitmapFromUri(desc.iconUri!!)
+ artworkBitmap = loadBitmapFromUriForUser(desc.iconUri!!, userId, appUid, packageName)
}
val artworkIcon =
if (artworkBitmap != null) {
@@ -712,9 +717,7 @@ class MediaDataManager(
null
}
- val currentEntry = mediaEntries.get(packageName)
val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
- val appUid = currentEntry?.appUid ?: Process.INVALID_UID
val isExplicit =
desc.extras?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
@@ -1261,6 +1264,30 @@ class MediaDataManager(
false
}
}
+
+ /** Returns a bitmap if the user can access the given URI, else null */
+ private fun loadBitmapFromUriForUser(
+ uri: Uri,
+ userId: Int,
+ appUid: Int,
+ packageName: String,
+ ): Bitmap? {
+ try {
+ val ugm = UriGrantsManager.getService()
+ ugm.checkGrantUriPermission_ignoreNonSystem(
+ appUid,
+ packageName,
+ ContentProvider.getUriWithoutUserId(uri),
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ ContentProvider.getUserIdFromUri(uri, userId)
+ )
+ return loadBitmapFromUri(uri)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "Failed to get URI permission: $e")
+ }
+ return null
+ }
+
/**
* Load a bitmap from a URI
*
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt
index 2883210805d3..83a6e58cc444 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt
@@ -35,7 +35,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.MediaContainerView
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject
import javax.inject.Named
@@ -55,6 +55,7 @@ constructor(
private val secureSettings: SecureSettings,
@Main private val handler: Handler,
configurationController: ConfigurationController,
+ private val splitShadeStateController: SplitShadeStateController
) {
init {
@@ -108,7 +109,7 @@ constructor(
}
private fun updateResources() {
- useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ useSplitShade = splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index c1c757e424dc..0b30e597ab1c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -52,7 +52,7 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.traceSection
@@ -101,6 +101,7 @@ constructor(
panelEventsEvents: ShadeStateEvents,
private val secureSettings: SecureSettings,
@Main private val handler: Handler,
+ private val splitShadeStateController: SplitShadeStateController
) {
/** Track the media player setting status on lock screen. */
@@ -568,7 +569,7 @@ constructor(
context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_media_transition_distance
)
- inSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ inSplitShade = splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
index 5d732fb8ace9..cbb7e1d0ef83 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
@@ -17,6 +17,7 @@
package com.android.systemui.mediaprojection.appselector.view
import android.app.ActivityOptions
+import android.app.ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
import android.app.IActivityTaskManager
import android.graphics.Rect
import android.os.Binder
@@ -129,6 +130,9 @@ constructor(
view.width,
view.height
)
+ activityOptions.setPendingIntentBackgroundActivityStartMode(
+ MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
activityOptions.launchCookie = launchCookie
activityTaskManager.startActivityFromRecents(task.taskId, activityOptions.toBundle())
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 146b5f57630e..79e7b710c56e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -359,6 +359,7 @@ public class NavigationBarView extends FrameLayout {
public void setBackgroundExecutor(Executor bgExecutor) {
mBgExecutor = bgExecutor;
+ mRotationButtonController.setBgExecutor(bgExecutor);
}
public void setDisplayTracker(DisplayTracker displayTracker) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 856a92e85ad7..9359958397d1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -39,6 +39,7 @@ import com.android.systemui.settings.brightness.BrightnessMirrorHandler;
import com.android.systemui.settings.brightness.BrightnessSliderController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.tuner.TunerService;
import javax.inject.Inject;
@@ -80,9 +81,10 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory,
BrightnessSliderController.Factory brightnessSliderFactory,
FalsingManager falsingManager,
- StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+ SplitShadeStateController splitShadeStateController) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost,
- metricsLogger, uiEventLogger, qsLogger, dumpManager);
+ metricsLogger, uiEventLogger, qsLogger, dumpManager, splitShadeStateController);
mTunerService = tunerService;
mQsCustomizerController = qsCustomizerController;
mQsTileRevealControllerFactory = qsTileRevealControllerFactory;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 20f035260ba4..81e3a2f68bfd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -40,7 +40,7 @@ import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileViewImpl;
-import com.android.systemui.util.LargeScreenUtils;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.animation.DisappearParameters;
@@ -86,6 +86,8 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
private final QSHost.Callback mQSHostCallback = this::setTiles;
+ private SplitShadeStateController mSplitShadeStateController;
+
@VisibleForTesting
protected final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
new QSPanel.OnConfigurationChangedListener() {
@@ -93,8 +95,8 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
public void onConfigurationChange(Configuration newConfig) {
final boolean previousSplitShadeState = mShouldUseSplitNotificationShade;
final int previousOrientation = mLastOrientation;
- mShouldUseSplitNotificationShade =
- LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
+ mShouldUseSplitNotificationShade = mSplitShadeStateController
+ .shouldUseSplitNotificationShade(getResources());
mLastOrientation = newConfig.orientation;
mQSLogger.logOnConfigurationChanged(
@@ -138,7 +140,8 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
MetricsLogger metricsLogger,
UiEventLogger uiEventLogger,
QSLogger qsLogger,
- DumpManager dumpManager
+ DumpManager dumpManager,
+ SplitShadeStateController splitShadeStateController
) {
super(view);
mHost = host;
@@ -149,8 +152,9 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
mUiEventLogger = uiEventLogger;
mQSLogger = qsLogger;
mDumpManager = dumpManager;
+ mSplitShadeStateController = splitShadeStateController;
mShouldUseSplitNotificationShade =
- LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
+ mSplitShadeStateController.shouldUseSplitNotificationShade(getResources());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 2d543139a1b4..585136ad0789 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -32,6 +32,7 @@ import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.leak.RotationUtils;
import java.util.ArrayList;
@@ -55,10 +56,10 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
@Named(QS_USING_COLLAPSED_LANDSCAPE_MEDIA)
Provider<Boolean> usingCollapsedLandscapeMediaProvider,
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
- DumpManager dumpManager
+ DumpManager dumpManager, SplitShadeStateController splitShadeStateController
) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
- uiEventLogger, qsLogger, dumpManager);
+ uiEventLogger, qsLogger, dumpManager, splitShadeStateController);
mUsingCollapsedLandscapeMediaProvider = usingCollapsedLandscapeMediaProvider;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
new file mode 100644
index 000000000000..1a03481b9fca
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
@@ -0,0 +1,26 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Provides data and availability for the tile. In most cases it would delegate data retrieval to
+ * repository, manager, controller or a combination of those. Avoid doing long running operations in
+ * these methods because there is no background thread guarantee. Use [Flow.flowOn] (typically
+ * with @Background [CoroutineDispatcher]) instead to move the calculations to another thread.
+ */
+interface QSTileDataInteractor<DATA_TYPE> {
+
+ /**
+ * Returns the data to be mapped to [QSTileState]. Make sure to start the flow [Flow.onStart]
+ * with the current state to update the tile as soon as possible.
+ */
+ fun tileData(qsTileDataRequest: QSTileDataRequest): Flow<DATA_TYPE>
+
+ /**
+ * Returns tile availability - whether this device currently supports this tile. Make sure to
+ * start the flow [Flow.onStart] with the current state to update the tile as soon as possible.
+ */
+ fun availability(): Flow<Boolean>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt
new file mode 100644
index 000000000000..82897044f06c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+data class QSTileDataRequest(
+ val userId: Int,
+ val trigger: StateUpdateTrigger,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
new file mode 100644
index 000000000000..8569fc73adb4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
@@ -0,0 +1,13 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import android.annotation.WorkerThread
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+
+interface QSTileUserActionInteractor<DATA_TYPE> {
+
+ /**
+ * Processes user input based on [userAction] and [currentData]. It's safe to run long running
+ * computations inside this function in this.
+ */
+ @WorkerThread suspend fun handleInput(userAction: QSTileUserAction, currentData: DATA_TYPE)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt
new file mode 100644
index 000000000000..ed7ec8e32de4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt
@@ -0,0 +1,11 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+
+sealed interface StateUpdateTrigger {
+ class UserAction<T>(val action: QSTileUserAction, val tileState: QSTileState, val tileData: T) :
+ StateUpdateTrigger
+ data object ForceUpdate : StateUpdateTrigger
+ data object InitialRequest : StateUpdateTrigger
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
new file mode 100644
index 000000000000..a5eaac154230
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
@@ -0,0 +1,14 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.graphics.drawable.Icon
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+data class QSTileConfig(
+ val tileSpec: TileSpec,
+ val tileIcon: Icon,
+ val tileLabel: CharSequence,
+// TODO(b/299908705): Fill necessary params
+/*
+val instanceId: InstanceId,
+ */
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt
new file mode 100644
index 000000000000..39db7038bfa2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+enum class QSTileLifecycle {
+ ON_CREATE,
+ ON_DESTROY,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
new file mode 100644
index 000000000000..53f9edfb954c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -0,0 +1,18 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.graphics.drawable.Icon
+
+data class QSTileState(
+ val icon: Icon,
+ val label: CharSequence,
+// TODO(b/299908705): Fill necessary params
+/*
+ val subtitle: CharSequence = "",
+ val activeState: ActivationState = Active,
+ val enabledState: Enabled = Enabled,
+ val loopIconAnimation: Boolean = false,
+ val secondaryIcon: Icon? = null,
+ val slashState: SlashState? = null,
+ val supportedActions: Collection<UserAction> = listOf(Click), clicks should be a default action
+*/
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
new file mode 100644
index 000000000000..f1f8f0152c67
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
@@ -0,0 +1,13 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.content.Context
+import android.view.View
+
+sealed interface QSTileUserAction {
+
+ val context: Context
+ val view: View?
+
+ class Click(override val context: Context, override val view: View?) : QSTileUserAction
+ class LongClick(override val context: Context, override val view: View?) : QSTileUserAction
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
new file mode 100644
index 000000000000..49077f3f310d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
@@ -0,0 +1,41 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * Represents tiles behaviour logic. This ViewModel is a connection between tile view and data
+ * layers.
+ */
+interface QSTileViewModel {
+
+ /**
+ * State of the tile to be shown by the view. Favor reactive consumption over the
+ * [StateFlow.value], because there is no guarantee that current value would be available at any
+ * time.
+ */
+ val state: StateFlow<QSTileState>
+
+ val config: QSTileConfig
+
+ val isAvailable: Flow<Boolean>
+
+ /**
+ * Handles ViewModel lifecycle. Implementations should be inactive outside of
+ * [QSTileLifecycle.ON_CREATE] and [QSTileLifecycle.ON_DESTROY] bounds.
+ */
+ fun onLifecycle(lifecycle: QSTileLifecycle)
+
+ /**
+ * Notifies about the user change. Implementations should avoid using 3rd party userId sources
+ * and use this value instead. This is to maintain consistent and concurrency-free behaviour
+ * across different parts of QS.
+ */
+ fun onUserIdChanged(userId: Int)
+
+ /** Triggers emit of the new [QSTileState] in [state]. */
+ fun forceUpdate()
+
+ /** Notifies underlying logic about user input. */
+ fun onActionPerformed(userAction: QSTileUserAction)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 49ce832c1e8c..a5b46e2df462 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -141,7 +141,6 @@ import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.shared.model.WakefulnessModel;
import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder;
-import com.android.systemui.keyguard.ui.view.KeyguardRootView;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
@@ -223,10 +222,10 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.Compile;
-import com.android.systemui.util.LargeScreenUtils;
import com.android.systemui.util.Utils;
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -236,7 +235,6 @@ import kotlin.Unit;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
@@ -320,7 +318,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
private final LayoutInflater mLayoutInflater;
private final FeatureFlags mFeatureFlags;
- private final PowerManager mPowerManager;
private final AccessibilityManager mAccessibilityManager;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final PulseExpansionHandler mPulseExpansionHandler;
@@ -357,7 +354,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final AccessibilityDelegate mAccessibilityDelegate = new ShadeAccessibilityDelegate();
private final NotificationGutsManager mGutsManager;
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
- private final KeyguardRootView mKeyguardRootView;
private final QuickSettingsController mQsController;
private final TouchHandler mTouchHandler = new TouchHandler();
@@ -370,8 +366,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private float mExpandedHeight = 0;
/** The current squish amount for the predictive back animation */
private float mCurrentBackProgress = 0.0f;
- private boolean mTracking;
- private boolean mHintAnimationRunning;
@Deprecated
private KeyguardBottomAreaView mKeyguardBottomArea;
private boolean mExpanding;
@@ -622,7 +616,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private int mLockscreenToDreamingTransitionTranslationY;
private int mGoneToDreamingTransitionTranslationY;
private int mLockscreenToOccludedTransitionTranslationY;
-
+ private SplitShadeStateController mSplitShadeStateController;
private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */);
private final Runnable mAnimateKeyguardBottomAreaInvisibleEndRunnable =
@@ -781,7 +775,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
SharedNotificationContainerInteractor sharedNotificationContainerInteractor,
KeyguardViewConfigurator keyguardViewConfigurator,
KeyguardFaceAuthInteractor keyguardFaceAuthInteractor,
- KeyguardRootView keyguardRootView) {
+ SplitShadeStateController splitShadeStateController) {
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardFadingAwayChanged() {
@@ -877,8 +871,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mFragmentService = fragmentService;
mStatusBarService = statusBarService;
mSettingsChangeObserver = new SettingsChangeObserver(handler);
+ mSplitShadeStateController = splitShadeStateController;
mSplitShadeEnabled =
- LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
+ mSplitShadeStateController.shouldUseSplitNotificationShade(mResources);
mView.setWillNotDraw(!DEBUG_DRAWABLE);
mShadeHeaderController = shadeHeaderController;
mLayoutInflater = layoutInflater;
@@ -886,7 +881,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mAnimateBack = mFeatureFlags.isEnabled(Flags.WM_SHADE_ANIMATE_BACK_GESTURE);
mTrackpadGestureFeaturesEnabled = mFeatureFlags.isEnabled(Flags.TRACKPAD_GESTURE_FEATURES);
mFalsingCollector = falsingCollector;
- mPowerManager = powerManager;
mWakeUpCoordinator = coordinator;
mMainDispatcher = mainDispatcher;
mAccessibilityManager = accessibilityManager;
@@ -987,7 +981,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
});
mAlternateBouncerInteractor = alternateBouncerInteractor;
- mKeyguardRootView = keyguardRootView;
dumpManager.registerDumpable(this);
}
@@ -1006,7 +999,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
// cause blurring. This will eventually be re-enabled by the panel view on
// ACTION_UP, since the user's finger might still be down after a swipe to
// unlock gesture, and we don't want that to cause blurring either.
- mDepthController.setBlursDisabledForUnlock(mTracking);
+ mDepthController.setBlursDisabledForUnlock(isTracking());
if (playingCannedAnimation && !isWakeAndUnlockNotFromDream) {
// Hide the panel so it's not in the way or the surface behind the
@@ -1300,7 +1293,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
@Override
public void updateResources() {
final boolean newSplitShadeEnabled =
- LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
+ mSplitShadeStateController.shouldUseSplitNotificationShade(mResources);
final boolean splitShadeChanged = mSplitShadeEnabled != newSplitShadeEnabled;
mSplitShadeEnabled = newSplitShadeEnabled;
mQsController.updateResources();
@@ -1519,7 +1512,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
private boolean shouldAvoidChangingNotificationsCount() {
- return mHintAnimationRunning || mUnlockedScreenOffAnimationController.isAnimationPlaying();
+ return mUnlockedScreenOffAnimationController.isAnimationPlaying();
}
@Deprecated
@@ -1849,6 +1842,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
/** Returns extra space available to show the shelf on lockscreen */
@VisibleForTesting
float getVerticalSpaceForLockscreenShelf() {
+ if (mSplitShadeEnabled) {
+ return 0f;
+ }
final float lockIconPadding = getLockIconPadding();
final float noShelfOverlapBottomPadding =
@@ -2549,10 +2545,10 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void onHeightUpdated(float expandedHeight) {
if (expandedHeight <= 0) {
mShadeLog.logExpansionChanged("onHeightUpdated: fully collapsed.",
- mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
+ mExpandedFraction, isExpanded(), isTracking(), mExpansionDragDownAmountPx);
} else if (isFullyExpanded()) {
mShadeLog.logExpansionChanged("onHeightUpdated: fully expanded.",
- mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
+ mExpandedFraction, isExpanded(), isTracking(), mExpansionDragDownAmountPx);
}
if (!mQsController.getExpanded() || mQsController.isExpandImmediate()
|| mIsExpandingOrCollapsing && mQsController.getExpandedWhenExpandingStarted()) {
@@ -2645,7 +2641,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
&& !mHeadsUpManager.hasPinnedHeadsUp()) {
alpha = getFadeoutAlpha();
}
- if (mBarState == KEYGUARD && !mHintAnimationRunning
+ if (mBarState == KEYGUARD
&& !mKeyguardBypassController.getBypassEnabled()
&& !mQsController.getFullyExpanded()) {
alpha *= mClockPositionResult.clockAlpha;
@@ -2683,7 +2679,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
// change due to "unlock hint animation." In this case, fading out the bottom area
// would also hide the message that says "swipe to unlock," we don't want to do that.
float expansionAlpha = MathUtils.constrainedMap(0f, 1f,
- isUnlockHintRunning() ? 0f : KeyguardBouncerConstants.ALPHA_EXPANSION_THRESHOLD, 1f,
+ KeyguardBouncerConstants.ALPHA_EXPANSION_THRESHOLD, 1f,
getExpandedFraction());
float alpha = Math.min(expansionAlpha, 1 - mQsController.computeExpansionFraction());
@@ -2745,7 +2741,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mAnimateAfterExpanding = animate;
mUpdateFlingOnLayout = false;
abortAnimations();
- if (mTracking) {
+ if (isTracking()) {
// The panel is expanded after this call.
onTrackingStopped(true /* expands */);
}
@@ -2832,7 +2828,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void onTrackingStarted() {
endClosing();
- mTracking = true;
+ mShadeRepository.setLegacyShadeTracking(true);
mTrackingStartedListener.onTrackingStarted();
notifyExpandingStarted();
updateExpansionAndVisibility();
@@ -2846,7 +2842,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
private void onTrackingStopped(boolean expand) {
- mTracking = false;
+ mShadeRepository.setLegacyShadeTracking(false);
updateExpansionAndVisibility();
if (expand) {
@@ -2865,44 +2861,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mView.getHeight(), mNavigationBarBottomHeight);
}
- @VisibleForTesting
- void startUnlockHintAnimation() {
- if (mPowerManager.isPowerSaveMode() || mAmbientState.getDozeAmount() > 0f) {
- onUnlockHintStarted();
- onUnlockHintFinished();
- return;
- }
-
- // We don't need to hint the user if an animation is already running or the user is changing
- // the expansion.
- if (mHeightAnimator != null || mTracking) {
- return;
- }
- notifyExpandingStarted();
- startUnlockHintAnimationPhase1(() -> {
- notifyExpandingFinished();
- onUnlockHintFinished();
- mHintAnimationRunning = false;
- });
- onUnlockHintStarted();
- mHintAnimationRunning = true;
- }
-
- @VisibleForTesting
- void onUnlockHintFinished() {
- // Delay the reset a bit so the user can read the text.
- mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
- mScrimController.setExpansionAffectsAlpha(true);
- mNotificationStackScrollLayoutController.setUnlockHintRunning(false);
- }
-
- @VisibleForTesting
- void onUnlockHintStarted() {
- mKeyguardIndicationController.showActionToUnlock();
- mScrimController.setExpansionAffectsAlpha(false);
- mNotificationStackScrollLayoutController.setUnlockHintRunning(true);
- }
-
private boolean shouldUseDismissingAnimation() {
return mBarState != StatusBarState.SHADE && (mKeyguardStateController.canDismissLockScreen()
|| !isTracking());
@@ -2989,7 +2947,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
mLockscreenGestureLogger
.log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT);
- startUnlockHintAnimation();
+ mKeyguardIndicationController.showActionToUnlock();
}
}
break;
@@ -3056,7 +3014,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
private void updateExpandedHeight(float expandedHeight) {
- if (mTracking) {
+ if (isTracking()) {
mNotificationStackScrollLayoutController
.setExpandingVelocity(getCurrentExpandVelocity());
}
@@ -3145,7 +3103,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mTouchDisabled = disabled;
if (mTouchDisabled) {
cancelHeightAnimator();
- if (mTracking) {
+ if (isTracking()) {
onTrackingStopped(true /* expanded */);
}
notifyExpandingFinished();
@@ -3384,7 +3342,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
@Override
public void blockExpansionForCurrentTouch() {
- mBlockingExpansionForCurrentTouch = mTracking;
+ mBlockingExpansionForCurrentTouch = isTracking();
}
@Override
@@ -3398,8 +3356,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
ipw.print("mIsLaunchAnimationRunning="); ipw.println(mIsLaunchAnimationRunning);
ipw.print("mOverExpansion="); ipw.println(mOverExpansion);
ipw.print("mExpandedHeight="); ipw.println(mExpandedHeight);
- ipw.print("mTracking="); ipw.println(mTracking);
- ipw.print("mHintAnimationRunning="); ipw.println(mHintAnimationRunning);
+ ipw.print("isTracking()="); ipw.println(isTracking());
ipw.print("mExpanding="); ipw.println(mExpanding);
ipw.print("mSplitShadeEnabled="); ipw.println(mSplitShadeEnabled);
ipw.print("mKeyguardNotificationBottomPadding=");
@@ -3737,7 +3694,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mQsController.beginJankMonitoring(isFullyCollapsed());
}
mInitialOffsetOnTouch = expandedHeight;
- if (!mTracking || isFullyCollapsed()) {
+ if (!isTracking() || isFullyCollapsed()) {
mInitialExpandY = newY;
mInitialExpandX = newX;
} else {
@@ -3755,7 +3712,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mShadeLog.logEndMotionEvent("endMotionEvent called", forceCancel, false);
mTrackingPointer = -1;
mAmbientState.setSwipingUp(false);
- if ((mTracking && mTouchSlopExceeded) || Math.abs(x - mInitialExpandX) > mTouchSlop
+ if ((isTracking() && mTouchSlopExceeded) || Math.abs(x - mInitialExpandX) > mTouchSlop
|| Math.abs(y - mInitialExpandY) > mTouchSlop
|| (!isFullyExpanded() && !isFullyCollapsed())
|| event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
@@ -3919,7 +3876,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
return;
}
- if (mTracking && !(mBlockingExpansionForCurrentTouch
+ if (isTracking() && !(mBlockingExpansionForCurrentTouch
|| mQsController.isTrackingBlocked())) {
return;
}
@@ -3945,7 +3902,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
float maxPanelHeight = getMaxPanelTransitionDistance();
if (mHeightAnimator == null) {
// Split shade has its own overscroll logic
- if (mTracking) {
+ if (isTracking()) {
float overExpansionPixels = Math.max(0, h - maxPanelHeight);
setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */);
}
@@ -4032,12 +3989,12 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
public boolean isTracking() {
- return mTracking;
+ return mShadeRepository.getLegacyShadeTracking().getValue();
}
@Override
public boolean canBeCollapsed() {
- return !isFullyCollapsed() && !mTracking && !mClosing;
+ return !isFullyCollapsed() && !isTracking() && !mClosing;
}
@Override
@@ -4058,73 +4015,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mView.removeCallbacks(mFlingCollapseRunnable);
}
- @Override
- public boolean isUnlockHintRunning() {
- return mHintAnimationRunning;
- }
-
- /**
- * Phase 1: Move everything upwards.
- */
- private void startUnlockHintAnimationPhase1(final Runnable onAnimationFinished) {
- float target = Math.max(0, getMaxPanelHeight() - mHintDistance);
- ValueAnimator animator = createHeightAnimator(target);
- animator.setDuration(250);
- animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- animator.addListener(new AnimatorListenerAdapter() {
- private boolean mCancelled;
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCancelled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mCancelled) {
- setAnimator(null);
- onAnimationFinished.run();
- } else {
- startUnlockHintAnimationPhase2(onAnimationFinished);
- }
- }
- });
- animator.start();
- setAnimator(animator);
-
-
- if (mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
- final ViewPropertyAnimator mKeyguardRootViewAnimator = mKeyguardRootView.animate();
- mKeyguardRootViewAnimator
- .translationY(-mHintDistance)
- .setDuration(250)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .withEndAction(() -> mKeyguardRootViewAnimator
- .translationY(0)
- .setDuration(450)
- .setInterpolator(mBounceInterpolator)
- .start())
- .start();
- } else {
- final List<ViewPropertyAnimator> indicationAnimators =
- mKeyguardBottomArea.getIndicationAreaAnimators();
-
- for (final ViewPropertyAnimator indicationAreaAnimator : indicationAnimators) {
- indicationAreaAnimator
- .translationY(-mHintDistance)
- .setDuration(250)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .withEndAction(() -> indicationAreaAnimator
- .translationY(0)
- .setDuration(450)
- .setInterpolator(mBounceInterpolator)
- .start())
- .start();
- }
- }
-
- }
-
private void setAnimator(ValueAnimator animator) {
mHeightAnimator = animator;
if (animator == null && mPanelUpdateWhenAnimatorEnds) {
@@ -4135,7 +4025,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
/** Returns whether a shade or QS expansion animation is running */
private boolean isShadeOrQsHeightAnimationRunning() {
- return mHeightAnimator != null && !mHintAnimationRunning && !mIsSpringBackAnimation;
+ return mHeightAnimator != null && !mIsSpringBackAnimation;
}
/**
@@ -4196,7 +4086,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
@Override
public void updateExpansionAndVisibility() {
mShadeExpansionStateManager.onPanelExpansionChanged(
- mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
+ mExpandedFraction, isExpanded(), isTracking(), mExpansionDragDownAmountPx);
updateVisibility();
}
@@ -4206,7 +4096,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
return mExpandedFraction > 0f
|| mInstantExpanding
|| isPanelVisibleBecauseOfHeadsUp()
- || mTracking
+ || isTracking()
|| mHeightAnimator != null
|| isPanelVisibleBecauseScrimIsAnimatingOff()
&& !mIsSpringBackAnimation;
@@ -4214,9 +4104,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
/** Called when the user performs a click anywhere in the empty area of the panel. */
private void onEmptySpaceClick() {
- if (!mHintAnimationRunning) {
- onMiddleClicked();
- }
+ onMiddleClicked();
}
@VisibleForTesting
@@ -4816,11 +4704,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
return mStatusBarStateListener;
}
- @VisibleForTesting
- boolean isHintAnimationRunning() {
- return mHintAnimationRunning;
- }
-
private void onStatusBarWindowStateChanged(@StatusBarManager.WindowVisibleState int state) {
if (state != WINDOW_STATE_SHOWING
&& mStatusBarStateController.getState() == StatusBarState.SHADE) {
@@ -4909,15 +4792,14 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation;
mMinExpandHeight = 0.0f;
mDownTime = mSystemClock.uptimeMillis();
- if (mAnimatingOnDown && mClosing && !mHintAnimationRunning) {
+ if (mAnimatingOnDown && mClosing) {
cancelHeightAnimator();
mTouchSlopExceeded = true;
mShadeLog.v("NotificationPanelViewController MotionEvent intercepted:"
- + " mAnimatingOnDown: true, mClosing: true, mHintAnimationRunning:"
- + " false");
+ + " mAnimatingOnDown: true, mClosing: true");
return true;
}
- if (!mTracking || isFullyCollapsed()) {
+ if (!isTracking() || isFullyCollapsed()) {
mInitialExpandY = y;
mInitialExpandX = x;
} else {
@@ -5094,7 +4976,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
// If dragging should not expand the notifications shade, then return false.
if (!mNotificationsDragEnabled) {
- if (mTracking) {
+ if (isTracking()) {
// Turn off tracking if it's on or the shade can get stuck in the down position.
onTrackingStopped(true /* expand */);
}
@@ -5220,7 +5102,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
&& (Math.abs(h) > Math.abs(x - mInitialExpandX)
|| mIgnoreXTouchSlop)) {
mTouchSlopExceeded = true;
- if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) {
+ if (mGestureWaitForTouchSlop
+ && !isTracking()
+ && !mCollapsedAndHeadsUpOnDown) {
if (mInitialOffsetOnTouch != 0f) {
startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
h = 0;
@@ -5235,7 +5119,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mTouchAboveFalsingThreshold = true;
mUpwardsWhenThresholdReached = isDirectionUpwards(x, y);
}
- if ((!mGestureWaitForTouchSlop || mTracking)
+ if ((!mGestureWaitForTouchSlop || isTracking())
&& !(mBlockingExpansionForCurrentTouch
|| mQsController.isTrackingBlocked())) {
// Count h==0 as part of swipe-up,
@@ -5261,7 +5145,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
break;
}
- return !mGestureWaitForTouchSlop || mTracking;
+ return !mGestureWaitForTouchSlop || isTracking();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index 941254223965..bdf114efb2b4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -39,6 +39,7 @@ import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.LargeScreenUtils
import com.android.systemui.util.ViewController
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -61,6 +62,7 @@ class NotificationsQSContainerController @Inject constructor(
private val featureFlags: FeatureFlags,
private val
notificationStackScrollLayoutController: NotificationStackScrollLayoutController,
+ private val splitShadeStateController: SplitShadeStateController
) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController {
private var qsExpanded = false
@@ -149,7 +151,8 @@ class NotificationsQSContainerController @Inject constructor(
}
fun updateResources() {
- val newSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(resources)
+ val newSplitShadeEnabled =
+ splitShadeStateController.shouldUseSplitNotificationShade(resources)
val splitShadeEnabledChanged = newSplitShadeEnabled != splitShadeEnabled
splitShadeEnabled = newSplitShadeEnabled
largeScreenShadeHeaderActive = LargeScreenUtils.shouldUseLargeScreenShadeHeader(resources)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index b2bbffdb5453..ff0d78f89e68 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -100,6 +100,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.LargeScreenUtils;
import com.android.systemui.util.kotlin.JavaAdapter;
@@ -150,6 +151,7 @@ public class QuickSettingsController implements Dumpable {
private final ShadeLogger mShadeLog;
private final KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
private final CastController mCastController;
+ private final SplitShadeStateController mSplitShadeStateController;
private final FeatureFlags mFeatureFlags;
private final InteractionJankMonitor mInteractionJankMonitor;
private final ShadeRepository mShadeRepository;
@@ -199,8 +201,6 @@ public class QuickSettingsController implements Dumpable {
private float mInitialTouchY;
/** whether current touch Y delta is above falsing threshold */
private boolean mTouchAboveFalsingThreshold;
- /** whether we are tracking a touch on QS container */
- private boolean mTracking;
/** pointerId of the pointer we're currently tracking */
private int mTrackingPointer;
@@ -344,14 +344,16 @@ public class QuickSettingsController implements Dumpable {
ShadeRepository shadeRepository,
ShadeInteractor shadeInteractor,
JavaAdapter javaAdapter,
- CastController castController
+ CastController castController,
+ SplitShadeStateController splitShadeStateController
) {
mPanelViewControllerLazy = panelViewControllerLazy;
mPanelView = panelView;
mQsFrame = mPanelView.findViewById(R.id.qs_frame);
mKeyguardStatusBar = mPanelView.findViewById(R.id.keyguard_header);
mResources = mPanelView.getResources();
- mSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
+ mSplitShadeStateController = splitShadeStateController;
+ mSplitShadeEnabled = mSplitShadeStateController.shouldUseSplitNotificationShade(mResources);
mQsFrameTranslateController = qsFrameTranslateController;
mShadeTransitionController = shadeTransitionController;
mPulseExpansionHandler = pulseExpansionHandler;
@@ -437,7 +439,7 @@ public class QuickSettingsController implements Dumpable {
}
void updateResources() {
- mSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
+ mSplitShadeEnabled = mSplitShadeStateController.shouldUseSplitNotificationShade(mResources);
if (mQs != null) {
mQs.setInSplitShade(mSplitShadeEnabled);
}
@@ -596,7 +598,7 @@ public class QuickSettingsController implements Dumpable {
@VisibleForTesting
boolean isTracking() {
- return mTracking;
+ return mShadeRepository.getLegacyQsTracking().getValue();
}
public boolean getFullyExpanded() {
@@ -609,10 +611,14 @@ public class QuickSettingsController implements Dumpable {
// split shade as there QS are always expanded so every collapsing motion is motion from
// expanded QS to closed panel
return mExpandImmediate || (mExpanded
- && !mTracking && !isExpansionAnimating()
+ && !isTracking() && !isExpansionAnimating()
&& !mExpansionFromOverscroll);
}
+ private void setTracking(boolean tracking) {
+ mShadeRepository.setLegacyQsTracking(tracking);
+ }
+
private boolean isQsFragmentCreated() {
return mQs != null;
}
@@ -1597,7 +1603,7 @@ public class QuickSettingsController implements Dumpable {
if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) {
// Down in the empty area while fully expanded - go to QS.
mShadeLog.logMotionEvent(event, "handleQsTouch: down action, QS tracking enabled");
- mTracking = true;
+ setTracking(true);
traceQsJank(true, false);
mConflictingExpansionGesture = true;
onExpansionStarted();
@@ -1612,9 +1618,9 @@ public class QuickSettingsController implements Dumpable {
// as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS.
if (!mSplitShadeEnabled && !mLastShadeFlingWasExpanding
&& computeExpansionFraction() <= 0.01 && mShadeExpandedFraction < 1.0) {
- mTracking = false;
+ setTracking(false);
}
- if (!isExpandImmediate() && mTracking) {
+ if (!isExpandImmediate() && isTracking()) {
onTouch(event);
if (!mConflictingExpansionGesture && !mSplitShadeEnabled) {
return true;
@@ -1658,7 +1664,7 @@ public class QuickSettingsController implements Dumpable {
if (shouldQuickSettingsIntercept(event.getX(), event.getY(), -1)) {
mShadeLog.logMotionEvent(event,
"handleQsDown: down action, QS tracking enabled");
- mTracking = true;
+ setTracking(true);
onExpansionStarted();
mInitialHeightOnTouch = mExpansionHeight;
mInitialTouchY = event.getY();
@@ -1684,7 +1690,7 @@ public class QuickSettingsController implements Dumpable {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mShadeLog.logMotionEvent(event, "onQsTouch: down action, QS tracking enabled");
- mTracking = true;
+ setTracking(true);
traceQsJank(true, false);
mInitialTouchY = y;
mInitialTouchX = x;
@@ -1721,7 +1727,7 @@ public class QuickSettingsController implements Dumpable {
case MotionEvent.ACTION_CANCEL:
mShadeLog.logMotionEvent(event,
"onQsTouch: up/cancel action, QS tracking disabled");
- mTracking = false;
+ setTracking(false);
mTrackingPointer = -1;
trackMovement(event);
float fraction = computeExpansionFraction();
@@ -1776,7 +1782,7 @@ public class QuickSettingsController implements Dumpable {
mInitialHeightOnTouch = mExpansionHeight;
mShadeLog.logMotionEvent(event,
"onQsIntercept: down action, QS tracking enabled");
- mTracking = true;
+ setTracking(true);
traceQsJank(true, false);
mNotificationStackScrollLayoutController.cancelLongPress();
}
@@ -1795,7 +1801,7 @@ public class QuickSettingsController implements Dumpable {
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
trackMovement(event);
- if (mTracking) {
+ if (isTracking()) {
// Already tracking because onOverscrolled was called. We need to update here
// so we don't stop for a frame until the next touch event gets handled in
// onTouchEvent.
@@ -1815,7 +1821,7 @@ public class QuickSettingsController implements Dumpable {
mInitialTouchX, mInitialTouchY, h)) {
mPanelView.getParent().requestDisallowInterceptTouchEvent(true);
mShadeLog.onQsInterceptMoveQsTrackingEnabled(h);
- mTracking = true;
+ setTracking(true);
traceQsJank(true, false);
onExpansionStarted();
mPanelViewControllerLazy.get().notifyExpandingFinished();
@@ -1835,7 +1841,7 @@ public class QuickSettingsController implements Dumpable {
case MotionEvent.ACTION_UP:
trackMovement(event);
mShadeLog.logMotionEvent(event, "onQsIntercept: up action, QS tracking disabled");
- mTracking = false;
+ setTracking(false);
break;
}
return false;
@@ -2061,7 +2067,7 @@ public class QuickSettingsController implements Dumpable {
ipw.print("mTouchAboveFalsingThreshold=");
ipw.println(mTouchAboveFalsingThreshold);
ipw.print("mTracking=");
- ipw.println(mTracking);
+ ipw.println(isTracking());
ipw.print("mTrackingPointer=");
ipw.println(mTrackingPointer);
ipw.print("mExpanded=");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index 656411874de5..9a356ad1fd0b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -135,7 +135,8 @@ constructor(
private val date: TextView = header.requireViewById(R.id.date)
private val iconContainer: StatusIconContainer = header.requireViewById(R.id.statusIcons)
private val mShadeCarrierGroup: ShadeCarrierGroup = header.requireViewById(R.id.carrier_group)
- private val systemIcons: View = header.requireViewById(R.id.shade_header_system_icons)
+ private val systemIconsHoverContainer: View =
+ header.requireViewById(R.id.hover_system_icons_container)
private var roundedCorners = 0
private var cutout: DisplayCutout? = null
@@ -259,14 +260,18 @@ constructor(
header.paddingRight,
header.paddingBottom
)
- systemIcons.setPaddingRelative(
+ systemIconsHoverContainer.setPaddingRelative(
resources.getDimensionPixelSize(
- R.dimen.shade_header_system_icons_padding_start
+ R.dimen.hover_system_icons_container_padding_start
),
- resources.getDimensionPixelSize(R.dimen.shade_header_system_icons_padding_top),
- resources.getDimensionPixelSize(R.dimen.shade_header_system_icons_padding_end),
resources.getDimensionPixelSize(
- R.dimen.shade_header_system_icons_padding_bottom
+ R.dimen.hover_system_icons_container_padding_top
+ ),
+ resources.getDimensionPixelSize(
+ R.dimen.hover_system_icons_container_padding_end
+ ),
+ resources.getDimensionPixelSize(
+ R.dimen.hover_system_icons_container_padding_bottom
)
)
}
@@ -330,8 +335,8 @@ constructor(
demoModeController.addCallback(demoModeReceiver)
statusBarIconController.addIconGroup(iconManager)
nextAlarmController.addCallback(nextAlarmCallback)
- systemIcons.setOnHoverListener(
- statusOverlayHoverListenerFactory.createListener(systemIcons)
+ systemIconsHoverContainer.setOnHoverListener(
+ statusOverlayHoverListenerFactory.createListener(systemIconsHoverContainer)
)
}
@@ -343,7 +348,7 @@ constructor(
demoModeController.removeCallback(demoModeReceiver)
statusBarIconController.removeIconGroup(iconManager)
nextAlarmController.removeCallback(nextAlarmCallback)
- systemIcons.setOnHoverListener(null)
+ systemIconsHoverContainer.setOnHoverListener(null)
}
fun disable(state1: Int, state2: Int, animate: Boolean) {
@@ -479,11 +484,11 @@ constructor(
if (largeScreenActive) {
logInstantEvent("Large screen constraints set")
header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
- systemIcons.setOnClickListener { shadeCollapseAction?.run() }
+ systemIconsHoverContainer.setOnClickListener { shadeCollapseAction?.run() }
} else {
logInstantEvent("Small screen constraints set")
header.setTransition(HEADER_TRANSITION_ID)
- systemIcons.setOnClickListener(null)
+ systemIconsHoverContainer.setOnClickListener(null)
}
header.jumpToState(header.startState)
updatePosition()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index cdbea8185edd..b3f6e1681ad6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -199,12 +199,6 @@ interface ShadeViewController {
/** Animate to expanded shade after a delay in ms. Used for lockscreen to shade transition. */
fun transitionToExpandedShade(delay: Long)
- /**
- * Returns whether the unlock hint animation is running. The unlock hint animation is when the
- * user taps the lock screen, causing the contents of the lock screen visually bounce.
- */
- val isUnlockHintRunning: Boolean
-
/** @see ViewGroupFadeHelper.reset */
fun resetViewGroupFade()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt
index 189375620285..b8a41019419d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt
@@ -73,7 +73,6 @@ class ShadeViewControllerEmptyImpl @Inject constructor() : ShadeViewController {
return false
}
override fun transitionToExpandedShade(delay: Long) {}
- override val isUnlockHintRunning: Boolean = false
override fun resetViewGroupFade() {}
override fun setKeyguardTransitionProgress(keyguardAlpha: Float, keyguardTranslationY: Int) {}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index 947259a79345..52a99af3eee4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -56,6 +56,30 @@ interface ShadeRepository {
@Deprecated("Use ShadeInteractor.shadeExpansion instead")
val legacyShadeExpansion: StateFlow<Float>
+ /**
+ * NotificationPanelViewController.mTracking as a flow. "Tracking" means that the user is moving
+ * the shade up or down with a pointer. Going forward, this concept will be replaced by checks
+ * for whether a transition was driven by user input instead of whether a pointer is currently
+ * touching the screen, i.e. after the user has lifted their finger to fling the shade, these
+ * values would be different.
+ */
+ @Deprecated("Use ShadeInteractor instead") val legacyShadeTracking: StateFlow<Boolean>
+
+ /**
+ * QuickSettingsController.mTracking as a flow. "Tracking" means that the user is moving quick
+ * settings up or down with a pointer. Going forward, this concept will be replaced by checks
+ * for whether a transition was driven by user input instead of whether a pointer is currently
+ * touching the screen, i.e. after the user has lifted their finger to fling the QS, these
+ * values would be different.
+ */
+ @Deprecated("Use ShadeInteractor instead") val legacyQsTracking: StateFlow<Boolean>
+
+ /** Sets whether the user is moving Quick Settings with a pointer */
+ fun setLegacyQsTracking(legacyQsTracking: Boolean)
+
+ /** Sets whether the user is moving the shade with a pointer */
+ fun setLegacyShadeTracking(tracking: Boolean)
+
/** Amount shade has expanded with regard to the UDFPS location */
val udfpsTransitionToFullShadeProgress: StateFlow<Float>
@@ -123,6 +147,24 @@ constructor(shadeExpansionStateManager: ShadeExpansionStateManager) : ShadeRepos
@Deprecated("Use ShadeInteractor.shadeExpansion instead")
override val legacyShadeExpansion: StateFlow<Float> = _legacyShadeExpansion.asStateFlow()
+ private val _legacyShadeTracking = MutableStateFlow(false)
+ @Deprecated("Use ShadeInteractor instead")
+ override val legacyShadeTracking: StateFlow<Boolean> = _legacyShadeTracking.asStateFlow()
+
+ private val _legacyQsTracking = MutableStateFlow(false)
+ @Deprecated("Use ShadeInteractor instead")
+ override val legacyQsTracking: StateFlow<Boolean> = _legacyQsTracking.asStateFlow()
+
+ @Deprecated("Should only be called by NPVC and tests")
+ override fun setLegacyQsTracking(legacyQsTracking: Boolean) {
+ _legacyQsTracking.value = legacyQsTracking
+ }
+
+ @Deprecated("Should only be called by NPVC and tests")
+ override fun setLegacyShadeTracking(tracking: Boolean) {
+ _legacyShadeTracking.value = tracking
+ }
+
override fun setQsExpansion(qsExpansion: Float) {
_qsExpansion.value = qsExpansion
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImpl.kt
index fd57f21b2e1e..4ba56749de91 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImpl.kt
@@ -20,7 +20,7 @@ import android.content.Context
import android.content.res.Configuration
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import javax.inject.Inject
/** Interpolator responsible for the shade when on large screens. */
@@ -32,6 +32,7 @@ internal constructor(
private val context: Context,
private val splitShadeInterpolator: SplitShadeInterpolator,
private val portraitShadeInterpolator: LargeScreenPortraitShadeInterpolator,
+ private val splitShadeStateController: SplitShadeStateController
) : LargeScreenShadeInterpolator {
private var inSplitShade = false
@@ -48,7 +49,7 @@ internal constructor(
}
private fun updateResources() {
- inSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ inSplitShade = splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
}
private val impl: LargeScreenShadeInterpolator
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
index ec16109fe1c7..971507055873 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
@@ -18,7 +18,6 @@ package com.android.systemui.shade.transition
import android.content.Context
import android.content.res.Configuration
-import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
@@ -31,6 +30,7 @@ import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import java.io.PrintWriter
import javax.inject.Inject
@@ -45,6 +45,7 @@ constructor(
private val context: Context,
private val scrimShadeTransitionController: ScrimShadeTransitionController,
private val statusBarStateController: SysuiStatusBarStateController,
+ private val splitShadeStateController: SplitShadeStateController
) {
lateinit var shadeViewController: ShadeViewController
@@ -73,7 +74,7 @@ constructor(
}
private fun updateResources() {
- inSplitShade = context.resources.getBoolean(R.bool.config_use_split_notification_shade)
+ inSplitShade = splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
}
private fun onPanelStateChanged(@PanelState state: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
index 5b24af038b6b..b6a633fdd1a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
@@ -6,14 +6,15 @@ import android.util.IndentingPrintWriter
import com.android.systemui.Dumpable
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import java.io.PrintWriter
/** An abstract implementation of a class that controls the lockscreen to shade transition. */
abstract class AbstractLockscreenShadeTransitionController(
protected val context: Context,
configurationController: ConfigurationController,
- dumpManager: DumpManager
+ dumpManager: DumpManager,
+ private val splitShadeStateController: SplitShadeStateController
) : Dumpable {
protected var useSplitShade = false
@@ -44,7 +45,8 @@ abstract class AbstractLockscreenShadeTransitionController(
}
private fun updateResourcesInternal() {
- useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ useSplitShade = splitShadeStateController
+ .shouldUseSplitNotificationShade(context.resources)
updateResources()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
index fec61124bc86..238317cfc99e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
@@ -8,6 +8,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.media.controls.ui.MediaHierarchyManager
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -16,12 +17,14 @@ import dagger.assisted.AssistedInject
class LockscreenShadeKeyguardTransitionController
@AssistedInject
constructor(
- private val mediaHierarchyManager: MediaHierarchyManager,
- @Assisted private val notificationPanelController: ShadeViewController,
- context: Context,
- configurationController: ConfigurationController,
- dumpManager: DumpManager
-) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+ private val mediaHierarchyManager: MediaHierarchyManager,
+ @Assisted private val notificationPanelController: ShadeViewController,
+ context: Context,
+ configurationController: ConfigurationController,
+ dumpManager: DumpManager,
+ splitShadeStateController: SplitShadeStateController
+) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager,
+ splitShadeStateController) {
/**
* Distance that the full shade transition takes in order for the keyguard content on
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
index df8c6abfff97..5f3d75786973 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
@@ -25,6 +25,7 @@ import com.android.systemui.R
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -38,7 +39,14 @@ constructor(
configurationController: ConfigurationController,
dumpManager: DumpManager,
@Assisted private val qsProvider: () -> QS,
-) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+ splitShadeStateController: SplitShadeStateController
+) :
+ AbstractLockscreenShadeTransitionController(
+ context,
+ configurationController,
+ dumpManager,
+ splitShadeStateController
+ ) {
private val qs: QS
get() = qsProvider()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
index 00d3701a0cc7..af4a1aa98d9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
@@ -7,6 +7,7 @@ import com.android.systemui.R
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import javax.inject.Inject
/** Controls the lockscreen to shade transition for scrims. */
@@ -16,8 +17,10 @@ constructor(
private val scrimController: ScrimController,
context: Context,
configurationController: ConfigurationController,
- dumpManager: DumpManager
-) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+ dumpManager: DumpManager,
+ splitShadeStateController: SplitShadeStateController
+) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager,
+ splitShadeStateController) {
/**
* Distance that the full shade transition takes in order for scrim to fully transition to the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 73bbbca09fe8..29ca0f438aac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -42,7 +42,7 @@ import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.wm.shell.animation.Interpolators
import java.io.PrintWriter
import javax.inject.Inject
@@ -79,6 +79,7 @@ class LockscreenShadeTransitionController @Inject constructor(
private val shadeRepository: ShadeRepository,
private val shadeInteractor: ShadeInteractor,
private val powerInteractor: PowerInteractor,
+ private val splitShadeStateController: SplitShadeStateController
) : Dumpable {
private var pulseHeight: Float = 0f
@@ -267,7 +268,9 @@ class LockscreenShadeTransitionController @Inject constructor(
R.dimen.lockscreen_shade_udfps_keyguard_transition_distance)
statusBarTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_status_bar_transition_distance)
- useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+
+ useSplitShade = splitShadeStateController
+ .shouldUseSplitNotificationShade(context.resources)
}
fun setStackScroller(nsslController: NotificationStackScrollLayoutController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 59c63aa28d0f..5c45f3d1bbc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -46,7 +46,7 @@ import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.LargeScreenUtils
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.WallpaperController
import java.io.PrintWriter
import javax.inject.Inject
@@ -67,6 +67,7 @@ class NotificationShadeDepthController @Inject constructor(
private val notificationShadeWindowController: NotificationShadeWindowController,
private val dozeParameters: DozeParameters,
private val context: Context,
+ private val splitShadeStateController: SplitShadeStateController,
dumpManager: DumpManager,
configurationController: ConfigurationController
) : ShadeExpansionListener, Dumpable {
@@ -329,7 +330,7 @@ class NotificationShadeDepthController @Inject constructor(
}
private fun updateResources() {
- inSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ inSplitShade = splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
}
fun addListener(listener: DepthListener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 3f37c60bee8d..c760227aa124 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -776,7 +776,7 @@ public class NotificationShelf extends ActivatableNotificationView implements St
}
} else if (viewEnd >= shelfClipStart
- && (!mAmbientState.isUnlockHintRunning() || view.isInShelf())
+ && view.isInShelf()
&& (mAmbientState.isShadeExpanded()
|| (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index e20614178885..70ccc4f3ae43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -31,6 +31,7 @@ import android.view.ViewGroup;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -38,6 +39,7 @@ import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.icon.IconManager;
+import com.android.systemui.statusbar.notification.row.BigPictureIconManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
@@ -151,6 +153,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
component.getExpandableNotificationRowController();
rowController.init(entry);
entry.setRowController(rowController);
+ maybeSetBigPictureIconManager(row, component);
bindRow(entry, row);
updateRow(entry, row);
inflateContentViews(entry, params, row, callback);
@@ -165,6 +168,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
return;
}
mLogger.logReleasingViews(entry);
+ cancelRunningJobs(entry.getRow());
final RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_CONTRACTED);
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_EXPANDED);
@@ -172,6 +176,23 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
mRowContentBindStage.requestRebind(entry, null);
}
+ private void maybeSetBigPictureIconManager(ExpandableNotificationRow row,
+ ExpandableNotificationRowComponent component) {
+ if (mFeatureFlags.isEnabled(Flags.BIGPICTURE_NOTIFICATION_LAZY_LOADING)) {
+ row.setBigPictureIconManager(component.getBigPictureIconManager());
+ }
+ }
+
+ private void cancelRunningJobs(ExpandableNotificationRow row) {
+ if (row == null) {
+ return;
+ }
+ BigPictureIconManager iconManager = row.getBigPictureIconManager();
+ if (iconManager != null) {
+ iconManager.cancelJobs();
+ }
+ }
+
/**
* Bind row to various controllers and managers. This is only called when the row is first
* created.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
new file mode 100644
index 000000000000..88dbb4cf1342
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row
+
+import android.annotation.WorkerThread
+import android.app.ActivityManager
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
+import android.util.Dumpable
+import android.util.Log
+import android.util.Size
+import com.android.internal.R
+import com.android.internal.widget.NotificationDrawableConsumer
+import com.android.internal.widget.NotificationIconManager
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.graphics.ImageLoader
+import com.android.systemui.statusbar.notification.row.BigPictureIconManager.DrawableState.Empty
+import com.android.systemui.statusbar.notification.row.BigPictureIconManager.DrawableState.FullImage
+import com.android.systemui.statusbar.notification.row.BigPictureIconManager.DrawableState.PlaceHolder
+import java.io.PrintWriter
+import javax.inject.Inject
+import kotlin.math.min
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+private const val TAG = "BigPicImageLoader"
+private const val DEBUG = false
+private const val FREE_IMAGE_DELAY_MS = 3000L
+
+/**
+ * A helper class for [com.android.internal.widget.BigPictureNotificationImageView] to lazy-load
+ * images from SysUI. It replaces the placeholder image with the fully loaded one, and vica versa.
+ *
+ * TODO(b/283082473) move the logs to a [com.android.systemui.log.LogBuffer]
+ */
+@SuppressWarnings("DumpableNotRegistered")
+class BigPictureIconManager
+@Inject
+constructor(
+ private val context: Context,
+ private val imageLoader: ImageLoader,
+ @Application private val scope: CoroutineScope,
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ @Background private val bgDispatcher: CoroutineDispatcher
+) : NotificationIconManager, Dumpable {
+
+ private var lastLoadingJob: Job? = null
+ private var drawableConsumer: NotificationDrawableConsumer? = null
+ private var displayedState: DrawableState = Empty(null)
+ private var viewShown = false
+
+ private var maxWidth = getMaxWidth()
+ private var maxHeight = getMaxHeight()
+
+ /**
+ * Called when the displayed state changes of the view.
+ *
+ * @param shown true if the view is shown, and the image needs to be displayed.
+ */
+ fun onViewShown(shown: Boolean) {
+ log("onViewShown:$shown")
+
+ if (this.viewShown != shown) {
+ this.viewShown = shown
+
+ val state = displayedState
+
+ this.lastLoadingJob?.cancel()
+ this.lastLoadingJob =
+ when {
+ state is Empty && shown -> state.icon?.let(::startLoadingJob)
+ state is PlaceHolder && shown -> startLoadingJob(state.icon)
+ state is FullImage && !shown ->
+ startFreeImageJob(state.icon, state.drawableSize)
+ else -> null
+ }
+ }
+ }
+
+ /**
+ * Update the maximum width and height allowed for bitmaps, ex. after a configuration change.
+ */
+ fun updateMaxImageSizes() {
+ log("updateMaxImageSizes")
+ maxWidth = getMaxWidth()
+ maxHeight = getMaxHeight()
+ }
+
+ /** Cancels all currently running jobs. */
+ fun cancelJobs() {
+ lastLoadingJob?.cancel()
+ }
+
+ @WorkerThread
+ override fun updateIcon(drawableConsumer: NotificationDrawableConsumer, icon: Icon?): Runnable {
+ if (this.drawableConsumer != null && this.drawableConsumer != drawableConsumer) {
+ Log.wtf(TAG, "A consumer is already set for this iconManager.")
+ return Runnable {}
+ }
+
+ if (displayedState.iconSameAs(icon)) {
+ // We're already handling this icon, nothing to do here.
+ log("skipping updateIcon for consumer:$drawableConsumer with icon:$icon")
+ return Runnable {}
+ }
+
+ this.drawableConsumer = drawableConsumer
+ this.displayedState = Empty(icon)
+ this.lastLoadingJob?.cancel()
+
+ val drawable = loadImageOrPlaceHolderSync(icon)
+
+ log("icon updated")
+
+ return Runnable { drawableConsumer.setImageDrawable(drawable) }
+ }
+
+ override fun dump(pw: PrintWriter, args: Array<out String>?) {
+ pw.println("BigPictureIconManager ${getDebugString()}")
+ }
+
+ @WorkerThread
+ private fun loadImageOrPlaceHolderSync(icon: Icon?): Drawable? {
+ icon ?: return null
+
+ if (viewShown) {
+ return loadImageSync(icon)
+ }
+
+ return loadPlaceHolderSync(icon) ?: loadImageSync(icon)
+ }
+
+ @WorkerThread
+ private fun loadImageSync(icon: Icon): Drawable? {
+ return imageLoader.loadDrawableSync(icon, context, maxWidth, maxHeight)?.also { drawable ->
+ checkPlaceHolderSizeForDrawable(this.displayedState, drawable)
+ this.displayedState = FullImage(icon, drawable.intrinsicSize)
+ }
+ }
+
+ private fun checkPlaceHolderSizeForDrawable(
+ displayedState: DrawableState,
+ newDrawable: Drawable
+ ) {
+ if (displayedState is PlaceHolder) {
+ val (oldWidth, oldHeight) = displayedState.drawableSize
+ val (newWidth, newHeight) = newDrawable.intrinsicSize
+
+ if (oldWidth != newWidth || oldHeight != newHeight) {
+ Log.e(
+ TAG,
+ "Mismatch in dimensions, when replacing PlaceHolder " +
+ "$oldWidth X $oldHeight with Drawable $newWidth X $newHeight."
+ )
+ }
+ }
+ }
+
+ @WorkerThread
+ private fun loadPlaceHolderSync(icon: Icon): Drawable? {
+ return imageLoader
+ .loadSizeSync(icon, context)
+ ?.resizeToMax(maxWidth, maxHeight) // match the dimensions of the fully loaded drawable
+ ?.let { size -> createPlaceHolder(size) }
+ ?.also { drawable -> this.displayedState = PlaceHolder(icon, drawable.intrinsicSize) }
+ }
+
+ private fun startLoadingJob(icon: Icon): Job =
+ scope.launch {
+ val drawable = withContext(bgDispatcher) { loadImageSync(icon) }
+ withContext(mainDispatcher) { drawableConsumer?.setImageDrawable(drawable) }
+ log("image loaded")
+ }
+
+ private fun startFreeImageJob(icon: Icon, drawableSize: Size): Job =
+ scope.launch {
+ delay(FREE_IMAGE_DELAY_MS)
+ val drawable = createPlaceHolder(drawableSize)
+ displayedState = PlaceHolder(icon, drawable.intrinsicSize)
+ withContext(mainDispatcher) { drawableConsumer?.setImageDrawable(drawable) }
+ log("placeholder loaded")
+ }
+
+ private fun createPlaceHolder(size: Size): Drawable {
+ return PlaceHolderDrawable(width = size.width, height = size.height)
+ }
+
+ private fun isLowRam(): Boolean {
+ return ActivityManager.isLowRamDeviceStatic()
+ }
+
+ private fun getMaxWidth() =
+ context.resources.getDimensionPixelSize(
+ if (isLowRam()) {
+ R.dimen.notification_big_picture_max_width_low_ram
+ } else {
+ R.dimen.notification_big_picture_max_width
+ }
+ )
+
+ private fun getMaxHeight() =
+ context.resources.getDimensionPixelSize(
+ if (isLowRam()) {
+ R.dimen.notification_big_picture_max_height_low_ram
+ } else {
+ R.dimen.notification_big_picture_max_height
+ }
+ )
+
+ private fun log(msg: String) {
+ if (DEBUG) {
+ Log.d(TAG, "$msg state=${getDebugString()}")
+ }
+ }
+
+ private fun getDebugString() =
+ "{ state:$displayedState, hasConsumer:${drawableConsumer != null}, viewShown:$viewShown}"
+
+ private sealed class DrawableState(open val icon: Icon?) {
+ data class Empty(override val icon: Icon?) : DrawableState(icon)
+ data class PlaceHolder(override val icon: Icon, val drawableSize: Size) :
+ DrawableState(icon)
+ data class FullImage(override val icon: Icon, val drawableSize: Size) : DrawableState(icon)
+
+ fun iconSameAs(other: Icon?): Boolean {
+ val displayedIcon = icon
+ return when {
+ displayedIcon == null && other == null -> true
+ displayedIcon != null && other != null -> displayedIcon.sameAs(other)
+ else -> false
+ }
+ }
+ }
+}
+
+/**
+ * @return an image size that conforms to the maxWidth / maxHeight parameters. It can be the same
+ * instance, if the provided size was already small enough.
+ */
+private fun Size.resizeToMax(maxWidth: Int, maxHeight: Int): Size {
+ if (width <= maxWidth && height <= maxHeight) {
+ return this
+ }
+
+ // Calculate the scale factor for both dimensions
+ val wScale =
+ if (maxWidth <= 0) {
+ 1.0f
+ } else {
+ maxWidth.toFloat() / width.toFloat()
+ }
+
+ val hScale =
+ if (maxHeight <= 0) {
+ 1.0f
+ } else {
+ maxHeight.toFloat() / height.toFloat()
+ }
+
+ // Scale down to the smaller scale factor
+ val scale = min(wScale, hScale)
+ if (scale < 1.0f) {
+ val targetWidth = (width * scale).toInt()
+ val targetHeight = (height * scale).toInt()
+
+ return Size(targetWidth, targetHeight)
+ }
+
+ return this
+}
+
+private val Drawable.intrinsicSize
+ get() = Size(/*width=*/ intrinsicWidth, /*height=*/ intrinsicHeight)
+
+private operator fun Size.component1() = width
+
+private operator fun Size.component2() = height
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureLayoutInflaterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureLayoutInflaterFactory.kt
new file mode 100644
index 000000000000..e22666574e0d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureLayoutInflaterFactory.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification.row
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import com.android.internal.widget.BigPictureNotificationImageView
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
+import javax.inject.Inject
+
+class BigPictureLayoutInflaterFactory @Inject constructor() : NotifRemoteViewsFactory {
+
+ override fun instantiate(
+ row: ExpandableNotificationRow,
+ @InflationFlag layoutType: Int,
+ parent: View?,
+ name: String,
+ context: Context,
+ attrs: AttributeSet
+ ): View? {
+ // Currently the [BigPictureIconManager] only handles one view per notification.
+ // Exclude other layout types for now, to make sure that we set the same iconManager
+ // on only one [BigPictureNotificationImageView].
+ if (layoutType != FLAG_CONTENT_VIEW_EXPANDED) {
+ return null
+ }
+
+ return when (name) {
+ BigPictureNotificationImageView::class.java.name ->
+ BigPictureNotificationImageView(context, attrs).also { view ->
+ view.setIconManager(row.bigPictureIconManager)
+ }
+ else -> null
+ }
+ }
+}
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 c02382dcde94..7fa955bc75eb 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
@@ -376,6 +376,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private float mTranslationWhenRemoved;
private boolean mWasChildInGroupWhenRemoved;
private NotificationInlineImageResolver mImageResolver;
+ private BigPictureIconManager mBigPictureIconManager;
@Nullable
private OnExpansionChangedListener mExpansionChangedListener;
@Nullable
@@ -1355,6 +1356,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
if (mImageResolver != null) {
mImageResolver.updateMaxImageSizes();
}
+ if (mBigPictureIconManager != null) {
+ mBigPictureIconManager.updateMaxImageSizes();
+ }
}
public void onUiModeChanged() {
@@ -1794,6 +1798,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mImageResolver;
}
+ public BigPictureIconManager getBigPictureIconManager() {
+ return mBigPictureIconManager;
+ }
+
+ public void setBigPictureIconManager(
+ BigPictureIconManager bigPictureIconManager) {
+ mBigPictureIconManager = bigPictureIconManager;
+ }
+
+
/**
* Resets this view so it can be re-used for an updated notification.
*/
@@ -3687,6 +3701,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
pw.println("no viewState!!!");
}
pw.println(getRoundableState().debugString());
+ if (mBigPictureIconManager != null) {
+ mBigPictureIconManager.dump(pw, args);
+ }
dumpBackgroundView(pw, args);
int transientViewCount = mChildrenContainer == null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
index 867e08b2e743..0239afc08ec5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
@@ -60,12 +60,16 @@ public abstract class NotificationRowModule {
@Named(NOTIF_REMOTEVIEWS_FACTORIES)
static Set<NotifRemoteViewsFactory> provideNotifRemoteViewsFactories(
FeatureFlags featureFlags,
- PrecomputedTextViewFactory precomputedTextViewFactory
+ PrecomputedTextViewFactory precomputedTextViewFactory,
+ BigPictureLayoutInflaterFactory bigPictureLayoutInflaterFactory
) {
final Set<NotifRemoteViewsFactory> replacementFactories = new HashSet<>();
if (featureFlags.isEnabled(Flags.PRECOMPUTED_TEXT)) {
replacementFactories.add(precomputedTextViewFactory);
}
+ if (featureFlags.isEnabled(Flags.BIGPICTURE_NOTIFICATION_LAZY_LOADING)) {
+ replacementFactories.add(bigPictureLayoutInflaterFactory);
+ }
return replacementFactories;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PlaceHolderDrawable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PlaceHolderDrawable.kt
new file mode 100644
index 000000000000..40aa27fc4592
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PlaceHolderDrawable.kt
@@ -0,0 +1,33 @@
+package com.android.systemui.statusbar.notification.row
+
+import android.graphics.Canvas
+import android.graphics.ColorFilter
+import android.graphics.PixelFormat
+import android.graphics.drawable.Drawable
+
+class PlaceHolderDrawable(private val width: Int, private val height: Int) : Drawable() {
+
+ companion object {
+ fun createFrom(other: Drawable): PlaceHolderDrawable {
+ return PlaceHolderDrawable(other.intrinsicWidth, other.intrinsicHeight)
+ }
+ }
+
+ override fun getIntrinsicWidth(): Int {
+ return width
+ }
+
+ override fun getIntrinsicHeight(): Int {
+ return height
+ }
+
+ override fun draw(canvas: Canvas) {}
+ override fun setAlpha(alpha: Int) {}
+ override fun setColorFilter(colorFilter: ColorFilter?) {}
+
+ @Suppress("DeprecatedCallableAddReplaceWith")
+ @Deprecated("Deprecated in android.graphics.drawable.Drawable")
+ override fun getOpacity(): Int {
+ return PixelFormat.TRANSPARENT
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
index 3588621b12ad..0a6a2c84b0c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
@@ -23,6 +23,7 @@ import android.service.notification.StatusBarNotification;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+import com.android.systemui.statusbar.notification.row.BigPictureIconManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
@@ -68,6 +69,12 @@ public interface ExpandableNotificationRowComponent {
ExpandableNotificationRowController getExpandableNotificationRowController();
/**
+ * Creates a BigPictureIconManager.
+ */
+ @NotificationRowScope
+ BigPictureIconManager getBigPictureIconManager();
+
+ /**
* Dagger Module that extracts interesting properties from an ExpandableNotificationRow.
*/
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
index 175ba15eebae..acd6cc69b553 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
@@ -28,6 +28,7 @@ import android.view.View;
import com.android.internal.R;
import com.android.internal.widget.BigPictureNotificationImageView;
import com.android.systemui.statusbar.notification.ImageTransformState;
+import com.android.systemui.statusbar.notification.row.BigPictureIconManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
/**
@@ -66,6 +67,17 @@ public class NotificationBigPictureTemplateViewWrapper extends NotificationTempl
}
}
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ BigPictureIconManager imageManager = mRow.getBigPictureIconManager();
+ if (imageManager != null) {
+ // TODO(b/283082473) call it a bit earlier for true, as soon as the row starts to expand
+ imageManager.onViewShown(visible);
+ }
+ }
+
/**
* Starts or stops the animations in any drawables contained in this BigPicture Notification.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 95e74f210c5d..38a368e1fdc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -86,7 +86,6 @@ public class AmbientState implements Dumpable {
private boolean mExpansionChanging;
private boolean mIsSmallScreen;
private boolean mPulsing;
- private boolean mUnlockHintRunning;
private float mHideAmount;
private boolean mAppearing;
private float mPulseHeight = MAX_PULSE_HEIGHT;
@@ -592,14 +591,6 @@ public class AmbientState implements Dumpable {
mIsSmallScreen = smallScreen;
}
- public void setUnlockHintRunning(boolean unlockHintRunning) {
- mUnlockHintRunning = unlockHintRunning;
- }
-
- public boolean isUnlockHintRunning() {
- return mUnlockHintRunning;
- }
-
/**
* @return Whether we need to do a fling down after swiping up on lockscreen.
*/
@@ -770,7 +761,6 @@ public class AmbientState implements Dumpable {
pw.println("mPulseHeight=" + mPulseHeight);
pw.println("mTrackedHeadsUpRow.key=" + logKey(mTrackedHeadsUpRow));
pw.println("mMaxHeadsUpTranslation=" + mMaxHeadsUpTranslation);
- pw.println("mUnlockHintRunning=" + mUnlockHintRunning);
pw.println("mDozeAmount=" + mDozeAmount);
pw.println("mDozing=" + mDozing);
pw.println("mFractionToShade=" + mFractionToShade);
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 5e3a67ece4a5..e8521d1673cf 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
@@ -118,9 +118,9 @@ import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.ScrollAdapter;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.Assert;
import com.android.systemui.util.DumpUtilsKt;
-import com.android.systemui.util.LargeScreenUtils;
import com.google.errorprone.annotations.CompileTimeConstant;
@@ -568,6 +568,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private final ScreenOffAnimationController mScreenOffAnimationController;
private boolean mShouldUseSplitNotificationShade;
private boolean mHasFilteredOutSeenNotifications;
+ @Nullable private SplitShadeStateController mSplitShadeStateController = null;
+
+ /** Pass splitShadeStateController to view and update split shade */
+ public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) {
+ mSplitShadeStateController = splitShadeStateController;
+ updateSplitNotificationShade();
+ }
private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
new ExpandableView.OnHeightChangedListener() {
@@ -630,7 +637,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSectionsManager = Dependency.get(NotificationSectionsManager.class);
mScreenOffAnimationController =
Dependency.get(ScreenOffAnimationController.class);
- updateSplitNotificationShade();
mSectionsManager.initialize(this);
mSections = mSectionsManager.createSectionsForBuckets();
@@ -1350,8 +1356,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
*/
private boolean shouldSkipHeightUpdate() {
return mAmbientState.isOnKeyguard()
- && (mAmbientState.isUnlockHintRunning()
- || mAmbientState.isSwipingUp()
+ && (mAmbientState.isSwipingUp()
|| mAmbientState.isFlingingAfterSwipeUpOnLockscreen());
}
@@ -5071,14 +5076,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mAmbientState.setSmallScreen(isFullWidth);
}
- public void setUnlockHintRunning(boolean running) {
- mAmbientState.setUnlockHintRunning(running);
- if (!running) {
- // re-calculate the stack height which was frozen while running this animation
- updateStackPosition();
- }
- }
-
public void setPanelFlinging(boolean flinging) {
mAmbientState.setFlinging(flinging);
if (!flinging) {
@@ -5675,7 +5672,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@VisibleForTesting
void updateSplitNotificationShade() {
- boolean split = LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
+ boolean split = mSplitShadeStateController.shouldUseSplitNotificationShade(getResources());
if (split != mShouldUseSplitNotificationShade) {
mShouldUseSplitNotificationShade = split;
updateDismissBehavior();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 93b5ff7268e3..b051809f2c5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -128,6 +128,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.Compile;
@@ -672,7 +673,8 @@ public class NotificationStackScrollLayoutController {
NotificationTargetsHelper notificationTargetsHelper,
SecureSettings secureSettings,
NotificationDismissibilityProvider dismissibilityProvider,
- ActivityStarter activityStarter) {
+ ActivityStarter activityStarter,
+ SplitShadeStateController splitShadeStateController) {
mView = view;
mKeyguardTransitionRepo = keyguardTransitionRepo;
mStackStateLogger = stackLogger;
@@ -722,6 +724,7 @@ public class NotificationStackScrollLayoutController {
mSecureSettings = secureSettings;
mDismissibilityProvider = dismissibilityProvider;
mActivityStarter = activityStarter;
+ mView.passSplitShadeStateController(splitShadeStateController);
updateResources();
setUpView();
}
@@ -1200,10 +1203,6 @@ public class NotificationStackScrollLayoutController {
mView.setHeadsUpBoundaries(height, bottomBarHeight);
}
- public void setUnlockHintRunning(boolean running) {
- mView.setUnlockHintRunning(running);
- }
-
public void setPanelFlinging(boolean flinging) {
mView.setPanelFlinging(flinging);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index c7cb70c1da05..24104d2f37e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -29,8 +29,8 @@ import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.Compile
-import com.android.systemui.util.LargeScreenUtils.shouldUseSplitNotificationShade
import com.android.systemui.util.children
import java.io.PrintWriter
import javax.inject.Inject
@@ -54,7 +54,8 @@ constructor(
private val statusBarStateController: SysuiStatusBarStateController,
private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
private val mediaDataManager: MediaDataManager,
- @Main private val resources: Resources
+ @Main private val resources: Resources,
+ private val splitShadeStateController: SplitShadeStateController
) {
/**
@@ -181,7 +182,8 @@ constructor(
// How many notifications we can show at heightWithoutLockscreenConstraints
var minCountAtHeightWithoutConstraints =
- if (isMediaShowing && !shouldUseSplitNotificationShade(resources)) 2 else 1
+ if (isMediaShowing && !splitShadeStateController
+ .shouldUseSplitNotificationShade(resources)) 2 else 1
log {
"\t---maxNotifWithoutSavingSpace=$maxNotifWithoutSavingSpace " +
"isMediaShowing=$isMediaShowing" +
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
index 4ed31c2cec89..51b6c75f44b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
@@ -21,6 +21,7 @@ import android.content.Context
import com.android.systemui.R
import com.android.systemui.common.ui.data.repository.ConfigurationRepository
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.SplitShadeStateController
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -36,6 +37,7 @@ class SharedNotificationContainerInteractor
constructor(
configurationRepository: ConfigurationRepository,
private val context: Context,
+ private val splitShadeStateController: SplitShadeStateController
) {
private val _topPosition = MutableStateFlow(0f)
@@ -47,7 +49,10 @@ constructor(
.map { _ ->
with(context.resources) {
ConfigurationBasedDimensions(
- useSplitShade = getBoolean(R.bool.config_use_split_notification_shade),
+ useSplitShade =
+ splitShadeStateController.shouldUseSplitNotificationShade(
+ context.resources
+ ),
useLargeScreenHeader =
getBoolean(R.bool.config_use_large_screen_shade_header),
marginHorizontal =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
index cdd410e766a2..47ab316bb239 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
@@ -20,7 +20,6 @@ import android.content.res.Configuration
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
-import android.view.ViewPropertyAnimator
import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.annotation.StringRes
@@ -32,7 +31,6 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
-import com.android.systemui.util.animation.requiresRemeasuring
/**
* Renders the bottom area of the lock-screen. Concerned primarily with the quick affordance UI
@@ -61,6 +59,7 @@ constructor(
}
private var ambientIndicationArea: View? = null
+ private var keyguardIndicationArea: View? = null
private var binding: KeyguardBottomAreaViewBinder.Binding? = null
private var lockIconViewController: LockIconViewController? = null
@@ -124,13 +123,14 @@ constructor(
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
binding?.onConfigurationChanged()
- }
-
- /** Returns a list of animators to use to animate the indication areas. */
- @Deprecated("Deprecated as part of b/278057014")
- val indicationAreaAnimators: List<ViewPropertyAnimator>
- get() = checkNotNull(binding).getIndicationAreaAnimators()
+ keyguardIndicationArea?.let {
+ val params = it.layoutParams as FrameLayout.LayoutParams
+ params.bottomMargin =
+ resources.getDimensionPixelSize(R.dimen.keyguard_indication_margin_bottom)
+ it.layoutParams = params
+ }
+ }
override fun hasOverlappingRendering(): Boolean {
return false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 83a040cc17b8..1966033363d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -40,6 +40,7 @@ import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
+import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.user.ui.binder.StatusBarUserChipViewBinder;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
import com.android.systemui.util.leak.RotationUtils;
@@ -51,7 +52,7 @@ public class PhoneStatusBarView extends FrameLayout {
private final StatusBarContentInsetsProvider mContentInsetsProvider;
private DarkReceiver mBattery;
- private DarkReceiver mClock;
+ private Clock mClock;
private int mRotationOrientation = -1;
@Nullable
private View mCutoutSpace;
@@ -123,6 +124,10 @@ public class PhoneStatusBarView extends FrameLayout {
}
}
+ void onDensityOrFontScaleChanged() {
+ mClock.onDensityOrFontScaleChanged();
+ }
+
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (updateDisplayParameters()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index dd471aa042fa..fc5f91506c06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -75,6 +75,10 @@ private constructor(
override fun onConfigChanged(newConfig: Configuration?) {
mView.updateResources()
}
+
+ override fun onDensityOrFontScaleChanged() {
+ mView.onDensityOrFontScaleChanged()
+ }
}
override fun onViewAttached() {
@@ -82,6 +86,10 @@ private constructor(
statusContainer.setOnHoverListener(
statusOverlayHoverListenerFactory.createDarkAwareListener(statusContainer)
)
+
+ progressProvider?.setReadyToHandleTransition(true)
+ configurationController.addCallback(configurationListener)
+
if (moveFromCenterAnimationController == null) return
val statusBarLeftSide: View =
@@ -106,9 +114,6 @@ private constructor(
moveFromCenterAnimationController.onStatusBarWidthChanged()
}
}
-
- progressProvider?.setReadyToHandleTransition(true)
- configurationController.addCallback(configurationListener)
}
override fun onViewDetached() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 3afbbfddeb8a..e337215089ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -565,7 +565,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
&& !mKeyguardStateController.isOccluded()
&& !mKeyguardStateController.canDismissLockScreen()
&& !bouncerIsAnimatingAway()
- && !mShadeViewController.isUnlockHintRunning()
&& !(mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 249ca35b610a..7ec8e12e557e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.binder
import android.content.res.ColorStateList
import android.view.View
import android.view.View.GONE
-import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ImageView
@@ -34,12 +33,11 @@ import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
-import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
+import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewVisibilityHelper
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -106,20 +104,11 @@ object MobileIconBinder {
launch {
visibilityState.collect { state ->
- when (state) {
- STATE_ICON -> {
- mobileGroupView.visibility = VISIBLE
- dotView.visibility = GONE
- }
- STATE_DOT -> {
- mobileGroupView.visibility = INVISIBLE
- dotView.visibility = VISIBLE
- }
- STATE_HIDDEN -> {
- mobileGroupView.visibility = INVISIBLE
- dotView.visibility = INVISIBLE
- }
- }
+ ModernStatusBarViewVisibilityHelper.setVisibilityState(
+ state,
+ mobileGroupView,
+ dotView,
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewVisibilityHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewVisibilityHelper.kt
new file mode 100644
index 000000000000..6668cbc290fc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewVisibilityHelper.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared.ui.binder
+
+import android.view.View
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
+import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder
+
+/**
+ * The helper to update the groupView and dotView visibility based on given visibility state, only
+ * used for [MobileIconBinder] and [WifiViewBinder] now.
+ */
+class ModernStatusBarViewVisibilityHelper {
+ companion object {
+
+ fun setVisibilityState(
+ @StatusBarIconView.VisibleState state: Int,
+ groupView: View,
+ dotView: View,
+ ) {
+ when (state) {
+ StatusBarIconView.STATE_ICON -> {
+ groupView.visibility = View.VISIBLE
+ dotView.visibility = View.GONE
+ }
+ StatusBarIconView.STATE_DOT -> {
+ groupView.visibility = View.INVISIBLE
+ dotView.visibility = View.VISIBLE
+ }
+ StatusBarIconView.STATE_HIDDEN -> {
+ groupView.visibility = View.INVISIBLE
+ dotView.visibility = View.INVISIBLE
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
index 3082a6629dc2..e593575bd791 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt
@@ -27,10 +27,9 @@ import com.android.systemui.R
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
-import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
+import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewVisibilityHelper
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
import kotlinx.coroutines.InternalCoroutinesApi
@@ -83,8 +82,18 @@ object WifiViewBinder {
launch {
visibilityState.collect { visibilityState ->
- groupView.isVisible = visibilityState == STATE_ICON
- dotView.isVisible = visibilityState == STATE_DOT
+ // for b/296864006, we can not hide all the child views if visibilityState
+ // is STATE_HIDDEN. Because hiding all child views would cause the
+ // getWidth() of this view return 0, and that would cause the translation
+ // calculation fails in StatusIconContainer. Therefore, like class
+ // MobileIconBinder, instead of set the child views visibility to View.GONE,
+ // we set their visibility to View.INVISIBLE to make them invisible but
+ // keep the width.
+ ModernStatusBarViewVisibilityHelper.setVisibilityState(
+ visibilityState,
+ groupView,
+ dotView,
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java
index ba5fa1df4b15..3d51ab0a2b27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java
@@ -45,6 +45,7 @@ public class AospPolicyModule {
BroadcastDispatcher broadcastDispatcher,
DemoModeController demoModeController,
DumpManager dumpManager,
+ BatteryControllerLogger logger,
@Main Handler mainHandler,
@Background Handler bgHandler) {
BatteryController bC = new BatteryControllerImpl(
@@ -54,6 +55,7 @@ public class AospPolicyModule {
broadcastDispatcher,
demoModeController,
dumpManager,
+ logger,
mainHandler,
bgHandler);
bC.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 4b515115dd77..41ed76d7edb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -20,7 +20,6 @@ import static android.os.BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE;
import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT;
import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
import static android.os.BatteryManager.EXTRA_PRESENT;
-
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
import static com.android.systemui.util.DumpUtilsKt.asIndenting;
@@ -85,6 +84,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
private final PowerManager mPowerManager;
private final DemoModeController mDemoModeController;
private final DumpManager mDumpManager;
+ private final BatteryControllerLogger mLogger;
private final Handler mMainHandler;
private final Handler mBgHandler;
protected final Context mContext;
@@ -122,6 +122,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
BroadcastDispatcher broadcastDispatcher,
DemoModeController demoModeController,
DumpManager dumpManager,
+ BatteryControllerLogger logger,
@Main Handler mainHandler,
@Background Handler bgHandler) {
mContext = context;
@@ -132,6 +133,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
mBroadcastDispatcher = broadcastDispatcher;
mDemoModeController = demoModeController;
mDumpManager = dumpManager;
+ mLogger = logger;
+ mLogger.logBatteryControllerInstance(this);
}
private void registerReceiver() {
@@ -145,6 +148,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@Override
public void init() {
+ mLogger.logBatteryControllerInit(this, mHasReceivedBattery);
registerReceiver();
if (!mHasReceivedBattery) {
// Get initial state. Relying on Sticky behavior until API for getting info.
@@ -232,8 +236,13 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@Override
public void onReceive(final Context context, Intent intent) {
final String action = intent.getAction();
+ mLogger.logIntentReceived(action);
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- if (mTestMode && !intent.getBooleanExtra("testmode", false)) return;
+ mLogger.logBatteryChangedIntent(intent);
+ if (mTestMode && !intent.getBooleanExtra("testmode", false)) {
+ mLogger.logBatteryChangedSkipBecauseTest();
+ return;
+ }
mHasReceivedBattery = true;
mLevel = (int) (100f
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
@@ -275,6 +284,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
fireIsIncompatibleChargingChanged();
}
} else if (action.equals(ACTION_LEVEL_TEST)) {
+ mLogger.logEnterTestMode();
mTestMode = true;
mMainHandler.post(new Runnable() {
int mCurrentLevel = 0;
@@ -286,6 +296,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@Override
public void run() {
if (mCurrentLevel < 0) {
+ mLogger.logExitTestMode();
mTestMode = false;
mTestIntent.putExtra("level", mSavedLevel);
mTestIntent.putExtra("plugged", mSavedPluggedIn);
@@ -438,6 +449,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
}
protected void fireBatteryLevelChanged() {
+ mLogger.logBatteryLevelChangedCallback(mLevel, mPluggedIn, mCharging);
synchronized (mChangeCallbacks) {
final int N = mChangeCallbacks.size();
for (int i = 0; i < N; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt
new file mode 100644
index 000000000000..4a2a2dbad638
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.content.Intent
+import android.os.BatteryManager.EXTRA_LEVEL
+import android.os.BatteryManager.EXTRA_SCALE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.policy.dagger.BatteryControllerLog
+import javax.inject.Inject
+
+/** Detailed, [LogBuffer]-backed logs for [BatteryControllerImpl] */
+@SysUISingleton
+class BatteryControllerLogger
+@Inject
+constructor(@BatteryControllerLog private val logBuffer: LogBuffer) {
+ fun logBatteryControllerInstance(controller: BatteryController) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { int1 = System.identityHashCode(controller) },
+ { "BatteryController CREATE (${Integer.toHexString(int1)})" }
+ )
+ }
+
+ fun logBatteryControllerInit(controller: BatteryController, hasReceivedBattery: Boolean) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = System.identityHashCode(controller)
+ bool1 = hasReceivedBattery
+ },
+ { "BatteryController INIT (${Integer.toHexString(int1)}) hasReceivedBattery=$bool1" }
+ )
+ }
+
+ fun logIntentReceived(action: String) {
+ logBuffer.log(TAG, LogLevel.DEBUG, { str1 = action }, { "Received intent $str1" })
+ }
+
+ fun logBatteryChangedIntent(intent: Intent) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = intent.getIntExtra(EXTRA_LEVEL, DEFAULT)
+ int2 = intent.getIntExtra(EXTRA_SCALE, DEFAULT)
+ },
+ { "Processing BATTERY_CHANGED intent. level=${int1.report()} scale=${int2.report()}" }
+ )
+ }
+
+ fun logBatteryChangedSkipBecauseTest() {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "Detected test intent. Will not execute battery level callbacks." }
+ )
+ }
+
+ fun logEnterTestMode() {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "Entering test mode for BATTERY_LEVEL_TEST intent" }
+ )
+ }
+
+ fun logExitTestMode() {
+ logBuffer.log(TAG, LogLevel.DEBUG, {}, { "Exiting test mode" })
+ }
+
+ fun logBatteryLevelChangedCallback(level: Int, plugged: Boolean, charging: Boolean) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = level
+ bool1 = plugged
+ bool2 = charging
+ },
+ {
+ "Sending onBatteryLevelChanged callbacks " +
+ "with level=$int1, plugged=$bool1, charging=$bool2"
+ }
+ )
+ }
+
+ private fun Int.report(): String =
+ if (this == DEFAULT) {
+ "(missing)"
+ } else {
+ toString()
+ }
+
+ companion object {
+ const val TAG: String = "BatteryControllerLog"
+ }
+}
+
+// Use a token value so we can determine if we got the default
+private const val DEFAULT = -11
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index f9943729ac7d..b7ae233c8e52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -37,9 +37,11 @@ import android.text.format.DateFormat;
import android.text.style.CharacterStyle;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.TextView;
import com.android.settingslib.Utils;
@@ -143,6 +145,8 @@ public class Clock extends TextView implements
}
mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
mUserTracker = Dependency.get(UserTracker.class);
+
+ setIncludeFontPadding(false);
}
@Override
@@ -389,6 +393,15 @@ public class Clock extends TextView implements
mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_clock_end_padding),
0);
+
+ float fontHeight = getPaint().getFontMetricsInt(null);
+ setLineHeight(TypedValue.COMPLEX_UNIT_PX, fontHeight);
+
+ ViewGroup.LayoutParams lp = getLayoutParams();
+ if (lp != null) {
+ lp.height = (int) Math.ceil(fontHeight);
+ setLayoutParams(lp);
+ }
}
private void updateShowSeconds() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt
index d5f2d210b9b0..67a8e3d0e345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt
@@ -20,7 +20,6 @@ import android.content.Context
import android.content.res.Configuration
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.CommandQueue
-import com.android.systemui.util.LargeScreenUtils
import javax.inject.Inject
/**
@@ -30,9 +29,10 @@ import javax.inject.Inject
*/
@SysUISingleton
class RemoteInputQuickSettingsDisabler @Inject constructor(
- private val context: Context,
- private val commandQueue: CommandQueue,
- configController: ConfigurationController
+ private val context: Context,
+ private val commandQueue: CommandQueue,
+ private val splitShadeStateController: SplitShadeStateController,
+ configController: ConfigurationController
) : ConfigurationController.ConfigurationListener {
private var remoteInputActive = false
@@ -43,7 +43,7 @@ class RemoteInputQuickSettingsDisabler @Inject constructor(
isLandscape =
context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
shouldUseSplitNotificationShade =
- LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ splitShadeStateController.shouldUseSplitNotificationShade(context.resources)
configController.addCallback(this)
}
@@ -74,7 +74,8 @@ class RemoteInputQuickSettingsDisabler @Inject constructor(
needToRecompute = true
}
- val newSplitShadeFlag = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ val newSplitShadeFlag = splitShadeStateController
+ .shouldUseSplitNotificationShade(context.resources)
if (newSplitShadeFlag != shouldUseSplitNotificationShade) {
shouldUseSplitNotificationShade = newSplitShadeFlag
needToRecompute = true
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt
new file mode 100644
index 000000000000..e71c972266f2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy
+
+import android.content.res.Resources
+import com.android.systemui.R
+
+/**
+ * Fake SplitShadeStateController
+ *
+ * Identical behaviour to legacy implementation (that used LargeScreenUtils.kt) I.E., behaviour
+ * based solely on resources, no extra flag logic.
+ */
+class ResourcesSplitShadeStateController : SplitShadeStateController {
+ override fun shouldUseSplitNotificationShade(resources: Resources): Boolean {
+ return resources.getBoolean(R.bool.config_use_split_notification_shade)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt
new file mode 100644
index 000000000000..f64d4c67ea23
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy
+
+import android.content.res.Resources
+
+/** Source of truth for split shade state: should or should not use split shade. */
+interface SplitShadeStateController {
+ /** Returns true if the device should use the split notification shade. */
+ fun shouldUseSplitNotificationShade(resources: Resources): Boolean
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt
new file mode 100644
index 000000000000..ab4a8afcc3c9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.policy
+
+import android.content.res.Resources
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import javax.inject.Inject
+
+/**
+ * Source of truth for split shade state: should or should not use split shade based on orientation,
+ * screen width, and flags.
+ */
+@SysUISingleton
+class SplitShadeStateControllerImpl @Inject constructor(private val featureFlags: FeatureFlags) :
+ SplitShadeStateController {
+ /**
+ * Returns true if the device should use the split notification shade. Based on orientation,
+ * screen width, and flags.
+ */
+ override fun shouldUseSplitNotificationShade(resources: Resources): Boolean {
+ return (resources.getBoolean(R.bool.config_use_split_notification_shade) ||
+ (featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE) &&
+ resources.getBoolean(R.bool.force_config_use_split_notification_shade)))
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt
new file mode 100644
index 000000000000..5322b3811f95
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy.dagger
+
+import javax.inject.Qualifier
+
+/** Logs for Battery events. See [BatteryControllerImpl] */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class BatteryControllerLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index c2a8e701653a..927024fbdd34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -24,6 +24,8 @@ import com.android.internal.R;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.LogBuffer;
+import com.android.systemui.log.LogBufferFactory;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.connectivity.AccessPointController;
import com.android.systemui.statusbar.connectivity.AccessPointControllerImpl;
@@ -31,6 +33,7 @@ import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.NetworkControllerImpl;
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory;
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
+import com.android.systemui.statusbar.policy.BatteryControllerLogger;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.CastController;
@@ -57,6 +60,8 @@ import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.statusbar.policy.SecurityControllerImpl;
+import com.android.systemui.statusbar.policy.SplitShadeStateController;
+import com.android.systemui.statusbar.policy.SplitShadeStateControllerImpl;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.WalletController;
@@ -110,6 +115,11 @@ public interface StatusBarPolicyModule {
/** */
@Binds
+ SplitShadeStateController provideSplitShadeStateController(
+ SplitShadeStateControllerImpl splitShadeStateControllerImpl);
+
+ /** */
+ @Binds
HotspotController provideHotspotController(HotspotControllerImpl controllerImpl);
/** */
@@ -202,4 +212,13 @@ public interface StatusBarPolicyModule {
static DataSaverController provideDataSaverController(NetworkController networkController) {
return networkController.getDataSaverController();
}
+
+ /** Provides a log bufffer for BatteryControllerImpl */
+ @Provides
+ @SysUISingleton
+ @BatteryControllerLog
+ //TODO(b/300147438): reduce the size of this log buffer
+ static LogBuffer provideBatteryControllerLog(LogBufferFactory factory) {
+ return factory.create(BatteryControllerLogger.TAG, 300);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
index 8b29310cf1c5..9b241a72b708 100644
--- a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
@@ -4,16 +4,6 @@ import android.content.res.Resources
import com.android.systemui.R
object LargeScreenUtils {
-
- /**
- * Returns true if the device should use the split notification shade, based on orientation and
- * screen width.
- */
- @JvmStatic
- fun shouldUseSplitNotificationShade(resources: Resources): Boolean {
- return resources.getBoolean(R.bool.config_use_split_notification_shade)
- }
-
/**
* Returns true if we should use large screen shade header:
* [com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController]
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index e1b608ffb1d6..ee67348c9b93 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -30,6 +30,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.policy.DevicePostureController
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.mockito.whenever
import org.junit.Before
@@ -67,6 +68,7 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var mKeyguardMessageAreaController:
KeyguardMessageAreaController<BouncerKeyguardMessageArea>
+ @Mock private lateinit var postureController: DevicePostureController
private lateinit var keyguardPasswordViewController: KeyguardPasswordViewController
@@ -89,6 +91,7 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
`when`(keyguardPasswordView.resources).thenReturn(context.resources)
val fakeFeatureFlags = FakeFeatureFlags()
fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+ fakeFeatureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false)
keyguardPasswordViewController =
KeyguardPasswordViewController(
keyguardPasswordView,
@@ -104,6 +107,7 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
mContext.resources,
falsingCollector,
keyguardViewController,
+ postureController,
fakeFeatureFlags
)
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 93048a5787b2..0ef9f4533015 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -94,9 +94,10 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
.thenReturn(mKeyguardMessageAreaController)
fakeFeatureFlags = FakeFeatureFlags()
fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, false)
+ fakeFeatureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false)
mKeyguardPatternView =
View.inflate(mContext, R.layout.keyguard_pattern_view, null) as KeyguardPatternView
-
+ mKeyguardPatternView.setIsLockScreenLandscapeEnabled(false)
mKeyguardPatternViewController =
KeyguardPatternViewController(
mKeyguardPatternView,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 7c1861e42d6d..decc457dc452 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -60,6 +60,7 @@ import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.DevicePostureController
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.UserSwitcherController
@@ -140,6 +141,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
@Mock private lateinit var userInteractor: UserInteractor
@Mock private lateinit var faceAuthAccessibilityDelegate: FaceAuthAccessibilityDelegate
@Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
+ @Mock private lateinit var postureController: DevicePostureController
@Captor
private lateinit var swipeListenerArgumentCaptor:
@@ -197,6 +199,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
featureFlags.set(Flags.BOUNCER_USER_SWITCHER, false)
featureFlags.set(Flags.KEYGUARD_WM_STATE_REFACTOR, false)
featureFlags.set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false)
+ featureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false)
keyguardPasswordViewController =
KeyguardPasswordViewController(
@@ -213,6 +216,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
mock(),
null,
keyguardViewController,
+ postureController,
featureFlags
)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 09ff546120c6..0e4b3c9b6a23 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -19,6 +19,7 @@ package com.android.keyguard;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
+import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
import static com.android.systemui.flags.Flags.MIGRATE_LOCK_ICON;
@@ -146,6 +147,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
mFeatureFlags.set(FACE_AUTH_REFACTOR, false);
mFeatureFlags.set(MIGRATE_LOCK_ICON, false);
mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
+ mFeatureFlags.set(LOCKSCREEN_ENABLE_LANDSCAPE, false);
mUnderTest = new LockIconViewController(
mStatusBarStateController,
mKeyguardUpdateMonitor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 7775a05568e8..969a01164734 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -41,7 +41,7 @@ import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
import com.android.systemui.biometrics.data.repository.FakePromptRepository
-import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor
@@ -109,7 +109,7 @@ open class AuthContainerViewTest : SysuiTestCase() {
private val fakeExecutor = FakeExecutor(FakeSystemClock())
private val biometricPromptRepository = FakePromptRepository()
private val fingerprintRepository = FakeFingerprintPropertyRepository()
- private val rearDisplayStateRepository = FakeRearDisplayStateRepository()
+ private val displayStateRepository = FakeDisplayStateRepository()
private val credentialInteractor = FakeCredentialInteractor()
private val bpCredentialInteractor = PromptCredentialInteractor(
Dispatchers.Main.immediate,
@@ -141,7 +141,7 @@ open class AuthContainerViewTest : SysuiTestCase() {
testScope.backgroundScope,
mContext,
fakeExecutor,
- rearDisplayStateRepository,
+ displayStateRepository,
displayRepository,
)
}
@@ -520,6 +520,7 @@ open class AuthContainerViewTest : SysuiTestCase() {
displayStateInteractor,
promptSelectorInteractor,
vibrator,
+ context,
featureFlags
),
{ credentialViewModel },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
index 2bb3785f0eef..8fc63b246c9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
@@ -36,6 +36,7 @@ import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFl
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
import com.android.systemui.user.data.repository.FakeUserRepository
@@ -72,6 +73,7 @@ class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() {
SharedNotificationContainerInteractor(
configurationRepository,
mContext,
+ ResourcesSplitShadeStateController()
)
private lateinit var detector: AuthDialogPanelInteractionDetector
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 3ebc2d6174ad..17928a3da140 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -56,7 +56,7 @@ import com.android.systemui.R
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestableContext
-import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
@@ -117,7 +117,7 @@ class SideFpsControllerTest : SysuiTestCase() {
@Captor lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
private lateinit var displayRepository: FakeDisplayRepository
- private lateinit var rearDisplayStateRepository: FakeRearDisplayStateRepository
+ private lateinit var displayStateRepository: FakeDisplayStateRepository
private lateinit var keyguardBouncerRepository: FakeKeyguardBouncerRepository
private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
private lateinit var displayStateInteractor: DisplayStateInteractor
@@ -145,7 +145,7 @@ class SideFpsControllerTest : SysuiTestCase() {
@Before
fun setup() {
displayRepository = FakeDisplayRepository()
- rearDisplayStateRepository = FakeRearDisplayStateRepository()
+ displayStateRepository = FakeDisplayStateRepository()
keyguardBouncerRepository = FakeKeyguardBouncerRepository()
alternateBouncerInteractor =
AlternateBouncerInteractor(
@@ -161,7 +161,7 @@ class SideFpsControllerTest : SysuiTestCase() {
testScope.backgroundScope,
context,
executor,
- rearDisplayStateRepository,
+ displayStateRepository,
displayRepository,
)
@@ -273,7 +273,7 @@ class SideFpsControllerTest : SysuiTestCase() {
TestCoroutineScope(),
dumpManager
)
- rearDisplayStateRepository.setIsInRearDisplayMode(inRearDisplayMode)
+ displayStateRepository.setIsInRearDisplayMode(inRearDisplayMode)
overlayController =
ArgumentCaptor.forClass(ISidefpsController::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
index dfe8d36504d0..c9c46cbe8420 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
@@ -17,13 +17,21 @@
package com.android.systemui.keyguard.data.repository
import android.hardware.devicestate.DeviceStateManager
+import android.hardware.display.DisplayManager
+import android.os.Handler
+import android.view.Display
+import android.view.DisplayInfo
+import android.view.Surface
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.RearDisplayStateRepository
-import com.android.systemui.biometrics.data.repository.RearDisplayStateRepositoryImpl
+import com.android.systemui.biometrics.data.repository.DisplayStateRepository
+import com.android.systemui.biometrics.data.repository.DisplayStateRepositoryImpl
+import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -38,8 +46,10 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.same
import org.mockito.Captor
import org.mockito.Mock
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
@@ -50,16 +60,19 @@ private const val REAR_DISPLAY_MODE_DEVICE_STATE = 3
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
-class RearDisplayStateRepositoryTest : SysuiTestCase() {
+class DisplayStateRepositoryTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule: MockitoRule = MockitoJUnit.rule()
@Mock private lateinit var deviceStateManager: DeviceStateManager
- private lateinit var underTest: RearDisplayStateRepository
+ @Mock private lateinit var displayManager: DisplayManager
+ @Mock private lateinit var handler: Handler
+ @Mock private lateinit var display: Display
+ private lateinit var underTest: DisplayStateRepository
private val testScope = TestScope(StandardTestDispatcher())
private val fakeExecutor = FakeExecutor(FakeSystemClock())
@Captor
- private lateinit var callbackCaptor: ArgumentCaptor<DeviceStateManager.DeviceStateCallback>
+ private lateinit var displayListenerCaptor: ArgumentCaptor<DisplayManager.DisplayListener>
@Before
fun setUp() {
@@ -69,11 +82,16 @@ class RearDisplayStateRepositoryTest : SysuiTestCase() {
rearDisplayDeviceStates
)
+ mContext = spy(mContext)
+ whenever(mContext.display).thenReturn(display)
+
underTest =
- RearDisplayStateRepositoryImpl(
+ DisplayStateRepositoryImpl(
testScope.backgroundScope,
mContext,
deviceStateManager,
+ displayManager,
+ handler,
fakeExecutor
)
}
@@ -81,16 +99,46 @@ class RearDisplayStateRepositoryTest : SysuiTestCase() {
@Test
fun updatesIsInRearDisplayMode_whenRearDisplayStateChanges() =
testScope.runTest {
- val isInRearDisplayMode = collectLastValue(underTest.isInRearDisplayMode)
+ val isInRearDisplayMode by collectLastValue(underTest.isInRearDisplayMode)
runCurrent()
val callback = deviceStateManager.captureCallback()
callback.onStateChanged(NORMAL_DISPLAY_MODE_DEVICE_STATE)
- assertThat(isInRearDisplayMode()).isFalse()
+ assertThat(isInRearDisplayMode).isFalse()
callback.onStateChanged(REAR_DISPLAY_MODE_DEVICE_STATE)
- assertThat(isInRearDisplayMode()).isTrue()
+ assertThat(isInRearDisplayMode).isTrue()
+ }
+
+ @Test
+ fun updatesCurrentRotation_whenDisplayStateChanges() =
+ testScope.runTest {
+ val currentRotation by collectLastValue(underTest.currentRotation)
+ runCurrent()
+
+ verify(displayManager)
+ .registerDisplayListener(
+ displayListenerCaptor.capture(),
+ same(handler),
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED)
+ )
+
+ whenever(display.getDisplayInfo(any())).then {
+ val info = it.getArgument<DisplayInfo>(0)
+ info.rotation = Surface.ROTATION_90
+ return@then true
+ }
+ displayListenerCaptor.value.onDisplayChanged(Surface.ROTATION_90)
+ assertThat(currentRotation).isEqualTo(DisplayRotation.ROTATION_90)
+
+ whenever(display.getDisplayInfo(any())).then {
+ val info = it.getArgument<DisplayInfo>(0)
+ info.rotation = Surface.ROTATION_180
+ return@then true
+ }
+ displayListenerCaptor.value.onDisplayChanged(Surface.ROTATION_180)
+ assertThat(currentRotation).isEqualTo(DisplayRotation.ROTATION_180)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
index 524f2547ea4c..bf6caad688e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
@@ -3,7 +3,8 @@ package com.android.systemui.biometrics.domain.interactor
import android.view.Display
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
+import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.display.data.repository.FakeDisplayRepository
import com.android.systemui.display.data.repository.display
@@ -37,7 +38,7 @@ class DisplayStateInteractorImplTest : SysuiTestCase() {
private val fakeExecutor = FakeExecutor(FakeSystemClock())
private val testScope = TestScope(StandardTestDispatcher())
- private lateinit var rearDisplayStateRepository: FakeRearDisplayStateRepository
+ private lateinit var displayStateRepository: FakeDisplayStateRepository
private lateinit var displayRepository: FakeDisplayRepository
@Mock private lateinit var screenSizeFoldProvider: ScreenSizeFoldProvider
@@ -45,14 +46,14 @@ class DisplayStateInteractorImplTest : SysuiTestCase() {
@Before
fun setup() {
- rearDisplayStateRepository = FakeRearDisplayStateRepository()
+ displayStateRepository = FakeDisplayStateRepository()
displayRepository = FakeDisplayRepository()
interactor =
DisplayStateInteractorImpl(
testScope.backgroundScope,
mContext,
fakeExecutor,
- rearDisplayStateRepository,
+ displayStateRepository,
displayRepository,
)
interactor.setScreenSizeFoldProvider(screenSizeFoldProvider)
@@ -61,27 +62,39 @@ class DisplayStateInteractorImplTest : SysuiTestCase() {
@Test
fun isInRearDisplayModeChanges() =
testScope.runTest {
- val isInRearDisplayMode = collectLastValue(interactor.isInRearDisplayMode)
+ val isInRearDisplayMode by collectLastValue(interactor.isInRearDisplayMode)
- rearDisplayStateRepository.setIsInRearDisplayMode(false)
- assertThat(isInRearDisplayMode()).isFalse()
+ displayStateRepository.setIsInRearDisplayMode(false)
+ assertThat(isInRearDisplayMode).isFalse()
- rearDisplayStateRepository.setIsInRearDisplayMode(true)
- assertThat(isInRearDisplayMode()).isTrue()
+ displayStateRepository.setIsInRearDisplayMode(true)
+ assertThat(isInRearDisplayMode).isTrue()
+ }
+
+ @Test
+ fun currentRotationChanges() =
+ testScope.runTest {
+ val currentRotation by collectLastValue(interactor.currentRotation)
+
+ displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
+ assertThat(currentRotation).isEqualTo(DisplayRotation.ROTATION_180)
+
+ displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+ assertThat(currentRotation).isEqualTo(DisplayRotation.ROTATION_90)
}
@Test
fun isFoldedChanges() =
testScope.runTest {
- val isFolded = collectLastValue(interactor.isFolded)
+ val isFolded by collectLastValue(interactor.isFolded)
runCurrent()
val callback = screenSizeFoldProvider.captureCallback()
callback.onFoldUpdated(isFolded = true)
- assertThat(isFolded()).isTrue()
+ assertThat(isFolded).isTrue()
callback.onFoldUpdated(isFolded = false)
- assertThat(isFolded()).isFalse()
+ assertThat(isFolded).isFalse()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModelTest.kt
index b3964b619505..fd86486aeff8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModelTest.kt
@@ -4,9 +4,9 @@ import android.content.res.Configuration
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
import com.android.systemui.biometrics.data.repository.FakePromptRepository
-import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
@@ -43,7 +43,7 @@ class PromptFingerprintIconViewModelTest : SysuiTestCase() {
private lateinit var displayRepository: FakeDisplayRepository
private lateinit var fingerprintRepository: FakeFingerprintPropertyRepository
private lateinit var promptRepository: FakePromptRepository
- private lateinit var rearDisplayStateRepository: FakeRearDisplayStateRepository
+ private lateinit var displayStateRepository: FakeDisplayStateRepository
private val testScope = TestScope(StandardTestDispatcher())
private val fakeExecutor = FakeExecutor(FakeSystemClock())
@@ -57,7 +57,7 @@ class PromptFingerprintIconViewModelTest : SysuiTestCase() {
displayRepository = FakeDisplayRepository()
fingerprintRepository = FakeFingerprintPropertyRepository()
promptRepository = FakePromptRepository()
- rearDisplayStateRepository = FakeRearDisplayStateRepository()
+ displayStateRepository = FakeDisplayStateRepository()
promptSelectorInteractor =
PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils)
@@ -66,7 +66,7 @@ class PromptFingerprintIconViewModelTest : SysuiTestCase() {
testScope.backgroundScope,
mContext,
fakeExecutor,
- rearDisplayStateRepository,
+ displayStateRepository,
displayRepository,
)
viewModel = PromptFingerprintIconViewModel(displayStateInteractor, promptSelectorInteractor)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 5834e31cb591..ca6df4027ea9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -24,9 +24,9 @@ import android.view.MotionEvent
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
import com.android.systemui.biometrics.data.repository.FakePromptRepository
-import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
@@ -82,7 +82,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
private lateinit var fingerprintRepository: FakeFingerprintPropertyRepository
private lateinit var promptRepository: FakePromptRepository
- private lateinit var rearDisplayStateRepository: FakeRearDisplayStateRepository
+ private lateinit var displayStateRepository: FakeDisplayStateRepository
private lateinit var displayRepository: FakeDisplayRepository
private lateinit var displayStateInteractor: DisplayStateInteractor
@@ -94,21 +94,22 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
fun setup() {
fingerprintRepository = FakeFingerprintPropertyRepository()
promptRepository = FakePromptRepository()
- rearDisplayStateRepository = FakeRearDisplayStateRepository()
+ displayStateRepository = FakeDisplayStateRepository()
displayRepository = FakeDisplayRepository()
displayStateInteractor =
DisplayStateInteractorImpl(
testScope.backgroundScope,
mContext,
fakeExecutor,
- rearDisplayStateRepository,
+ displayStateRepository,
displayRepository,
)
selector =
PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils)
selector.resetPrompt()
- viewModel = PromptViewModel(displayStateInteractor, selector, vibrator, featureFlags)
+ viewModel =
+ PromptViewModel(displayStateInteractor, selector, vibrator, mContext, featureFlags)
featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 3c5212ae7e5c..8ce738ca89f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -21,6 +21,7 @@ import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
+import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate as Point
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
@@ -30,6 +31,7 @@ import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -67,6 +69,9 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
isInputEnabled = MutableStateFlow(true).asStateFlow(),
)
+ private val containerSize = 90 // px
+ private val dotSize = 30 // px
+
@Before
fun setUp() {
overrideResource(R.string.keyguard_enter_your_pattern, ENTER_YOUR_PATTERN)
@@ -80,13 +85,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
- utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
- )
- utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
- sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ transitionToPatternBouncer()
underTest.onShown()
@@ -103,13 +102,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
- utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
- )
- utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
- sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ transitionToPatternBouncer()
underTest.onShown()
runCurrent()
@@ -127,23 +120,12 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
val currentScene by collectLastValue(sceneInteractor.desiredScene)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
- utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
- )
- utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
- sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ transitionToPatternBouncer()
underTest.onShown()
underTest.onDragStart()
assertThat(currentDot).isNull()
CORRECT_PATTERN.forEachIndexed { index, coordinate ->
- underTest.onDrag(
- xPx = 30f * coordinate.x + 15,
- yPx = 30f * coordinate.y + 15,
- containerSizePx = 90,
- verticalOffsetPx = 0f,
- )
+ dragToCoordinate(coordinate)
assertWithMessage("Wrong selected dots for index $index")
.that(selectedDots)
.isEqualTo(
@@ -176,23 +158,10 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
- utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
- )
- utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
- sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ transitionToPatternBouncer()
underTest.onShown()
underTest.onDragStart()
- CORRECT_PATTERN.subList(0, 3).forEach { coordinate ->
- underTest.onDrag(
- xPx = 30f * coordinate.x + 15,
- yPx = 30f * coordinate.y + 15,
- containerSizePx = 90,
- verticalOffsetPx = 0f,
- )
- }
+ CORRECT_PATTERN.subList(0, 3).forEach { coordinate -> dragToCoordinate(coordinate) }
underTest.onDragEnd()
@@ -203,6 +172,147 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
}
@Test
+ fun onDrag_shouldIncludeDotsThatWereSkippedOverAlongTheSameRow() =
+ testScope.runTest {
+ val selectedDots by collectLastValue(underTest.selectedDots)
+ transitionToPatternBouncer()
+ underTest.onShown()
+
+ /*
+ * Pattern setup, coordinates are (column, row)
+ * 0 1 2
+ * 0 x x x
+ * 1 x x x
+ * 2 x x x
+ */
+ // Select (0,0), Skip over (1,0) and select (2,0)
+ dragOverCoordinates(Point(0, 0), Point(2, 0))
+
+ assertThat(selectedDots)
+ .isEqualTo(
+ listOf(
+ PatternDotViewModel(0, 0),
+ PatternDotViewModel(1, 0),
+ PatternDotViewModel(2, 0)
+ )
+ )
+ }
+
+ @Test
+ fun onDrag_shouldIncludeDotsThatWereSkippedOverAlongTheSameColumn() =
+ testScope.runTest {
+ val selectedDots by collectLastValue(underTest.selectedDots)
+ transitionToPatternBouncer()
+ underTest.onShown()
+
+ /*
+ * Pattern setup, coordinates are (column, row)
+ * 0 1 2
+ * 0 x x x
+ * 1 x x x
+ * 2 x x x
+ */
+ // Select (1,0), Skip over (1,1) and select (1, 2)
+ dragOverCoordinates(Point(1, 0), Point(1, 2))
+
+ assertThat(selectedDots)
+ .isEqualTo(
+ listOf(
+ PatternDotViewModel(1, 0),
+ PatternDotViewModel(1, 1),
+ PatternDotViewModel(1, 2)
+ )
+ )
+ }
+
+ @Test
+ fun onDrag_shouldIncludeDotsThatWereSkippedOverAlongTheDiagonal() =
+ testScope.runTest {
+ val selectedDots by collectLastValue(underTest.selectedDots)
+ transitionToPatternBouncer()
+ underTest.onShown()
+
+ /*
+ * Pattern setup
+ * 0 1 2
+ * 0 x x x
+ * 1 x x x
+ * 2 x x x
+ *
+ * Coordinates are (column, row)
+ * Select (2,0), Skip over (1,1) and select (0, 2)
+ */
+ dragOverCoordinates(Point(2, 0), Point(0, 2))
+
+ assertThat(selectedDots)
+ .isEqualTo(
+ listOf(
+ PatternDotViewModel(2, 0),
+ PatternDotViewModel(1, 1),
+ PatternDotViewModel(0, 2)
+ )
+ )
+ }
+
+ @Test
+ fun onDrag_shouldNotIncludeDotIfItIsNotOnTheLine() =
+ testScope.runTest {
+ val selectedDots by collectLastValue(underTest.selectedDots)
+ transitionToPatternBouncer()
+ underTest.onShown()
+
+ /*
+ * Pattern setup
+ * 0 1 2
+ * 0 x x x
+ * 1 x x x
+ * 2 x x x
+ *
+ * Coordinates are (column, row)
+ */
+ dragOverCoordinates(Point(0, 0), Point(1, 0), Point(2, 0), Point(0, 1))
+
+ assertThat(selectedDots)
+ .isEqualTo(
+ listOf(
+ PatternDotViewModel(0, 0),
+ PatternDotViewModel(1, 0),
+ PatternDotViewModel(2, 0),
+ PatternDotViewModel(0, 1),
+ )
+ )
+ }
+
+ @Test
+ fun onDrag_shouldNotIncludeSkippedOverDotsIfTheyAreAlreadySelected() =
+ testScope.runTest {
+ val selectedDots by collectLastValue(underTest.selectedDots)
+ transitionToPatternBouncer()
+ underTest.onShown()
+
+ /*
+ * Pattern setup
+ * 0 1 2
+ * 0 x x x
+ * 1 x x x
+ * 2 x x x
+ *
+ * Coordinates are (column, row)
+ */
+ dragOverCoordinates(Point(1, 0), Point(1, 1), Point(0, 0), Point(2, 0))
+
+ assertThat(selectedDots)
+ .isEqualTo(
+ listOf(
+ PatternDotViewModel(1, 0),
+ PatternDotViewModel(1, 1),
+ PatternDotViewModel(0, 0),
+ PatternDotViewModel(2, 0),
+ )
+ )
+ }
+
+ @Test
fun onDragEnd_whenPatternTooShort() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.desiredScene)
@@ -252,23 +362,10 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
- utils.authenticationRepository.setAuthenticationMethod(
- AuthenticationMethodModel.Pattern
- )
- utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
- sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
- assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ transitionToPatternBouncer()
underTest.onShown()
underTest.onDragStart()
- CORRECT_PATTERN.subList(2, 7).forEach { coordinate ->
- underTest.onDrag(
- xPx = 30f * coordinate.x + 15,
- yPx = 30f * coordinate.y + 15,
- containerSizePx = 90,
- verticalOffsetPx = 0f,
- )
- }
+ CORRECT_PATTERN.subList(2, 7).forEach { coordinate -> dragToCoordinate(coordinate) }
underTest.onDragEnd()
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
@@ -276,20 +373,36 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
// Enter the correct pattern:
- CORRECT_PATTERN.forEach { coordinate ->
- underTest.onDrag(
- xPx = 30f * coordinate.x + 15,
- yPx = 30f * coordinate.y + 15,
- containerSizePx = 90,
- verticalOffsetPx = 0f,
- )
- }
+ CORRECT_PATTERN.forEach { coordinate -> dragToCoordinate(coordinate) }
underTest.onDragEnd()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
+ private fun dragOverCoordinates(vararg coordinatesDragged: Point) {
+ underTest.onDragStart()
+ coordinatesDragged.forEach { dragToCoordinate(it) }
+ }
+
+ private fun dragToCoordinate(coordinate: Point) {
+ underTest.onDrag(
+ xPx = dotSize * coordinate.x + 15f,
+ yPx = dotSize * coordinate.y + 15f,
+ containerSizePx = containerSize,
+ verticalOffsetPx = 0f,
+ )
+ }
+
+ private fun TestScope.transitionToPatternBouncer() {
+ utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pattern)
+ utils.authenticationRepository.setUnlocked(false)
+ sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason")
+ sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason")
+ assertThat(collectLastValue(sceneInteractor.desiredScene).invoke())
+ .isEqualTo(SceneModel(SceneKey.Bouncer))
+ }
+
companion object {
private const val ENTER_YOUR_PATTERN = "Enter your pattern"
private const val WRONG_PATTERN = "Wrong pattern"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index f234582d792b..a76c88579dca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -41,8 +41,8 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
-import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
@@ -208,7 +208,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
applicationScope = testScope.backgroundScope,
context = context,
mainExecutor = FakeExecutor(FakeSystemClock()),
- rearDisplayStateRepository = FakeRearDisplayStateRepository(),
+ displayStateRepository = FakeDisplayStateRepository(),
displayRepository = displayRepository,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index d1299d40ea12..5939bb50bb25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -16,10 +16,12 @@
package com.android.systemui.media.controls.pipeline
+import android.app.IUriGrantsManager
import android.app.Notification
import android.app.Notification.FLAG_NO_CLEAR
import android.app.Notification.MediaStyle
import android.app.PendingIntent
+import android.app.UriGrantsManager
import android.app.smartspace.SmartspaceAction
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
@@ -27,12 +29,14 @@ import android.app.smartspace.SmartspaceTarget
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
+import android.graphics.ImageDecoder
import android.graphics.drawable.Icon
import android.media.MediaDescription
import android.media.MediaMetadata
import android.media.session.MediaController
import android.media.session.MediaSession
import android.media.session.PlaybackState
+import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.service.notification.StatusBarNotification
@@ -40,6 +44,7 @@ import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.media.utils.MediaConstants
import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.internal.logging.InstanceId
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.InstanceIdSequenceFake
@@ -83,7 +88,9 @@ import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoSession
import org.mockito.junit.MockitoJUnit
+import org.mockito.quality.Strictness
private const val KEY = "KEY"
private const val KEY_2 = "KEY_2"
@@ -149,6 +156,8 @@ class MediaDataManagerTest : SysuiTestCase() {
@Captor lateinit var stateCallbackCaptor: ArgumentCaptor<(String, PlaybackState) -> Unit>
@Captor lateinit var sessionCallbackCaptor: ArgumentCaptor<(String) -> Unit>
@Captor lateinit var smartSpaceConfigBuilderCaptor: ArgumentCaptor<SmartspaceConfig>
+ @Mock private lateinit var ugm: IUriGrantsManager
+ @Mock private lateinit var imageSource: ImageDecoder.Source
private val instanceIdSequence = InstanceIdSequenceFake(1 shl 20)
@@ -159,8 +168,17 @@ class MediaDataManagerTest : SysuiTestCase() {
1
)
+ private lateinit var staticMockSession: MockitoSession
+
@Before
fun setup() {
+ staticMockSession =
+ ExtendedMockito.mockitoSession()
+ .mockStatic<UriGrantsManager>(UriGrantsManager::class.java)
+ .mockStatic<ImageDecoder>(ImageDecoder::class.java)
+ .strictness(Strictness.LENIENT)
+ .startMocking()
+ whenever(UriGrantsManager.getService()).thenReturn(ugm)
foregroundExecutor = FakeExecutor(clock)
backgroundExecutor = FakeExecutor(clock)
uiExecutor = FakeExecutor(clock)
@@ -270,6 +288,7 @@ class MediaDataManagerTest : SysuiTestCase() {
@After
fun tearDown() {
+ staticMockSession.finishMocking()
session.release()
mediaDataManager.destroy()
Settings.Secure.putInt(
@@ -2198,6 +2217,66 @@ class MediaDataManagerTest : SysuiTestCase() {
verify(listener).onMediaDataRemoved(eq(KEY))
}
+ @Test
+ fun testResumeMediaLoaded_hasArtPermission_artLoaded() {
+ // When resume media is loaded and user/app has permission to access the art URI,
+ whenever(
+ ugm.checkGrantUriPermission_ignoreNonSystem(
+ anyInt(),
+ any(),
+ any(),
+ anyInt(),
+ anyInt()
+ )
+ )
+ .thenReturn(1)
+ val artwork = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
+ val uri = Uri.parse("content://example")
+ whenever(ImageDecoder.createSource(any(), eq(uri))).thenReturn(imageSource)
+ whenever(ImageDecoder.decodeBitmap(any(), any())).thenReturn(artwork)
+
+ val desc =
+ MediaDescription.Builder().run {
+ setTitle(SESSION_TITLE)
+ setIconUri(uri)
+ build()
+ }
+ addResumeControlAndLoad(desc)
+
+ // Then the artwork is loaded
+ assertThat(mediaDataCaptor.value.artwork).isNotNull()
+ }
+
+ @Test
+ fun testResumeMediaLoaded_noArtPermission_noArtLoaded() {
+ // When resume media is loaded and user/app does not have permission to access the art URI
+ whenever(
+ ugm.checkGrantUriPermission_ignoreNonSystem(
+ anyInt(),
+ any(),
+ any(),
+ anyInt(),
+ anyInt()
+ )
+ )
+ .thenThrow(SecurityException("Test no permission"))
+ val artwork = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
+ val uri = Uri.parse("content://example")
+ whenever(ImageDecoder.createSource(any(), eq(uri))).thenReturn(imageSource)
+ whenever(ImageDecoder.decodeBitmap(any(), any())).thenReturn(artwork)
+
+ val desc =
+ MediaDescription.Builder().run {
+ setTitle(SESSION_TITLE)
+ setIconUri(uri)
+ build()
+ }
+ addResumeControlAndLoad(desc)
+
+ // Then the artwork is not loaded
+ assertThat(mediaDataCaptor.value.artwork).isNull()
+ }
+
/** Helper function to add a basic media notification and capture the resulting MediaData */
private fun addNotificationAndLoad() {
addNotificationAndLoad(mediaNotification)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt
index 91b0245be8d3..7ad2ce8ae110 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt
@@ -30,6 +30,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.MediaContainerView
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
@@ -90,6 +91,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
settings,
fakeHandler,
configurationController,
+ ResourcesSplitShadeStateController()
)
keyguardMediaController.attachSinglePaneContainer(mediaContainerView)
keyguardMediaController.useSplitShade = false
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
index 2ce236d4ba89..33ed01f115b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
@@ -38,6 +38,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
@@ -120,6 +121,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
notifPanelEvents,
settings,
fakeHandler,
+ ResourcesSplitShadeStateController()
)
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
verify(statusBarStateController).addCallback(statusBarCallback.capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index fcda5f50cef2..8afe095cbaf0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -66,6 +66,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.animation.UniqueObjectHostView;
@@ -524,7 +525,10 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
return new QSFragment(
new RemoteInputQuickSettingsDisabler(
- context, commandQueue, mock(ConfigurationController.class)),
+ context,
+ commandQueue,
+ new ResourcesSplitShadeStateController(),
+ mock(ConfigurationController.class)),
mStatusBarStateController,
commandQueue,
mQSMediaHost,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 6720dae10230..2ac220c1975d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -50,6 +50,7 @@ import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.util.animation.DisappearParameters;
import org.junit.Before;
@@ -110,7 +111,7 @@ public class QSPanelControllerBaseTest extends SysuiTestCase {
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
DumpManager dumpManager) {
super(view, host, qsCustomizerController, true, mediaHost, metricsLogger, uiEventLogger,
- qsLogger, dumpManager);
+ qsLogger, dumpManager, new ResourcesSplitShadeStateController());
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 9d9d0c7de2ad..8a530dd7206c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -18,6 +18,7 @@ import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.settings.brightness.BrightnessController
import com.android.systemui.settings.brightness.BrightnessSliderController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.tuner.TunerService
import com.google.common.truth.Truth.assertThat
import org.junit.After
@@ -91,7 +92,8 @@ class QSPanelControllerTest : SysuiTestCase() {
brightnessControllerFactory,
brightnessSliderFactory,
falsingManager,
- statusBarKeyguardViewManager
+ statusBarKeyguardViewManager,
+ ResourcesSplitShadeStateController()
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index 71ea831e0f92..f188b4e19a2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -29,6 +29,7 @@ import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.plugins.qs.QSTileView
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.leak.RotationUtils
import org.junit.After
import org.junit.Before
@@ -167,7 +168,8 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
metricsLogger,
uiEventLogger,
qsLogger,
- dumpManager) {
+ dumpManager,
+ ResourcesSplitShadeStateController()) {
private var rotation = RotationUtils.ROTATION_NONE
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 4f57fd0d0a92..9130bc266d11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -120,6 +120,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.data.repository.FakeShadeRepository;
import com.android.systemui.shade.data.repository.ShadeRepository;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.shade.transition.ShadeTransitionController;
@@ -172,6 +173,7 @@ import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.kotlin.JavaAdapter;
@@ -320,7 +322,6 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mEmptySpaceClickListenerCaptor;
@Mock protected ActivityStarter mActivityStarter;
@Mock protected KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
- @Mock protected ShadeRepository mShadeRepository;
@Mock private ShadeInteractor mShadeInteractor;
@Mock private JavaAdapter mJavaAdapter;
@Mock private CastController mCastController;
@@ -341,6 +342,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
protected Handler mMainHandler;
protected View.OnLayoutChangeListener mLayoutChangeListener;
protected KeyguardStatusViewController mKeyguardStatusViewController;
+ protected ShadeRepository mShadeRepository;
protected final FalsingManagerFake mFalsingManager = new FalsingManagerFake();
protected final Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
@@ -362,6 +364,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mFakeKeyguardRepository = keyguardInteractorDeps.getRepository();
mKeyguardBottomAreaInteractor = new KeyguardBottomAreaInteractor(mFakeKeyguardRepository);
mKeyguardInteractor = keyguardInteractorDeps.getKeyguardInteractor();
+ mShadeRepository = new FakeShadeRepository();
SystemClock systemClock = new FakeSystemClock();
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
@@ -659,7 +662,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mSharedNotificationContainerInteractor,
mKeyguardViewConfigurator,
mKeyguardFaceAuthInteractor,
- mKeyguardRootView);
+ new ResourcesSplitShadeStateController());
mNotificationPanelViewController.initDependencies(
mCentralSurfaces,
null,
@@ -731,7 +734,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mShadeRepository,
mShadeInteractor,
mJavaAdapter,
- mCastController
+ mCastController,
+ new ResourcesSplitShadeStateController()
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 7aeafeb2a752..6dadd4c3dca9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -197,6 +197,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
@Test
public void getVerticalSpaceForLockscreenShelf_useLockIconBottomPadding_returnsShelfHeight() {
+ enableSplitShade(/* enabled= */ false);
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 20,
/* indicationPadding= */ 0,
@@ -209,6 +210,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
@Test
public void getVerticalSpaceForLockscreenShelf_useIndicationBottomPadding_returnsZero() {
+ enableSplitShade(/* enabled= */ false);
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 0,
/* indicationPadding= */ 30,
@@ -221,6 +223,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
@Test
public void getVerticalSpaceForLockscreenShelf_useAmbientBottomPadding_returnsZero() {
+ enableSplitShade(/* enabled= */ false);
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 0,
/* indicationPadding= */ 0,
@@ -233,6 +236,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
@Test
public void getVerticalSpaceForLockscreenShelf_useLockIconPadding_returnsLessThanShelfHeight() {
+ enableSplitShade(/* enabled= */ false);
setBottomPadding(/* stackScrollLayoutBottom= */ 100,
/* lockIconPadding= */ 10,
/* indicationPadding= */ 8,
@@ -244,6 +248,19 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
}
@Test
+ public void getVerticalSpaceForLockscreenShelf_splitShade() {
+ enableSplitShade(/* enabled= */ true);
+ setBottomPadding(/* stackScrollLayoutBottom= */ 100,
+ /* lockIconPadding= */ 10,
+ /* indicationPadding= */ 8,
+ /* ambientPadding= */ 0);
+
+ when(mNotificationShelfController.getIntrinsicHeight()).thenReturn(5);
+ assertThat(mNotificationPanelViewController.getVerticalSpaceForLockscreenShelf())
+ .isEqualTo(0);
+ }
+
+ @Test
public void testSetPanelScrimMinFractionWhenHeadsUpIsDragged() {
mNotificationPanelViewController.setHeadsUpDraggingStartingHeight(
mNotificationPanelViewController.getMaxPanelHeight() / 2);
@@ -866,37 +883,6 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
}
@Test
- public void testUnlockAnimationDoesNotAffectScrim() {
- mNotificationPanelViewController.onUnlockHintStarted();
- verify(mScrimController).setExpansionAffectsAlpha(false);
- mNotificationPanelViewController.onUnlockHintFinished();
- verify(mScrimController).setExpansionAffectsAlpha(true);
- }
-
- @Test
- public void testUnlockHintAnimation_runs_whenNotInPowerSaveMode_andDozeAmountIsZero() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(false);
- when(mAmbientState.getDozeAmount()).thenReturn(0f);
- mNotificationPanelViewController.startUnlockHintAnimation();
- assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isTrue();
- }
-
- @Test
- public void testUnlockHintAnimation_doesNotRun_inPowerSaveMode() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(true);
- mNotificationPanelViewController.startUnlockHintAnimation();
- assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse();
- }
-
- @Test
- public void testUnlockHintAnimation_doesNotRun_whenDozeAmountNotZero() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(false);
- when(mAmbientState.getDozeAmount()).thenReturn(0.5f);
- mNotificationPanelViewController.startUnlockHintAnimation();
- assertThat(mNotificationPanelViewController.isHintAnimationRunning()).isFalse();
- }
-
- @Test
public void setKeyguardStatusBarAlpha_setsAlphaOnKeyguardStatusBarController() {
float statusBarAlpha = 0.5f;
@@ -1056,36 +1042,6 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
}
@Test
- public void onEmptySpaceClicked_notDozingAndFaceDetectionIsNotRunning_startsUnlockAnimation() {
- StatusBarStateController.StateListener statusBarStateListener =
- mNotificationPanelViewController.getStatusBarStateListener();
- statusBarStateListener.onStateChanged(KEYGUARD);
- mNotificationPanelViewController.setDozing(false, false);
- when(mUpdateMonitor.requestFaceAuth(NOTIFICATION_PANEL_CLICKED)).thenReturn(false);
-
- // This sets the dozing state that is read when onMiddleClicked is eventually invoked.
- mTouchHandler.onTouch(mock(View.class), mDownMotionEvent);
- mEmptySpaceClickListenerCaptor.getValue().onEmptySpaceClicked(0, 0);
-
- verify(mNotificationStackScrollLayoutController).setUnlockHintRunning(true);
- }
-
- @Test
- public void onEmptySpaceClicked_notDozingAndFaceDetectionIsRunning_doesNotStartUnlockHint() {
- StatusBarStateController.StateListener statusBarStateListener =
- mNotificationPanelViewController.getStatusBarStateListener();
- statusBarStateListener.onStateChanged(KEYGUARD);
- mNotificationPanelViewController.setDozing(false, false);
- when(mUpdateMonitor.requestFaceAuth(NOTIFICATION_PANEL_CLICKED)).thenReturn(true);
-
- // This sets the dozing state that is read when onMiddleClicked is eventually invoked.
- mTouchHandler.onTouch(mock(View.class), mDownMotionEvent);
- mEmptySpaceClickListenerCaptor.getValue().onEmptySpaceClicked(0, 0);
-
- verify(mNotificationStackScrollLayoutController, never()).setUnlockHintRunning(true);
- }
-
- @Test
public void onEmptySpaceClicked_whenDozingAndOnKeyguard_doesNotRequestFaceAuth() {
StatusBarStateController.StateListener statusBarStateListener =
mNotificationPanelViewController.getStatusBarStateListener();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
index 577b6e0bc58a..36cf1d96b891 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.plugins.qs.QS
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.whenever
@@ -118,6 +119,7 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
delayableExecutor,
featureFlags,
notificationStackScrollLayoutController,
+ ResourcesSplitShadeStateController()
)
overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
@@ -474,6 +476,7 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
delayableExecutor,
featureFlags,
notificationStackScrollLayoutController,
+ ResourcesSplitShadeStateController()
)
controller.updateConstraints()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
index 405199ed4ecb..090bee2c772e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.plugins.qs.QS
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.whenever
@@ -117,6 +118,7 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() {
delayableExecutor,
featureFlags,
notificationStackScrollLayoutController,
+ ResourcesSplitShadeStateController()
)
overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
@@ -457,6 +459,7 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() {
delayableExecutor,
featureFlags,
notificationStackScrollLayoutController,
+ ResourcesSplitShadeStateController()
)
controller.updateConstraints()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
index 46b636b264be..849127ed10e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
@@ -75,6 +75,7 @@ import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.user.domain.interactor.UserInteractor;
import com.android.systemui.util.kotlin.JavaAdapter;
@@ -182,7 +183,8 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase {
mUserInteractor,
new SharedNotificationContainerInteractor(
new FakeConfigurationRepository(),
- mContext),
+ mContext,
+ new ResourcesSplitShadeStateController()),
mShadeRepository
);
@@ -260,7 +262,8 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase {
mShadeRepository,
mShadeInteractor,
new JavaAdapter(mTestScope.getBackgroundScope()),
- mCastController
+ mCastController,
+ new ResourcesSplitShadeStateController()
);
mQsController.init();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
index 8f8b840b03c9..7d5f68e783d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
@@ -130,7 +130,7 @@ class ShadeHeaderControllerTest : SysuiTestCase() {
var viewVisibility = View.GONE
var viewAlpha = 1f
- private val systemIcons = LinearLayout(context)
+ private val systemIconsHoverContainer = LinearLayout(context)
private lateinit var shadeHeaderController: ShadeHeaderController
private lateinit var carrierIconSlots: List<String>
private val configurationController = FakeConfigurationController()
@@ -150,7 +150,8 @@ class ShadeHeaderControllerTest : SysuiTestCase() {
.thenReturn(batteryMeterView)
whenever<StatusIconContainer>(view.requireViewById(R.id.statusIcons)).thenReturn(statusIcons)
- whenever<View>(view.requireViewById(R.id.shade_header_system_icons)).thenReturn(systemIcons)
+ whenever<View>(view.requireViewById(R.id.hover_system_icons_container))
+ .thenReturn(systemIconsHoverContainer)
viewContext = Mockito.spy(context)
whenever(view.context).thenReturn(viewContext)
@@ -457,12 +458,12 @@ class ShadeHeaderControllerTest : SysuiTestCase() {
}
@Test
- fun testLargeScreenActive_collapseActionRun_onSystemIconsClick() {
+ fun testLargeScreenActive_collapseActionRun_onSystemIconsHoverContainerClick() {
shadeHeaderController.largeScreenActive = true
var wasRun = false
shadeHeaderController.shadeCollapseAction = Runnable { wasRun = true }
- systemIcons.performClick()
+ systemIconsHoverContainer.performClick()
assertThat(wasRun).isTrue()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
index dd6ab73b7d11..9275ccb6d473 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
@@ -45,6 +45,7 @@ import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFl
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
import com.android.systemui.user.data.model.UserSwitcherSettingsModel
@@ -85,6 +86,7 @@ class ShadeInteractorTest : SysuiTestCase() {
SharedNotificationContainerInteractor(
configurationRepository,
mContext,
+ ResourcesSplitShadeStateController()
)
@Mock private lateinit var manager: UserManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index e086712308b6..19d59fd4f1b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -151,6 +151,24 @@ class ShadeRepositoryImplTest : SysuiTestCase() {
}
@Test
+ fun updateLegacyShadeTracking() =
+ testScope.runTest {
+ assertThat(underTest.legacyShadeTracking.value).isEqualTo(false)
+
+ underTest.setLegacyShadeTracking(true)
+ assertThat(underTest.legacyShadeTracking.value).isEqualTo(true)
+ }
+
+ @Test
+ fun updateLegacyQsTracking() =
+ testScope.runTest {
+ assertThat(underTest.legacyQsTracking.value).isEqualTo(false)
+
+ underTest.setLegacyQsTracking(true)
+ assertThat(underTest.legacyQsTracking.value).isEqualTo(true)
+ }
+
+ @Test
fun updateUdfpsTransitionToFullShadeProgress() =
testScope.runTest {
assertThat(underTest.udfpsTransitionToFullShadeProgress.value).isEqualTo(0f)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt
index 8309342d2c60..36f82c2a0e1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt
@@ -5,6 +5,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.google.common.truth.Expect
import org.junit.Rule
import org.junit.Test
@@ -23,7 +24,8 @@ class LargeScreenShadeInterpolatorImplTest : SysuiTestCase() {
configurationController,
context,
splitShadeInterpolator,
- portraitShadeInterpolator
+ portraitShadeInterpolator,
+ ResourcesSplitShadeStateController()
)
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
index d5a1f804e6a0..7737b4313e3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
@@ -9,6 +9,7 @@ import com.android.systemui.shade.ShadeExpansionChangeEvent
import com.android.systemui.shade.ShadeExpansionStateManager
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -41,6 +42,7 @@ class ShadeTransitionControllerTest : SysuiTestCase() {
context,
scrimShadeTransitionController,
statusBarStateController,
+ ResourcesSplitShadeStateController()
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
index 70412626420d..673d63f3a07d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt
@@ -23,6 +23,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.google.common.truth.Expect
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -59,7 +60,8 @@ class LockscreenShadeQsTransitionControllerTest : SysuiTestCase() {
context,
configurationController,
dumpManager,
- qsProvider = { qS }
+ qsProvider = { qS },
+ ResourcesSplitShadeStateController()
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 2446234bb022..2c9dfcc25324 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.mockito.mock
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
@@ -110,6 +111,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
private val sharedNotificationContainerInteractor = SharedNotificationContainerInteractor(
configurationRepository,
mContext,
+ ResourcesSplitShadeStateController()
)
private val shadeInteractor =
ShadeInteractor(
@@ -172,7 +174,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
scrimController,
context,
configurationController,
- dumpManager
+ dumpManager,
+ ResourcesSplitShadeStateController()
),
keyguardTransitionControllerFactory = { notificationPanelController ->
LockscreenShadeKeyguardTransitionController(
@@ -180,7 +183,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
notificationPanelController,
context,
configurationController,
- dumpManager
+ dumpManager,
+ ResourcesSplitShadeStateController()
)
},
qsTransitionControllerFactory = { qsTransitionController },
@@ -188,6 +192,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
shadeRepository = FakeShadeRepository(),
shadeInteractor = shadeInteractor,
powerInteractor = powerInteractor,
+ splitShadeStateController = ResourcesSplitShadeStateController()
)
transitionController.addCallback(transitionControllerCallback)
whenever(nsslController.view).thenReturn(stackscroller)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index c49f179c925e..a258f67932bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -33,6 +33,7 @@ import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.WallpaperController
import com.android.systemui.util.mockito.eq
@@ -114,8 +115,9 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
notificationShadeWindowController,
dozeParameters,
context,
+ ResourcesSplitShadeStateController(),
dumpManager,
- configurationController)
+ configurationController,)
notificationShadeDepthController.shadeAnimation = shadeAnimation
notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring
notificationShadeDepthController.root = root
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
index 580463a3010f..88ddc2d9ef03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.statusbar.disableflags.DisableFlagsLogger
import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
@@ -56,6 +57,7 @@ class DisableFlagsRepositoryTest : SysuiTestCase() {
RemoteInputQuickSettingsDisabler(
context,
commandQueue,
+ ResourcesSplitShadeStateController(),
configurationController,
)
private val logBuffer = LogBufferFactory(DumpManager(), mock()).create("buffer", 10)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
new file mode 100644
index 000000000000..c650e01263bc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.statusbar.notification.row
+
+import android.graphics.BitmapFactory
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
+import android.net.Uri
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.NotificationDrawableConsumer
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.graphics.ImageLoader
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
+
+private const val FREE_IMAGE_DELAY_MS = 4000L
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class BigPictureIconManagerTest : SysuiTestCase() {
+
+ private val testDispatcher = StandardTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
+ private val testableResources = context.orCreateTestableResources
+ private val imageLoader: ImageLoader = ImageLoader(context, testDispatcher)
+ private var mockConsumer: NotificationDrawableConsumer = mock()
+ private val drawableCaptor = argumentCaptor<Drawable>()
+
+ private lateinit var iconManager: BigPictureIconManager
+
+ private val expectedDrawable by lazy {
+ context.resources.getDrawable(R.drawable.dessert_zombiegingerbread, context.theme)
+ }
+ private val supportedIcon by lazy {
+ Icon.createWithContentUri(
+ Uri.parse(
+ "android.resource://${context.packageName}/${R.drawable.dessert_zombiegingerbread}"
+ )
+ )
+ }
+ private val unsupportedIcon by lazy {
+ Icon.createWithBitmap(
+ BitmapFactory.decodeResource(context.resources, R.drawable.dessert_zombiegingerbread)
+ )
+ }
+ private val invalidIcon by lazy { Icon.createWithContentUri(Uri.parse("this.is/broken")) }
+
+ @Before
+ fun setUp() {
+ iconManager =
+ BigPictureIconManager(
+ context,
+ imageLoader,
+ scope = testScope,
+ mainDispatcher = testDispatcher,
+ bgDispatcher = testDispatcher
+ )
+ }
+
+ @Test
+ fun onIconUpdated_supportedType_placeholderLoaded() =
+ testScope.runTest {
+ // WHEN update with a supported icon
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+
+ // THEN consumer is updated with a placeholder
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsPlaceHolder(drawableCaptor.value)
+ assertSize(drawableCaptor.value)
+ }
+
+ @Test
+ fun onIconUpdated_notSupportedType_fullImageLoaded() =
+ testScope.runTest {
+ // WHEN update with an unsupported icon
+ iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+
+ // THEN consumer is updated with the full image
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsFullImage(drawableCaptor.value)
+ assertSize(drawableCaptor.value)
+ }
+
+ @Test
+ fun onIconUpdated_invalidIcon_drawableIsNull() =
+ testScope.runTest {
+ // WHEN update with an invalid icon
+ iconManager.updateIcon(mockConsumer, invalidIcon).run()
+
+ // THEN consumer is updated with null
+ verify(mockConsumer).setImageDrawable(null)
+ }
+
+ @Test
+ fun onIconUpdated_consumerAlreadySet_nothingHappens() =
+ testScope.runTest {
+ // GIVEN a consumer is set
+ val otherConsumer: NotificationDrawableConsumer = mock()
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ reset(mockConsumer)
+
+ // WHEN a new consumer is set
+ iconManager.updateIcon(otherConsumer, unsupportedIcon).run()
+
+ // THEN nothing happens
+ verifyZeroInteractions(mockConsumer, otherConsumer)
+ }
+
+ @Test
+ fun onIconUpdated_iconAlreadySet_loadsNewIcon() =
+ testScope.runTest {
+ // GIVEN an icon is set
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ reset(mockConsumer)
+
+ // WHEN a new icon is set
+ iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+
+ // THEN consumer is updated with the new image
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsFullImage(drawableCaptor.value)
+ assertSize(drawableCaptor.value)
+ }
+
+ @Test
+ fun onIconUpdated_supportedTypeButTooWide_resizedPlaceholderLoaded() =
+ testScope.runTest {
+ // GIVEN the max width is smaller than our image
+ testableResources.addOverride(
+ com.android.internal.R.dimen.notification_big_picture_max_width,
+ 20
+ )
+ iconManager.updateMaxImageSizes()
+
+ // WHEN update with a supported icon
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+
+ // THEN consumer is updated with the resized placeholder
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsPlaceHolder(drawableCaptor.value)
+ assertSize(drawableCaptor.value, expectedWidth = 20, expectedHeight = 20)
+ }
+
+ @Test
+ fun onIconUpdated_supportedTypeButTooHigh_resizedPlaceholderLoaded() =
+ testScope.runTest {
+ // GIVEN the max height is smaller than our image
+ testableResources.addOverride(
+ com.android.internal.R.dimen.notification_big_picture_max_height,
+ 20
+ )
+ iconManager.updateMaxImageSizes()
+
+ // WHEN update with a supported icon
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+
+ // THEN consumer is updated with the resized placeholder
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsPlaceHolder(drawableCaptor.value)
+ assertSize(drawableCaptor.value, expectedWidth = 20, expectedHeight = 20)
+ }
+
+ @Test
+ fun onViewShown_placeholderShowing_fullImageLoaded() =
+ testScope.runTest {
+ // GIVEN placeholder is showing
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ reset(mockConsumer)
+
+ // WHEN the view is shown
+ iconManager.onViewShown(true)
+ runCurrent()
+
+ // THEN full image is set
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsFullImage(drawableCaptor.value)
+ assertSize(drawableCaptor.value)
+ }
+
+ @Test
+ fun onViewHidden_fullImageShowing_placeHolderSet() =
+ testScope.runTest {
+ // GIVEN full image is showing and the view is shown
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ iconManager.onViewShown(true)
+ runCurrent()
+ reset(mockConsumer)
+
+ // WHEN the view goes off the screen
+ iconManager.onViewShown(false)
+ // AND we wait a bit
+ advanceTimeBy(FREE_IMAGE_DELAY_MS)
+ runCurrent()
+
+ // THEN placeholder is set
+ verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
+ assertIsPlaceHolder(drawableCaptor.value)
+ assertSize(drawableCaptor.value)
+ }
+
+ @Test
+ fun onViewShownToggled_viewShown_nothingHappens() =
+ testScope.runTest {
+ // GIVEN full image is showing and the view is shown
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ iconManager.onViewShown(true)
+ runCurrent()
+ reset(mockConsumer)
+
+ // WHEN the onViewShown is toggled
+ iconManager.onViewShown(false)
+ runCurrent()
+ iconManager.onViewShown(true)
+ // AND we wait a bit
+ advanceTimeBy(FREE_IMAGE_DELAY_MS)
+ runCurrent()
+
+ // THEN nothing happens
+ verifyZeroInteractions(mockConsumer)
+ }
+
+ // nice to have tests
+
+ @Test
+ fun onViewShown_fullImageLoaded_nothingHappens() =
+ testScope.runTest {
+ // GIVEN full image is showing
+ iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+ reset(mockConsumer)
+
+ // WHEN the view is shown
+ iconManager.onViewShown(true)
+ runCurrent()
+
+ // THEN nothing happens
+ verifyZeroInteractions(mockConsumer)
+ }
+
+ @Test
+ fun onViewHidden_placeholderShowing_nothingHappens() =
+ testScope.runTest {
+ // GIVEN placeholder image is showing
+ iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+ reset(mockConsumer)
+
+ // WHEN the view is hidden
+ iconManager.onViewShown(false)
+ // AND we wait a bit
+ advanceTimeBy(FREE_IMAGE_DELAY_MS)
+ runCurrent()
+
+ // THEN nothing happens
+ verifyZeroInteractions(mockConsumer)
+ }
+
+ @Test
+ fun onViewShown_alreadyShowing_nothingHappens() =
+ testScope.runTest {
+ // GIVEN full image is showing and the view is shown
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ iconManager.onViewShown(true)
+ runCurrent()
+ reset(mockConsumer)
+
+ // WHEN view shown called again
+ iconManager.onViewShown(true)
+ runCurrent()
+
+ verifyZeroInteractions(mockConsumer)
+ }
+
+ @Test
+ fun onViewHidden_alreadyHidden_nothingHappens() =
+ testScope.runTest {
+ // GIVEN placeholder image is showing and the view is hidden
+ iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
+ iconManager.onViewShown(false)
+ advanceTimeBy(FREE_IMAGE_DELAY_MS)
+ runCurrent()
+ reset(mockConsumer)
+
+ // WHEN the view is hidden again
+ iconManager.onViewShown(false)
+ // AND we wait a bit
+ advanceTimeBy(FREE_IMAGE_DELAY_MS)
+ runCurrent()
+
+ // THEN nothing happens
+ verifyZeroInteractions(mockConsumer)
+ }
+
+ @Test
+ fun cancelJobs_freeImageJobRunning_jobCancelled() =
+ testScope.runTest {
+ // GIVEN full image is showing
+ iconManager.updateIcon(mockConsumer, supportedIcon).run()
+ iconManager.onViewShown(true)
+ runCurrent()
+ reset(mockConsumer)
+ // AND the view has just gone off the screen
+ iconManager.onViewShown(false)
+
+ // WHEN cancelJobs is called
+ iconManager.cancelJobs()
+ // AND we wait a bit
+ advanceTimeBy(FREE_IMAGE_DELAY_MS)
+ runCurrent()
+
+ // THEN no more updates are happening
+ verifyZeroInteractions(mockConsumer)
+ }
+
+ private fun assertIsPlaceHolder(drawable: Drawable) {
+ assertThat(drawable).isInstanceOf(PlaceHolderDrawable::class.java)
+ }
+
+ private fun assertIsFullImage(drawable: Drawable) {
+ assertThat(drawable).isInstanceOf(BitmapDrawable::class.java)
+ }
+
+ private fun assertSize(
+ drawable: Drawable,
+ expectedWidth: Int = expectedDrawable.intrinsicWidth,
+ expectedHeight: Int = expectedDrawable.intrinsicHeight
+ ) {
+ assertThat(drawable.intrinsicWidth).isEqualTo(expectedWidth)
+ assertThat(drawable.intrinsicHeight).isEqualTo(expectedHeight)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 79cf932a1880..b3f5ea26f9f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -95,6 +95,7 @@ import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.settings.SecureSettings;
@@ -713,7 +714,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mNotificationTargetsHelper,
mSecureSettings,
mock(NotificationDismissibilityProvider.class),
- mActivityStarter
+ mActivityStarter,
+ new ResourcesSplitShadeStateController()
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 72fcdec3c44c..4307066e2d44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -87,6 +87,7 @@ import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import org.junit.Assert;
import org.junit.Before;
@@ -322,26 +323,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
- public void setUnlockHintRunning_updatesStackEndHeightOnlyOnFinish() {
- final float expansionFraction = 0.5f;
- mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
- mStackScroller.setUnlockHintRunning(true);
-
- // Validate that when the animation is running, we update only the stackHeight
- clearInvocations(mAmbientState);
- mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
- verify(mAmbientState, never()).setStackEndHeight(anyFloat());
- verify(mAmbientState).setStackHeight(anyFloat());
-
- // Validate that when the animation ends the stackEndHeight is recalculated immediately
- clearInvocations(mAmbientState);
- mStackScroller.setUnlockHintRunning(false);
- verify(mAmbientState).setUnlockHintRunning(eq(false));
- verify(mAmbientState).setStackEndHeight(anyFloat());
- verify(mAmbientState).setStackHeight(anyFloat());
- }
-
- @Test
public void testNotDimmedOnKeyguard() {
when(mBarState.getState()).thenReturn(StatusBarState.SHADE);
mStackScroller.setDimmed(true /* dimmed */, false /* animate */);
@@ -865,6 +846,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
public void testSplitShade_hasTopOverscroll() {
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
+ mStackScroller.passSplitShadeStateController(new ResourcesSplitShadeStateController());
mStackScroller.updateSplitNotificationShade();
mAmbientState.setExpansionFraction(1f);
@@ -880,6 +862,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
public void testNormalShade_hasNoTopOverscroll() {
mTestableResources
.addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
+ mStackScroller.passSplitShadeStateController(new ResourcesSplitShadeStateController());
mStackScroller.updateSplitNotificationShade();
mAmbientState.setExpansionFraction(1f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index 5279740a8702..bc12bb0fca4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -30,6 +30,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
@@ -70,7 +71,8 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
statusBarStateController = sysuiStatusBarStateController,
lockscreenShadeTransitionController = lockscreenShadeTransitionController,
mediaDataManager = mediaDataManager,
- testableResources.resources
+ testableResources.resources,
+ ResourcesSplitShadeStateController()
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
index 7bbb09483b5f..7fc399b44795 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
@@ -23,6 +23,7 @@ import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -43,6 +44,7 @@ class SharedNotificationContainerInteractorTest : SysuiTestCase() {
SharedNotificationContainerInteractor(
configurationRepository,
mContext,
+ ResourcesSplitShadeStateController()
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 521069f15569..bfc09103ba41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCa
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.user.domain.interactor.UserInteractor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
@@ -106,6 +107,7 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
SharedNotificationContainerInteractor(
configurationRepository,
mContext,
+ ResourcesSplitShadeStateController()
)
shadeInteractor =
ShadeInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 4349d738b0f3..3a629e642d3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -104,6 +104,21 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
}
@Test
+ fun onViewAttachedAndDrawn_startListeningConfigurationControllerCallback() {
+ val view = createViewMock()
+ val argumentCaptor = ArgumentCaptor.forClass(
+ ConfigurationController.ConfigurationListener::class.java)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ controller = createAndInitController(view)
+ }
+
+ verify(configurationController).addCallback(argumentCaptor.capture())
+ argumentCaptor.value.onDensityOrFontScaleChanged()
+
+ verify(view).onDensityOrFontScaleChanged()
+ }
+
+ @Test
fun onViewAttachedAndDrawn_moveFromCenterAnimationEnabled_moveFromCenterAnimationInitialized() {
whenever(featureFlags.isEnabled(Flags.ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS)).thenReturn(true)
val view = createViewMock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 798c3f95b47b..ba4e8d325abc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -268,7 +268,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
@Test
public void onPanelExpansionChanged_neverShowsDuringHintAnimation() {
- when(mShadeViewController.isUnlockHintRunning()).thenReturn(true);
mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index a0d4d1390b2c..bbf048d6697f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -22,6 +22,7 @@ import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.testing.ViewUtils
import android.view.View
+import android.view.ViewGroup
import android.widget.ImageView
import androidx.test.filters.SmallTest
import com.android.systemui.R
@@ -138,7 +139,7 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() {
ViewUtils.attachView(view)
testableLooper.processAllMessages()
- assertThat(view.getIconGroupView().visibility).isEqualTo(View.GONE)
+ assertThat(view.getIconGroupView().visibility).isEqualTo(View.INVISIBLE)
assertThat(view.getDotView().visibility).isEqualTo(View.VISIBLE)
ViewUtils.detachView(view)
@@ -153,8 +154,36 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() {
ViewUtils.attachView(view)
testableLooper.processAllMessages()
- assertThat(view.getIconGroupView().visibility).isEqualTo(View.GONE)
- assertThat(view.getDotView().visibility).isEqualTo(View.GONE)
+ assertThat(view.getIconGroupView().visibility).isEqualTo(View.INVISIBLE)
+ assertThat(view.getDotView().visibility).isEqualTo(View.INVISIBLE)
+
+ ViewUtils.detachView(view)
+ }
+
+ /* Regression test for b/296864006. When STATE_HIDDEN we need to ensure the wifi view width
+ * would not break the StatusIconContainer translation calculation. */
+ @Test
+ fun setVisibleState_hidden_keepWidth() {
+ val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
+
+ view.setVisibleState(STATE_ICON, /* animate= */ false)
+
+ // get the view width when it's in visible state
+ ViewUtils.attachView(view)
+ val lp = view.layoutParams
+ lp.width = ViewGroup.LayoutParams.WRAP_CONTENT
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ view.layoutParams = lp
+ testableLooper.processAllMessages()
+ val currentWidth = view.width
+
+ view.setVisibleState(STATE_HIDDEN, /* animate= */ false)
+ testableLooper.processAllMessages()
+
+ // the view width when STATE_HIDDEN should be at least the width when STATE_ICON. Because
+ // when STATE_HIDDEN the invisible dot view width might be larger than group view width,
+ // then the wifi view width would be enlarged.
+ assertThat(view.width).isAtLeast(currentWidth)
ViewUtils.detachView(view)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index cdeb59278851..58d93c98f015 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -17,12 +17,10 @@
package com.android.systemui.statusbar.policy;
import static android.os.BatteryManager.EXTRA_PRESENT;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
-
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -91,6 +89,7 @@ public class BatteryControllerTest extends SysuiTestCase {
mBroadcastDispatcher,
mDemoModeController,
mock(DumpManager.class),
+ mock(BatteryControllerLogger.class),
new Handler(),
new Handler());
// Can throw if updateEstimate is called on the main thread
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
index 1ab0582a6c5b..cfb48a8f6995 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
@@ -49,7 +49,9 @@ class RemoteInputQuickSettingsDisablerTest : SysuiTestCase() {
remoteInputQuickSettingsDisabler = RemoteInputQuickSettingsDisabler(
mContext,
- commandQueue, Mockito.mock(ConfigurationController::class.java)
+ commandQueue,
+ ResourcesSplitShadeStateController(),
+ Mockito.mock(ConfigurationController::class.java),
)
configuration = Configuration(mContext.resources.configuration)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 65cac6efad1c..3152fd14bf48 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -44,6 +44,7 @@ import android.media.AudioManager;
import android.os.SystemClock;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.Log;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -98,6 +99,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
private ConfigurationController mConfigurationController;
private int mOriginalOrientation;
+ private static final String TAG = "VolumeDialogImplTest";
+
@Mock
VolumeDialogController mVolumeDialogController;
@Mock
@@ -674,12 +677,20 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@After
public void teardown() {
+ // Detailed logs to track down timeout issues in b/299491332
+ Log.d(TAG, "teardown: entered");
setOrientation(mOriginalOrientation);
+ Log.d(TAG, "teardown: after setOrientation");
mAnimatorTestRule.advanceTimeBy(mLongestHideShowAnimationDuration);
+ Log.d(TAG, "teardown: after advanceTimeBy");
mTestableLooper.moveTimeForward(mLongestHideShowAnimationDuration);
+ Log.d(TAG, "teardown: after moveTimeForward");
mTestableLooper.processAllMessages();
+ Log.d(TAG, "teardown: after processAllMessages");
reset(mPostureController);
+ Log.d(TAG, "teardown: after reset");
cleanUp(mDialog);
+ Log.d(TAG, "teardown: after cleanUp");
}
private void cleanUp(VolumeDialogImpl dialog) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeRearDisplayStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
index fd9139165c85..60291eece70b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeRearDisplayStateRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
@@ -17,15 +17,23 @@
package com.android.systemui.biometrics.data.repository
+import com.android.systemui.biometrics.shared.model.DisplayRotation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
-class FakeRearDisplayStateRepository : RearDisplayStateRepository {
+class FakeDisplayStateRepository : DisplayStateRepository {
private val _isInRearDisplayMode = MutableStateFlow<Boolean>(false)
override val isInRearDisplayMode: StateFlow<Boolean> = _isInRearDisplayMode.asStateFlow()
+ private val _currentRotation = MutableStateFlow<DisplayRotation>(DisplayRotation.ROTATION_0)
+ override val currentRotation: StateFlow<DisplayRotation> = _currentRotation.asStateFlow()
+
fun setIsInRearDisplayMode(isInRearDisplayMode: Boolean) {
_isInRearDisplayMode.value = isInRearDisplayMode
}
+
+ fun setCurrentRotation(currentRotation: DisplayRotation) {
+ _currentRotation.value = currentRotation
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
index 08152a3c49cd..e72544a24740 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
@@ -40,6 +40,23 @@ class FakeShadeRepository : ShadeRepository {
@Deprecated("Use ShadeInteractor instead")
override val legacyShadeExpansion = _legacyShadeExpansion
+ private val _legacyShadeTracking = MutableStateFlow(false)
+ @Deprecated("Use ShadeInteractor instead")
+ override val legacyShadeTracking = _legacyShadeTracking
+
+ private val _legacyQsTracking = MutableStateFlow(false)
+ @Deprecated("Use ShadeInteractor instead") override val legacyQsTracking = _legacyQsTracking
+
+ @Deprecated("Should only be called by NPVC and tests")
+ override fun setLegacyQsTracking(legacyQsTracking: Boolean) {
+ _legacyQsTracking.value = legacyQsTracking
+ }
+
+ @Deprecated("Should only be called by NPVC and tests")
+ override fun setLegacyShadeTracking(tracking: Boolean) {
+ _legacyShadeTracking.value = tracking
+ }
+
fun setShadeModel(model: ShadeModel) {
_shadeModel.value = model
}
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index b5fc2b6be22d..3709f4714a4f 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -1,7 +1,22 @@
package: "com.android.server.accessibility"
+
flag {
name: "proxy_use_apps_on_virtual_device_listener"
namespace: "accessibility"
description: "Fixes race condition described in b/286587811"
bug: "286587811"
}
+
+flag {
+ name: "enable_magnification_multiple_finger_multiple_tap_gesture"
+ namespace: "accessibility"
+ description: "Whether to enable multi-finger-multi-tap gesture for magnification"
+ bug: "257274411"
+}
+
+flag {
+ name: "enable_magnification_joystick"
+ namespace: "accessibility"
+ description: "Whether to enable joystick controls for magnification"
+ bug: "297211257"
+} \ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index ebb127d888d3..2ca84f884f78 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -217,7 +217,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
if (!activated) {
- clearAndTransitionToStateDetecting();
+ // cancel the magnification shortcut
+ mDetectingState.setShortcutTriggered(false);
}
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 330e35b5aeca..ba4533960db4 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -887,6 +887,11 @@ public class CompanionDeviceManagerService extends SystemService {
@Override
public PermissionSyncRequest getPermissionSyncRequest(int associationId) {
+ // TODO: temporary fix, will remove soon
+ AssociationInfo association = mAssociationStore.getAssociationById(associationId);
+ if (association == null) {
+ return null;
+ }
getAssociationWithCallerChecks(associationId);
return mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
index 42b5a8ba8a4d..e5c847acad6e 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -139,7 +139,7 @@ public class SystemDataTransferProcessor {
@UserIdInt int userId, int associationId) {
if (PackageUtils.isPackageAllowlisted(mContext, mPackageManager, packageName)) {
Slog.i(LOG_TAG, "User consent Intent should be skipped. Returning null.");
- // Auto enable perm sync for the whitelisted packages, but don't override user decision
+ // Auto enable perm sync for the allowlisted packages, but don't override user decision
PermissionSyncRequest request = getPermissionSyncRequest(associationId);
if (request == null) {
PermissionSyncRequest newRequest = new PermissionSyncRequest(associationId);
@@ -224,20 +224,30 @@ public class SystemDataTransferProcessor {
* Enable perm sync for the association
*/
public void enablePermissionsSync(int associationId) {
- int userId = mAssociationStore.getAssociationById(associationId).getUserId();
- PermissionSyncRequest request = new PermissionSyncRequest(associationId);
- request.setUserConsented(true);
- mSystemDataTransferRequestStore.writeRequest(userId, request);
+ final long callingIdentityToken = Binder.clearCallingIdentity();
+ try {
+ int userId = mAssociationStore.getAssociationById(associationId).getUserId();
+ PermissionSyncRequest request = new PermissionSyncRequest(associationId);
+ request.setUserConsented(true);
+ mSystemDataTransferRequestStore.writeRequest(userId, request);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentityToken);
+ }
}
/**
* Disable perm sync for the association
*/
public void disablePermissionsSync(int associationId) {
- int userId = mAssociationStore.getAssociationById(associationId).getUserId();
- PermissionSyncRequest request = new PermissionSyncRequest(associationId);
- request.setUserConsented(false);
- mSystemDataTransferRequestStore.writeRequest(userId, request);
+ final long callingIdentityToken = Binder.clearCallingIdentity();
+ try {
+ int userId = mAssociationStore.getAssociationById(associationId).getUserId();
+ PermissionSyncRequest request = new PermissionSyncRequest(associationId);
+ request.setUserConsented(false);
+ mSystemDataTransferRequestStore.writeRequest(userId, request);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentityToken);
+ }
}
/**
@@ -245,23 +255,34 @@ public class SystemDataTransferProcessor {
*/
@Nullable
public PermissionSyncRequest getPermissionSyncRequest(int associationId) {
- int userId = mAssociationStore.getAssociationById(associationId).getUserId();
- List<SystemDataTransferRequest> requests =
- mSystemDataTransferRequestStore.readRequestsByAssociationId(userId, associationId);
- for (SystemDataTransferRequest request : requests) {
- if (request instanceof PermissionSyncRequest) {
- return (PermissionSyncRequest) request;
+ final long callingIdentityToken = Binder.clearCallingIdentity();
+ try {
+ int userId = mAssociationStore.getAssociationById(associationId).getUserId();
+ List<SystemDataTransferRequest> requests =
+ mSystemDataTransferRequestStore.readRequestsByAssociationId(userId,
+ associationId);
+ for (SystemDataTransferRequest request : requests) {
+ if (request instanceof PermissionSyncRequest) {
+ return (PermissionSyncRequest) request;
+ }
}
+ return null;
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentityToken);
}
- return null;
}
/**
* Remove perm sync request for the association.
*/
public void removePermissionSyncRequest(int associationId) {
- int userId = mAssociationStore.getAssociationById(associationId).getUserId();
- mSystemDataTransferRequestStore.removeRequestsByAssociationId(userId, associationId);
+ final long callingIdentityToken = Binder.clearCallingIdentity();
+ try {
+ int userId = mAssociationStore.getAssociationById(associationId).getUserId();
+ mSystemDataTransferRequestStore.removeRequestsByAssociationId(userId, associationId);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentityToken);
+ }
}
private void onReceivePermissionRestore(byte[] message) {
diff --git a/services/core/java/com/android/server/SmartStorageMaintIdler.java b/services/core/java/com/android/server/SmartStorageMaintIdler.java
index 899692611086..44f1e76f7a22 100644
--- a/services/core/java/com/android/server/SmartStorageMaintIdler.java
+++ b/services/core/java/com/android/server/SmartStorageMaintIdler.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.util.Slog;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
public class SmartStorageMaintIdler extends JobService {
private static final String TAG = "SmartStorageMaintIdler";
@@ -34,15 +35,15 @@ public class SmartStorageMaintIdler extends JobService {
private static final int SMART_MAINT_JOB_ID = 2808;
- private boolean mStarted;
+ private final AtomicBoolean mStarted = new AtomicBoolean(false);
private JobParameters mJobParams;
private final Runnable mFinishCallback = new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Got smart storage maintenance service completion callback");
- if (mStarted) {
+ if (mStarted.get()) {
jobFinished(mJobParams, false);
- mStarted = false;
+ mStarted.set(false);
}
// ... and try again in a next period
scheduleSmartIdlePass(SmartStorageMaintIdler.this,
@@ -52,18 +53,26 @@ public class SmartStorageMaintIdler extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
- mJobParams = params;
- StorageManagerService ms = StorageManagerService.sSelf;
- if (ms != null) {
- mStarted = true;
- ms.runSmartIdleMaint(mFinishCallback);
+ final StorageManagerService ms = StorageManagerService.sSelf;
+ if (mStarted.compareAndSet(false, true)) {
+ new Thread() {
+ public void run() {
+ mJobParams = params;
+ if (ms != null) {
+ ms.runSmartIdleMaint(mFinishCallback);
+ } else {
+ mStarted.set(false);
+ }
+ }
+ }.start();
+ return ms != null;
}
- return ms != null;
+ return false;
}
@Override
public boolean onStopJob(JobParameters params) {
- mStarted = false;
+ mStarted.set(false);
return false;
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index a78764456d8b..25ca509cb949 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2842,7 +2842,7 @@ class StorageManagerService extends IStorageManager.Stub
return true;
}
- void runSmartIdleMaint(Runnable callback) {
+ synchronized void runSmartIdleMaint(Runnable callback) {
enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
try {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b5911f69b156..4c70db805a07 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9851,6 +9851,10 @@ public class ActivityManagerService extends IActivityManager.Stub
PriorityDump.dump(mPriorityDumper, fd, pw, args);
}
+ private static final String TICK =
+ "---------------------------------------"
+ + "----------------------------------------";
+
private void dumpEverything(FileDescriptor fd, PrintWriter pw, String[] args, int opti,
boolean dumpAll, String dumpPackage, int displayIdFilter, boolean dumpClient,
boolean dumpNormalPriority, int dumpAppId, boolean dumpProxies) {
@@ -9906,6 +9910,11 @@ public class ActivityManagerService extends IActivityManager.Stub
sdumper.dumpLocked();
}
}
+
+ // No need to hold the lock.
+ pw.println(TICK);
+ AnrTimer.dump(pw, false);
+
// We drop the lock here because we can't call dumpWithClient() with the lock held;
// if the caller wants a consistent state for the !dumpClient case, it can call this
// method with the lock held.
@@ -10351,6 +10360,8 @@ public class ActivityManagerService extends IActivityManager.Stub
mOomAdjuster.dumpCachedAppOptimizerSettings(pw);
mOomAdjuster.dumpCacheOomRankerSettings(pw);
}
+ } else if ("timers".equals(cmd)) {
+ AnrTimer.dump(pw, true);
} else if ("services".equals(cmd) || "s".equals(cmd)) {
if (dumpClient) {
ActiveServices.ServiceDumper dumper;
@@ -15866,7 +15877,15 @@ public class ActivityManagerService extends IActivityManager.Stub
activeInstr.mWatcher = watcher;
activeInstr.mUiAutomationConnection = uiAutomationConnection;
activeInstr.mResultClass = className;
- activeInstr.mHasBackgroundActivityStartsPermission = false;
+ activeInstr.mHasBackgroundActivityStartsPermission =
+ isSdkInSandbox
+ // TODO(b/261864298): consider using START_ACTIVITIES_FROM_BACKGROUND.
+ && checkPermission(
+ android.Manifest.permission
+ .START_ACTIVITIES_FROM_SDK_SANDBOX,
+ Binder.getCallingPid(),
+ Binder.getCallingUid())
+ == PackageManager.PERMISSION_GRANTED;
activeInstr.mHasBackgroundForegroundServiceStartsPermission = false;
// Instrumenting sdk sandbox without a restart is not supported
activeInstr.mNoRestart = false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 942d35a1d842..a057f32386f6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -4095,6 +4095,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" lru: raw LRU process list");
pw.println(" binder-proxies: stats on binder objects and IPCs");
pw.println(" settings: currently applied config settings");
+ pw.println(" timers: the current ANR timer state");
pw.println(" service [COMP_SPEC]: service client-side state");
pw.println(" package [PACKAGE_NAME]: all state related to given package");
pw.println(" all: dump all activities");
diff --git a/services/core/java/com/android/server/am/AnrHelper.java b/services/core/java/com/android/server/am/AnrHelper.java
index 7d984434284c..e0a224629174 100644
--- a/services/core/java/com/android/server/am/AnrHelper.java
+++ b/services/core/java/com/android/server/am/AnrHelper.java
@@ -20,6 +20,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.content.pm.ApplicationInfo;
+import android.os.Process;
import android.os.SystemClock;
import android.os.Trace;
import android.util.ArraySet;
@@ -267,6 +268,7 @@ class AnrHelper {
private class AnrRecord {
final ProcessRecord mApp;
final int mPid;
+ final int mUid;
final String mActivityShortComponentName;
final String mParentShortComponentName;
final TimeoutRecord mTimeoutRecord;
@@ -283,6 +285,7 @@ class AnrHelper {
Future<File> firstPidFilePromise) {
mApp = anrProcess;
mPid = anrProcess.mPid;
+ mUid = anrProcess.uid;
mActivityShortComponentName = activityShortComponentName;
mParentShortComponentName = parentShortComponentName;
mTimeoutRecord = timeoutRecord;
diff --git a/services/core/java/com/android/server/am/AnrTimer.java b/services/core/java/com/android/server/am/AnrTimer.java
new file mode 100644
index 000000000000..cd6f009a4106
--- /dev/null
+++ b/services/core/java/com/android/server/am/AnrTimer.java
@@ -0,0 +1,834 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.text.TextUtils.formatSimple;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.MathUtils;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.Keep;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.ProcessCpuTracker;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This class managers AnrTimers. An AnrTimer is a substitute for a delayed Message. In legacy
+ * mode, the timer just sends a delayed message. In modern mode, the timer is implemented in
+ * native code; on expiration, the message is sent without delay.
+ *
+ * <p>There are four external operations on a timer:
+ * <ul>
+ *
+ * <li>{@link #start} starts a timer. The timer is started with an object that the message
+ * argument. The timer is also given the pid and uid of the target. A timer that is started must
+ * be canceled, accepted, or discarded.
+ *
+ * <li>{@link #cancel} stops a timer and removes any in-flight expiration messages.
+ *
+ * <li>{@link #accept} acknowledges that the timer has expired, and that an ANR should be
+ * generated. This clears bookkeeping information for the timer.
+ *
+ * <li>{@link #discard} acknowledges that the timer has expired but, for other reasons, no ANR
+ * will be generated. This clears bookkeeping information for the timer.
+ *
+ *</li></p>
+ *
+ * <p>There is one internal operation on a timer: {@link #expire}. A timer may have automatic
+ * extensions enabled. If so, the extension is computed and if the extension is non-zero, the timer
+ * is restarted with the extension timeout. If extensions are disabled or if the extension is zero,
+ * the client process is notified of the expiration.
+ *
+ * @hide
+ */
+abstract class AnrTimer<V> {
+
+ /**
+ * The log tag.
+ */
+ final static String TAG = "AnrTimer";
+
+ /**
+ * The trace track for these events. There is a single track for all AnrTimer instances. The
+ * tracks give a sense of handler latency: the time between timer expiration and ANR
+ * collection.
+ */
+ private final static String TRACK = "AnrTimer";
+
+ /**
+ * Enable debug messages.
+ */
+ private static boolean DEBUG = false;
+
+ /**
+ * The trace tag.
+ */
+ private static final long TRACE_TAG = Trace.TRACE_TAG_ACTIVITY_MANAGER;
+
+ /**
+ * Enable tracing from the time a timer expires until it is accepted or discarded. This is
+ * used to diagnose long latencies in the client.
+ */
+ private static final boolean ENABLE_TRACING = false;
+
+ /**
+ * The status of an ANR timer. TIMER_INVALID status is returned when an error is detected.
+ */
+ private static final int TIMER_INVALID = 0;
+ private static final int TIMER_RUNNING = 1;
+ private static final int TIMER_EXPIRED = 2;
+
+ @IntDef(prefix = { "TIMER_" }, value = {
+ TIMER_INVALID, TIMER_RUNNING, TIMER_EXPIRED
+ })
+ private @interface TimerStatus {}
+
+ /**
+ * A static list of all known AnrTimer instances, used for dumping and testing.
+ */
+ @GuardedBy("sAnrTimerList")
+ private static final ArrayList<WeakReference<AnrTimer>> sAnrTimerList = new ArrayList<>();
+
+ /**
+ * An error is defined by its issue, the operation that detected the error, the tag of the
+ * affected service, a short stack of the bad call, and the stringified arg associated with
+ * the error.
+ */
+ private static final class Error {
+ /** The issue is the kind of error that was detected. This is a free-form string. */
+ final String issue;
+ /** The operation that detected the error: start, cancel, accept, or discard. */
+ final String operation;
+ /** The argument (stringified) passed in to the operation. */
+ final String arg;
+ /** The tag of the associated AnrTimer. */
+ final String tag;
+ /** A partial stack that localizes the caller of the operation. */
+ final StackTraceElement[] stack;
+
+ Error(@NonNull String issue, @NonNull String operation, @NonNull String tag,
+ @NonNull StackTraceElement[] stack, @NonNull String arg) {
+ this.issue = issue;
+ this.operation = operation;
+ this.tag = tag;
+ this.stack = stack;
+ this.arg = arg;
+ }
+ }
+
+ /**
+ * A list of errors detected during processing. Errors correspond to "timer not found"
+ * conditions. The stack trace identifies the source of the call. The list is
+ * first-in/first-out, and the size is limited to MAX_SAVED_ERROR_COUNT.
+ */
+ @GuardedBy("sErrors")
+ private static final ArrayList<Error> sErrors = new ArrayList<>();
+
+ /**
+ * The maximum number of errors that are saved in the sErrors list.
+ */
+ private static final int MAX_SAVED_ERROR_COUNT = 20;
+
+ /**
+ * A record of a single anr timer. The pid and uid are retained for reference but they do not
+ * participate in the equality tests. A {@link Timer} is bound to its parent {@link AnrTimer}
+ * through the owner field. Access to timer fields is guarded by the mLock of the owner.
+ */
+ private static class Timer {
+ /** The AnrTimer that is managing this Timer. */
+ final AnrTimer owner;
+
+ /** The argument that uniquely identifies the Timer in the context of its current owner. */
+ final Object arg;
+ /** The pid of the process being tracked by this Timer. */
+ final int pid;
+ /** The uid of the process being tracked by this Timer as reported by the kernel. */
+ final int uid;
+ /** The original timeout. */
+ final long timeoutMs;
+
+ /** The status of the Timer. */
+ @GuardedBy("owner.mLock")
+ @TimerStatus
+ int status;
+
+ /** The absolute time the timer was startd */
+ final long startedMs;
+
+ /** Fields used by the native timer service. */
+
+ /** The timer ID: used to exchange information with the native service. */
+ int timerId;
+
+ /** Fields used by the legacy timer service. */
+
+ /**
+ * The process's cpu delay time when the timer starts . It is meaningful only if
+ * extendable is true. The cpu delay is cumulative, so the incremental delay that occurs
+ * during a timer is the delay at the end of the timer minus this value. Units are in
+ * milliseconds.
+ */
+ @GuardedBy("owner.mLock")
+ long initialCpuDelayMs;
+
+ /** True if the timer has been extended. */
+ @GuardedBy("owner.mLock")
+ boolean extended;
+
+ /**
+ * Fetch a new Timer. This is private. Clients should get a new timer using the obtain()
+ * method.
+ */
+ private Timer(int pid, int uid, @Nullable Object arg, long timeoutMs,
+ @NonNull AnrTimer service) {
+ this.arg = arg;
+ this.pid = pid;
+ this.uid = uid;
+ this.timerId = 0;
+ this.timeoutMs = timeoutMs;
+ this.startedMs = now();
+ this.owner = service;
+ this.initialCpuDelayMs = 0;
+ this.extended = false;
+ this.status = TIMER_INVALID;
+ }
+
+ /** Get a timer. This implementation constructs a new timer. */
+ static Timer obtain(int pid, int uid, @Nullable Object arg, long timeout,
+ @NonNull AnrTimer service) {
+ return new Timer(pid, uid, arg, timeout, service);
+ }
+
+ /** Release a timer. This implementation simply drops the timer. */
+ void release() {
+ }
+
+ /** Return the age of the timer. This is used for debugging. */
+ long age() {
+ return now() - startedMs;
+ }
+
+ /**
+ * The hash code is generated from the owner and the argument. By definition, the
+ * combination must be unique for the lifetime of an in-use Timer.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(owner, arg);
+ }
+
+ /**
+ * The equality check compares the owner and the argument. By definition, the combination
+ * must be unique for the lifetime of an in-use Timer.
+ */
+ @Override
+ public boolean equals(Object r) {
+ if (r instanceof Timer) {
+ Timer t = (Timer) r;
+ return Objects.equals(owner, t.owner) && Objects.equals(arg, t.arg);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ final int myStatus;
+ synchronized (owner.mLock) {
+ myStatus = status;
+ }
+ return "timerId=" + timerId + " pid=" + pid + " uid=" + uid
+ + " " + statusString(myStatus) + " " + owner.mLabel;
+ }
+ }
+
+ /** A lock for the AnrTimer instance. */
+ private final Object mLock = new Object();
+
+ /**
+ * The map from client argument to the associated timer.
+ */
+ @GuardedBy("mLock")
+ private final ArrayMap<V, Timer> mTimerMap = new ArrayMap<>();
+
+ /** The highwater mark of started, but not closed, timers. */
+ @GuardedBy("mLock")
+ private int mMaxStarted = 0;
+
+ /**
+ * The total number of timers started.
+ */
+ @GuardedBy("mLock")
+ private int mTotalStarted = 0;
+
+ /**
+ * The total number of errors detected.
+ */
+ @GuardedBy("mLock")
+ private int mTotalErrors = 0;
+
+ /**
+ * The total number of timers that have expired.
+ */
+ @GuardedBy("mLock")
+ private int mTotalExpired = 0;
+
+ /**
+ * A TimerService that generates a timeout event <n> milliseconds in the future. See the
+ * class documentation for an explanation of the operations.
+ */
+ private abstract class TimerService {
+ /** Start a timer. The timeout must be initialized. */
+ abstract boolean start(@NonNull Timer timer);
+
+ abstract void cancel(@NonNull Timer timer);
+
+ abstract void accept(@NonNull Timer timer);
+
+ abstract void discard(@NonNull Timer timer);
+ }
+
+ /**
+ * A class to assist testing. All methods are null by default but can be overridden as
+ * necessary for a test.
+ */
+ @VisibleForTesting
+ static class Injector {
+ /**
+ * Return a handler for the given Callback.
+ */
+ Handler getHandler(@NonNull Handler.Callback callback) {
+ return null;
+ };
+
+ /**
+ * Return a CpuTracker.
+ */
+ CpuTracker getTracker() {
+ return null;
+ }
+ }
+
+ /**
+ * A helper class to measure CPU delays. Given a process ID, this class will return the
+ * cumulative CPU delay for the PID, since process inception. This class is defined to assist
+ * testing.
+ */
+ @VisibleForTesting
+ static class CpuTracker {
+ /**
+ * The parameter to ProcessCpuTracker indicates that statistics should be collected on a
+ * single process and not on the collection of threads associated with that process.
+ */
+ private final ProcessCpuTracker mCpu = new ProcessCpuTracker(false);
+
+ /** A simple wrapper to fetch the delay. This method can be overridden for testing. */
+ long delay(int pid) {
+ return mCpu.getCpuDelayTimeForPid(pid);
+ }
+ }
+
+ /**
+ * The "user-space" implementation of the timer service. This service uses its own message
+ * handler to create timeouts.
+ */
+ private class HandlerTimerService extends TimerService {
+ /** The lock for this handler */
+ private final Object mLock = new Object();
+
+ /** The message handler for scheduling future events. */
+ private final Handler mHandler;
+
+ /** The interface to fetch process statistics that might extend an ANR timeout. */
+ private final CpuTracker mCpu;
+
+ /** Create a HandlerTimerService based on the input handler. */
+ HandlerTimerService(@NonNull Handler handler) {
+ mHandler = new Handler(handler.getLooper(), this::expires);
+ mCpu = new CpuTracker();
+ }
+
+ /** Create a HandlerTimerService that directly uses the supplied handler and tracker. */
+ @VisibleForTesting
+ HandlerTimerService(@NonNull Injector injector) {
+ mHandler = injector.getHandler(this::expires);
+ mCpu = injector.getTracker();
+ }
+
+ /** Post a message with the specified timeout. The timer is not modified. */
+ private void post(@NonNull Timer t, long timeoutMillis) {
+ final Message msg = mHandler.obtainMessage();
+ msg.obj = t;
+ mHandler.sendMessageDelayed(msg, timeoutMillis);
+ }
+
+ /**
+ * The local expiration handler first attempts to compute a timer extension. If the timer
+ * should be extended, it is rescheduled in the future (granting more time to the
+ * associated process). If the timer should not be extended then the timeout is delivered
+ * to the client.
+ *
+ * A process is extended to account for the time the process was swapped out and was not
+ * runnable through no fault of its own. A timer can only be extended once and only if
+ * the AnrTimer permits extensions. Finally, a timer will never be extended by more than
+ * the original timeout, so the total timeout will never be more than twice the originally
+ * configured timeout.
+ */
+ private boolean expires(Message msg) {
+ Timer t = (Timer) msg.obj;
+ synchronized (mLock) {
+ long extension = 0;
+ if (mExtend && !t.extended) {
+ extension = mCpu.delay(t.pid) - t.initialCpuDelayMs;
+ if (extension < 0) extension = 0;
+ if (extension > t.timeoutMs) extension = t.timeoutMs;
+ t.extended = true;
+ }
+ if (extension > 0) {
+ post(t, extension);
+ } else {
+ onExpiredLocked(t, now());
+ }
+ }
+ return true;
+ }
+
+ @GuardedBy("mLock")
+ @Override
+ boolean start(@NonNull Timer t) {
+ if (mExtend) {
+ t.initialCpuDelayMs = mCpu.delay(t.pid);
+ }
+ post(t, t.timeoutMs);
+ return true;
+ }
+
+ @Override
+ void cancel(@NonNull Timer t) {
+ mHandler.removeMessages(0, t);
+ }
+
+ @Override
+ void accept(@NonNull Timer t) {
+ // Nothing to do.
+ }
+
+ @Override
+ void discard(@NonNull Timer t) {
+ // Nothing to do.
+ }
+
+ /** The string identifies this subclass of AnrTimerService as being based on handlers. */
+ @Override
+ public String toString() {
+ return "handler";
+ }
+ }
+
+ /**
+ * The handler for messages sent from this instance.
+ */
+ private final Handler mHandler;
+
+ /**
+ * The message type for messages sent from this interface.
+ */
+ private final int mWhat;
+
+ /**
+ * A label that identifies the AnrTimer associated with a Timer in log messages.
+ */
+ private final String mLabel;
+
+ /**
+ * Whether this timer instance supports extending timeouts.
+ */
+ private final boolean mExtend;
+
+ /**
+ * The timer service to use for this AnrTimer.
+ */
+ private final TimerService mTimerService;
+
+ /**
+ * Whether or not canceling a non-existent timer is an error. Clients often cancel freely
+ * preemptively, without knowing if the timer was ever started. Keeping this variable true
+ * means that such behavior is not an error.
+ */
+ private final boolean mLenientCancel = true;
+
+ /**
+ * The common constructor. A null injector results in a normal, production timer.
+ */
+ @VisibleForTesting
+ AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend,
+ @Nullable Injector injector) {
+ mHandler = handler;
+ mWhat = what;
+ mLabel = label;
+ mExtend = extend;
+ if (injector == null) {
+ mTimerService = new HandlerTimerService(handler);
+ } else {
+ mTimerService = new HandlerTimerService(injector);
+ }
+ synchronized (sAnrTimerList) {
+ sAnrTimerList.add(new WeakReference(this));
+ }
+ Log.i(TAG, formatSimple("created %s label: \"%s\"", mTimerService.toString(), label));
+ }
+
+ /**
+ * Create one timer instance for production. The client can ask for extensible timeouts.
+ */
+ AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend) {
+ this(handler, what, label, extend, null);
+ }
+
+ /**
+ * Create one timer instance for production. There are no extensible timeouts.
+ */
+ AnrTimer(@NonNull Handler handler, int what, @NonNull String label) {
+ this(handler, what, label, false, null);
+ }
+
+ /**
+ * Start a trace on the timer. The trace is laid down in the AnrTimerTrack.
+ */
+ private void traceBegin(Timer t, String what) {
+ if (ENABLE_TRACING) {
+ final String label = formatSimple("%s(%d,%d,%s)", what, t.pid, t.uid, mLabel);
+ final int cookie = t.hashCode();
+ Trace.asyncTraceForTrackBegin(TRACE_TAG, TRACK, label, cookie);
+ }
+ }
+
+ /**
+ * End a trace on the timer.
+ */
+ private void traceEnd(Timer t) {
+ if (ENABLE_TRACING) {
+ final int cookie = t.hashCode();
+ Trace.asyncTraceForTrackEnd(TRACE_TAG, TRACK, cookie);
+ }
+ }
+
+ /**
+ * Return the string representation for a timer status.
+ */
+ private static String statusString(int s) {
+ switch (s) {
+ case TIMER_INVALID: return "invalid";
+ case TIMER_RUNNING: return "running";
+ case TIMER_EXPIRED: return "expired";
+ }
+ return formatSimple("unknown: %d", s);
+ }
+
+ /**
+ * Delete the timer associated with arg from the maps and return it. Return null if the timer
+ * was not found.
+ */
+ @GuardedBy("mLock")
+ private Timer removeLocked(V arg) {
+ Timer timer = mTimerMap.remove(arg);
+ return timer;
+ }
+
+ /**
+ * Return the number of timers currently running.
+ */
+ @VisibleForTesting
+ static int sizeOfTimerList() {
+ synchronized (sAnrTimerList) {
+ int totalTimers = 0;
+ for (int i = 0; i < sAnrTimerList.size(); i++) {
+ AnrTimer client = sAnrTimerList.get(i).get();
+ if (client != null) totalTimers += client.mTimerMap.size();
+ }
+ return totalTimers;
+ }
+ }
+
+ /**
+ * Clear out all existing timers. This will lead to unexpected behavior if used carelessly.
+ * It is available only for testing. It returns the number of times that were actually
+ * erased.
+ */
+ @VisibleForTesting
+ static int resetTimerListForHermeticTest() {
+ synchronized (sAnrTimerList) {
+ int mapLen = 0;
+ for (int i = 0; i < sAnrTimerList.size(); i++) {
+ AnrTimer client = sAnrTimerList.get(i).get();
+ if (client != null) {
+ mapLen += client.mTimerMap.size();
+ client.mTimerMap.clear();
+ }
+ }
+ if (mapLen > 0) {
+ Log.w(TAG, formatSimple("erasing timer list: clearing %d timers", mapLen));
+ }
+ return mapLen;
+ }
+ }
+
+ /**
+ * Report something about a timer.
+ */
+ private void report(@NonNull Timer timer, @NonNull String msg) {
+ Log.i(TAG, msg + " " + timer + " " + Objects.toString(timer.arg));
+ }
+
+ /**
+ * Start a timer.
+ */
+ boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) {
+ final Timer timer = Timer.obtain(pid, uid, arg, timeoutMs, this);
+ synchronized (mLock) {
+ Timer old = mTimerMap.get(arg);
+ if (old != null) {
+ // There is an existing timer. This is a protocol error in the client. Record
+ // the error and then clean up by canceling running timers and discarding expired
+ // timers.
+ restartedLocked(old.status, arg);
+ if (old.status == TIMER_EXPIRED) {
+ discard(arg);
+ } else {
+ cancel(arg);
+ }
+ }
+ if (mTimerService.start(timer)) {
+ timer.status = TIMER_RUNNING;
+ mTimerMap.put(arg, timer);
+ mTotalStarted++;
+ mMaxStarted = Math.max(mMaxStarted, mTimerMap.size());
+ if (DEBUG) report(timer, "start");
+ return true;
+ } else {
+ Log.e(TAG, "AnrTimer.start failed");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Cancel a timer. Return false if the timer was not found.
+ */
+ boolean cancel(@NonNull V arg) {
+ synchronized (mLock) {
+ Timer timer = removeLocked(arg);
+ if (timer == null) {
+ if (!mLenientCancel) notFoundLocked("cancel", arg);
+ return false;
+ }
+ mTimerService.cancel(timer);
+ // There may be an expiration message in flight. Cancel it.
+ mHandler.removeMessages(mWhat, arg);
+ if (DEBUG) report(timer, "cancel");
+ timer.release();
+ return true;
+ }
+ }
+
+ /**
+ * Accept a timer in the framework-level handler. The timeout has been accepted and the
+ * timeout handler is executing. Return false if the timer was not found.
+ */
+ boolean accept(@NonNull V arg) {
+ synchronized (mLock) {
+ Timer timer = removeLocked(arg);
+ if (timer == null) {
+ notFoundLocked("accept", arg);
+ return false;
+ }
+ mTimerService.accept(timer);
+ traceEnd(timer);
+ if (DEBUG) report(timer, "accept");
+ timer.release();
+ return true;
+ }
+ }
+
+ /**
+ * Discard a timer in the framework-level handler. For whatever reason, the timer is no
+ * longer interesting. No statistics are collected. Return false if the time was not found.
+ */
+ boolean discard(@NonNull V arg) {
+ synchronized (mLock) {
+ Timer timer = removeLocked(arg);
+ if (timer == null) {
+ notFoundLocked("discard", arg);
+ return false;
+ }
+ mTimerService.discard(timer);
+ traceEnd(timer);
+ if (DEBUG) report(timer, "discard");
+ timer.release();
+ return true;
+ }
+ }
+
+ /**
+ * The notifier that a timer has fired. The timer is not modified.
+ */
+ @GuardedBy("mLock")
+ private void onExpiredLocked(@NonNull Timer timer, long when) {
+ if (DEBUG) report(timer, "expire");
+ traceBegin(timer, "expired");
+ mHandler.sendMessage(Message.obtain(mHandler, mWhat, timer.arg));
+ synchronized (mLock) {
+ mTotalExpired++;
+ }
+ }
+
+ /**
+ * Dump a single AnrTimer.
+ */
+ private void dump(IndentingPrintWriter pw) {
+ synchronized (mLock) {
+ pw.format("timer: %s\n", mLabel);
+ pw.increaseIndent();
+ pw.format("started=%d maxStarted=%d running=%d expired=%d error=%d\n",
+ mTotalStarted, mMaxStarted, mTimerMap.size(),
+ mTotalExpired, mTotalErrors);
+ pw.decreaseIndent();
+ }
+ }
+
+ /**
+ * Enable or disable debugging.
+ */
+ static void debug(boolean f) {
+ DEBUG = f;
+ }
+
+ /**
+ * The current time in milliseconds.
+ */
+ private static long now() {
+ return SystemClock.uptimeMillis();
+ }
+
+ /**
+ * Log an error. A limited stack trace leading to the client call that triggered the error is
+ * recorded. The stack trace assumes that this method is not called directly.
+ *
+ * If DEBUG is true, a log message is generated as well.
+ */
+ @GuardedBy("mLock")
+ private void recordErrorLocked(String operation, String errorMsg, Object arg) {
+ StackTraceElement[] s = Thread.currentThread().getStackTrace();
+ final String what = Objects.toString(arg);
+ // The copy range starts at the caller of the timer operation, and includes three levels.
+ // This should be enough to isolate the location of the call.
+ StackTraceElement[] location = Arrays.copyOfRange(s, 6, 9);
+ synchronized (sErrors) {
+ // Ensure the error list does not grow beyond the limit.
+ while (sErrors.size() >= MAX_SAVED_ERROR_COUNT) {
+ sErrors.remove(0);
+ }
+ // Add the new error to the list.
+ sErrors.add(new Error(errorMsg, operation, mLabel, location, what));
+ }
+ if (DEBUG) Log.w(TAG, operation + " " + errorMsg + " " + mLabel + " timer " + what);
+ mTotalErrors++;
+ }
+
+ /**
+ * Log an error about a timer not found.
+ */
+ @GuardedBy("mLock")
+ private void notFoundLocked(String operation, Object arg) {
+ recordErrorLocked(operation, "notFound", arg);
+ }
+
+ /**
+ * Log an error about a timer that is started when there is an existing timer.
+ */
+ @GuardedBy("mLock")
+ private void restartedLocked(@TimerStatus int status, Object arg) {
+ recordErrorLocked("start", status == TIMER_EXPIRED ? "autoDiscard" : "autoCancel", arg);
+ }
+
+ /**
+ * Dump a single error to the output stream.
+ */
+ private static void dump(IndentingPrintWriter ipw, int seq, Error err) {
+ ipw.format("%2d: op:%s tag:%s issue:%s arg:%s\n", seq, err.operation, err.tag,
+ err.issue, err.arg);
+ ipw.increaseIndent();
+ for (int i = 0; i < err.stack.length; i++) {
+ ipw.println(" " + err.stack[i].toString());
+ }
+ ipw.decreaseIndent();
+ }
+
+ /**
+ * Dump all errors to the output stream.
+ */
+ private static void dumpErrors(IndentingPrintWriter ipw) {
+ ArrayList<Error> errors;
+ synchronized (sErrors) {
+ if (sErrors.size() == 0) return;
+ errors = (ArrayList<Error>) sErrors.clone();
+ }
+ ipw.println("Errors");
+ ipw.increaseIndent();
+ for (int i = 0; i < errors.size(); i++) {
+ dump(ipw, i, errors.get(i));
+ }
+ ipw.decreaseIndent();
+ }
+
+ /**
+ * Dumpsys output.
+ */
+ static void dump(@NonNull PrintWriter pw, boolean verbose) {
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
+ ipw.println("AnrTimer statistics");
+ ipw.increaseIndent();
+ synchronized (sAnrTimerList) {
+ for (int i = 0; i < sAnrTimerList.size(); i++) {
+ AnrTimer client = sAnrTimerList.get(i).get();
+ if (client != null) client.dump(ipw);
+ }
+ }
+ if (verbose) dumpErrors(ipw);
+ ipw.format("AnrTimerEnd\n");
+ ipw.decreaseIndent();
+ }
+}
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index fc8175b76ecd..c35a3b2474aa 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -101,10 +101,9 @@ class BroadcastProcessQueue {
boolean runningOomAdjusted;
/**
- * Snapshotted value of {@link ProcessRecord#getCpuDelayTime()}, typically
- * used when deciding if we should extend the soft ANR timeout.
+ * True if a timer has been started against this queue.
*/
- long lastCpuDelayTime;
+ private boolean mTimeoutScheduled;
/**
* Snapshotted value of {@link ProcessStateRecord#getCurProcState()} before
@@ -1344,6 +1343,21 @@ class BroadcastProcessQueue {
return head;
}
+ /**
+ * Set the timeout flag to indicate that an ANR timer has been started. A value of true means a
+ * timer is running; a value of false means there is no timer running.
+ */
+ void setTimeoutScheduled(boolean timeoutStarted) {
+ mTimeoutScheduled = timeoutStarted;
+ }
+
+ /**
+ * Get the timeout flag
+ */
+ boolean timeoutScheduled() {
+ return mTimeoutScheduled;
+ }
+
@Override
public String toString() {
if (mCachedToString == null) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 8d2edaaadb63..5b71595256da 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -149,6 +149,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// We configure runnable size only once at boot; it'd be too complex to
// try resizing dynamically at runtime
mRunning = new BroadcastProcessQueue[mConstants.getMaxRunningQueues()];
+
+ mAnrTimer = new BroadcastAnrTimer(mLocalHandler);
}
/**
@@ -242,14 +244,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
*/
private @UptimeMillisLong long mLastTestFailureTime;
+ /**
+ * The ANR timer service for broadcasts.
+ */
+ @GuardedBy("mService")
+ private final BroadcastAnrTimer mAnrTimer;
+
private static final int MSG_UPDATE_RUNNING_LIST = 1;
- private static final int MSG_DELIVERY_TIMEOUT_SOFT = 2;
- private static final int MSG_DELIVERY_TIMEOUT_HARD = 3;
- private static final int MSG_BG_ACTIVITY_START_TIMEOUT = 4;
- private static final int MSG_CHECK_HEALTH = 5;
- private static final int MSG_CHECK_PENDING_COLD_START_VALIDITY = 6;
- private static final int MSG_PROCESS_FREEZABLE_CHANGED = 7;
- private static final int MSG_UID_STATE_CHANGED = 8;
+ private static final int MSG_DELIVERY_TIMEOUT = 2;
+ private static final int MSG_BG_ACTIVITY_START_TIMEOUT = 3;
+ private static final int MSG_CHECK_HEALTH = 4;
+ private static final int MSG_CHECK_PENDING_COLD_START_VALIDITY = 5;
+ private static final int MSG_PROCESS_FREEZABLE_CHANGED = 6;
+ private static final int MSG_UID_STATE_CHANGED = 7;
private void enqueueUpdateRunningList() {
mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
@@ -264,12 +271,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
updateRunningList();
return true;
}
- case MSG_DELIVERY_TIMEOUT_SOFT: {
- deliveryTimeoutSoft((BroadcastProcessQueue) msg.obj, msg.arg1);
- return true;
- }
- case MSG_DELIVERY_TIMEOUT_HARD: {
- deliveryTimeoutHard((BroadcastProcessQueue) msg.obj);
+ case MSG_DELIVERY_TIMEOUT: {
+ deliveryTimeout((BroadcastProcessQueue) msg.obj);
return true;
}
case MSG_BG_ACTIVITY_START_TIMEOUT: {
@@ -1024,12 +1027,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// immediately assume delivery success
final boolean assumeDelivered = r.isAssumedDelivered(index);
if (mService.mProcessesReady && !r.timeoutExempt && !assumeDelivered) {
- queue.lastCpuDelayTime = queue.app.getCpuDelayTime();
-
+ queue.setTimeoutScheduled(true);
final int softTimeoutMillis = (int) (r.isForeground() ? mFgConstants.TIMEOUT
: mBgConstants.TIMEOUT);
- mLocalHandler.sendMessageDelayed(Message.obtain(mLocalHandler,
- MSG_DELIVERY_TIMEOUT_SOFT, softTimeoutMillis, 0, queue), softTimeoutMillis);
+ mAnrTimer.start(queue, softTimeoutMillis);
+ } else {
+ queue.setTimeoutScheduled(false);
}
if (r.mBackgroundStartPrivileges.allowsAny()) {
@@ -1107,7 +1110,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// If we were trying to deliver a manifest broadcast, throw the error as we need
// to try redelivering the broadcast to this receiver.
if (receiver instanceof ResolveInfo) {
- mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_SOFT, queue);
+ mAnrTimer.cancel(queue);
throw new BroadcastDeliveryFailedException(e);
}
finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
@@ -1156,39 +1159,27 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
r.resultTo = null;
}
- private void deliveryTimeoutSoft(@NonNull BroadcastProcessQueue queue,
- int softTimeoutMillis) {
+ private void deliveryTimeout(@NonNull BroadcastProcessQueue queue) {
synchronized (mService) {
- deliveryTimeoutSoftLocked(queue, softTimeoutMillis);
+ deliveryTimeoutLocked(queue);
}
}
- private void deliveryTimeoutSoftLocked(@NonNull BroadcastProcessQueue queue,
- int softTimeoutMillis) {
- if (queue.app != null) {
- // Instead of immediately triggering an ANR, extend the timeout by
- // the amount of time the process was runnable-but-waiting; we're
- // only willing to do this once before triggering an hard ANR
- final long cpuDelayTime = queue.app.getCpuDelayTime() - queue.lastCpuDelayTime;
- final long hardTimeoutMillis = MathUtils.constrain(cpuDelayTime, 0, softTimeoutMillis);
- mLocalHandler.sendMessageDelayed(
- Message.obtain(mLocalHandler, MSG_DELIVERY_TIMEOUT_HARD, queue),
- hardTimeoutMillis);
- } else {
- deliveryTimeoutHardLocked(queue);
- }
+ private void deliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) {
+ finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_TIMEOUT,
+ "deliveryTimeoutLocked");
+ demoteFromRunningLocked(queue);
}
- private void deliveryTimeoutHard(@NonNull BroadcastProcessQueue queue) {
- synchronized (mService) {
- deliveryTimeoutHardLocked(queue);
+ private class BroadcastAnrTimer extends AnrTimer<BroadcastProcessQueue> {
+ BroadcastAnrTimer(Handler handler) {
+ super(Objects.requireNonNull(handler),
+ MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT", true);
}
- }
- private void deliveryTimeoutHardLocked(@NonNull BroadcastProcessQueue queue) {
- finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_TIMEOUT,
- "deliveryTimeoutHardLocked");
- demoteFromRunningLocked(queue);
+ void start(@NonNull BroadcastProcessQueue queue, long timeoutMillis) {
+ start(queue, queue.app.getPid(), queue.app.uid, timeoutMillis);
+ }
}
@Override
@@ -1292,14 +1283,16 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
if (deliveryState == BroadcastRecord.DELIVERY_TIMEOUT) {
r.anrCount++;
if (app != null && !app.isDebugging()) {
+ mAnrTimer.accept(queue);
final String packageName = getReceiverPackageName(receiver);
final String className = getReceiverClassName(receiver);
mService.appNotResponding(queue.app,
TimeoutRecord.forBroadcastReceiver(r.intent, packageName, className));
+ } else {
+ mAnrTimer.discard(queue);
}
- } else {
- mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_SOFT, queue);
- mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_HARD, queue);
+ } else if (queue.timeoutScheduled()) {
+ mAnrTimer.cancel(queue);
}
// Given that a receiver just finished, check if the "waitingFor" conditions are met.
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 2ae3118d7bfa..b9ccbfbf55e7 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -275,7 +275,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
}
sensor.goToStateWaitingForCookie(requireConfirmation, mToken, mOperationId,
mUserId, mSensorReceiver, mOpPackageName, mRequestId, cookie,
- mPromptInfo.isAllowBackgroundAuthentication());
+ mPromptInfo.isAllowBackgroundAuthentication(),
+ mPromptInfo.isForLegacyFingerprintManager());
}
}
@@ -747,7 +748,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
Slog.v(TAG, "Confirmed! Modality: " + statsModality()
+ ", User: " + mUserId
+ ", IsCrypto: " + isCrypto()
- + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+ + ", Client: " + getStatsClient()
+ ", RequireConfirmation: " + mPreAuthInfo.confirmationRequested
+ ", State: " + FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
+ ", Latency: " + latency
@@ -758,7 +759,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mOperationContext,
statsModality(),
BiometricsProtoEnums.ACTION_UNKNOWN,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ getStatsClient(),
mDebugEnabled,
latency,
FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
@@ -784,7 +785,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
+ ", User: " + mUserId
+ ", IsCrypto: " + isCrypto()
+ ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
- + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+ + ", Client: " + getStatsClient()
+ ", Reason: " + reason
+ ", Error: " + error
+ ", Latency: " + latency
@@ -796,7 +797,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mOperationContext,
statsModality(),
BiometricsProtoEnums.ACTION_AUTHENTICATE,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ getStatsClient(),
mDebugEnabled,
latency,
error,
@@ -998,6 +999,12 @@ public final class AuthSession implements IBinder.DeathRecipient {
}
}
+ private int getStatsClient() {
+ return mPromptInfo.isForLegacyFingerprintManager()
+ ? BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER
+ : BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT;
+ }
+
@Override
public String toString() {
return "State: " + mState
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStats.java b/services/core/java/com/android/server/biometrics/AuthenticationStats.java
index 707240bf41f8..3c1cc006ffda 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationStats.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationStats.java
@@ -16,12 +16,16 @@
package com.android.server.biometrics;
+import android.util.Slog;
+
/**
* Utility class for on-device biometric authentication data, including total authentication,
* rejections, and the number of sent enrollment notifications.
*/
public class AuthenticationStats {
+ private static final String TAG = "AuthenticationStats";
+
private static final float FRR_NOT_ENOUGH_ATTEMPTS = -1.0f;
private final int mUserId;
@@ -88,6 +92,7 @@ public class AuthenticationStats {
public void resetData() {
mTotalAttempts = 0;
mRejectedAttempts = 0;
+ Slog.d(TAG, "Reset Counters.");
}
/** Update enrollment notification counter after sending a notification. */
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStatsBroadcastReceiver.java b/services/core/java/com/android/server/biometrics/AuthenticationStatsBroadcastReceiver.java
new file mode 100644
index 000000000000..832d73fd5d2d
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/AuthenticationStatsBroadcastReceiver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics;
+
+import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.biometrics.BiometricAuthenticator;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.BiometricNotificationImpl;
+
+import java.util.function.Consumer;
+
+/**
+ * Receives broadcast to initialize AuthenticationStatsCollector.
+ */
+public class AuthenticationStatsBroadcastReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "AuthenticationStatsBroadcastReceiver";
+
+ @NonNull
+ private final Consumer<AuthenticationStatsCollector> mCollectorConsumer;
+ @BiometricAuthenticator.Modality
+ private final int mModality;
+
+ public AuthenticationStatsBroadcastReceiver(@NonNull Context context,
+ @BiometricAuthenticator.Modality int modality,
+ @NonNull Consumer<AuthenticationStatsCollector> callback) {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+ context.registerReceiver(this, intentFilter);
+
+ mCollectorConsumer = callback;
+ mModality = modality;
+ }
+
+ @Override
+ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+
+ if (userId != UserHandle.USER_NULL
+ && Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+ Slog.d(TAG, "Received: " + intent.getAction());
+
+ mCollectorConsumer.accept(
+ new AuthenticationStatsCollector(context, mModality,
+ new BiometricNotificationImpl()));
+
+ context.unregisterReceiver(this);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java
index 64691e0b062b..6edbfb7752a1 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java
@@ -59,12 +59,9 @@ public class AuthenticationStatsCollector {
private final float mThreshold;
private final int mModality;
- private boolean mPersisterInitialized = false;
@NonNull private final Map<Integer, AuthenticationStats> mUserAuthenticationStatsMap;
-
- // TODO(b/295582896): Find a way to make this NonNull
- @Nullable private AuthenticationStatsPersister mAuthenticationStatsPersister;
+ @NonNull private AuthenticationStatsPersister mAuthenticationStatsPersister;
@NonNull private BiometricNotification mBiometricNotification;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -93,23 +90,20 @@ public class AuthenticationStatsCollector {
mFaceManager = mContext.getSystemService(FaceManager.class);
mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
+ mAuthenticationStatsPersister = new AuthenticationStatsPersister(mContext);
+
+ initializeUserAuthenticationStatsMap();
+ mAuthenticationStatsPersister.persistFrrThreshold(mThreshold);
+
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
context.registerReceiver(mBroadcastReceiver, intentFilter);
}
private void initializeUserAuthenticationStatsMap() {
- try {
- mAuthenticationStatsPersister = new AuthenticationStatsPersister(mContext);
- for (AuthenticationStats stats :
- mAuthenticationStatsPersister.getAllFrrStats(mModality)) {
- mUserAuthenticationStatsMap.put(stats.getUserId(), stats);
- }
- mAuthenticationStatsPersister.persistFrrThreshold(mThreshold);
-
- mPersisterInitialized = true;
- } catch (IllegalStateException e) {
- Slog.w(TAG, "Failed to initialize AuthenticationStatsPersister.", e);
+ for (AuthenticationStats stats :
+ mAuthenticationStatsPersister.getAllFrrStats(mModality)) {
+ mUserAuthenticationStatsMap.put(stats.getUserId(), stats);
}
}
@@ -143,9 +137,7 @@ public class AuthenticationStatsCollector {
sendNotificationIfNeeded(userId);
- if (mPersisterInitialized) {
- persistDataIfNeeded(userId);
- }
+ persistDataIfNeeded(userId);
}
/** Check if a notification should be sent after a calculation cycle. */
@@ -188,13 +180,8 @@ public class AuthenticationStatsCollector {
}
private void onUserRemoved(final int userId) {
- if (!mPersisterInitialized) {
- initializeUserAuthenticationStatsMap();
- }
- if (mPersisterInitialized) {
- mUserAuthenticationStatsMap.remove(userId);
- mAuthenticationStatsPersister.removeFrrStats(userId);
- }
+ mUserAuthenticationStatsMap.remove(userId);
+ mAuthenticationStatsPersister.removeFrrStats(userId);
}
private boolean isSingleModalityDevice() {
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index 937e3f8f8668..42dd36a5c35a 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -106,12 +106,13 @@ public abstract class BiometricSensor {
void goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- long requestId, int cookie, boolean allowBackgroundAuthentication)
+ long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
mCookie = cookie;
impl.prepareForAuthentication(requireConfirmation, token,
sessionId, userId, sensorReceiver, opPackageName, requestId, mCookie,
- allowBackgroundAuthentication);
+ allowBackgroundAuthentication, isForLegacyFingerprintManager);
mSensorState = STATE_WAITING_FOR_COOKIE;
}
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
index 87037af11a84..dbef7178efd0 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
@@ -17,6 +17,7 @@
package com.android.server.biometrics.log;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.SensorManager;
import android.hardware.biometrics.BiometricConstants;
@@ -42,7 +43,7 @@ public class BiometricLogger {
private final int mStatsAction;
private final int mStatsClient;
private final BiometricFrameworkStatsLogger mSink;
- @NonNull private final AuthenticationStatsCollector mAuthenticationStatsCollector;
+ @Nullable private final AuthenticationStatsCollector mAuthenticationStatsCollector;
@NonNull private final ALSProbe mALSProbe;
private long mFirstAcquireTimeMs;
@@ -68,7 +69,7 @@ public class BiometricLogger {
*/
public BiometricLogger(
@NonNull Context context, int statsModality, int statsAction, int statsClient,
- AuthenticationStatsCollector authenticationStatsCollector) {
+ @Nullable AuthenticationStatsCollector authenticationStatsCollector) {
this(statsModality, statsAction, statsClient,
BiometricFrameworkStatsLogger.getInstance(),
authenticationStatsCollector,
@@ -79,7 +80,7 @@ public class BiometricLogger {
BiometricLogger(
int statsModality, int statsAction, int statsClient,
BiometricFrameworkStatsLogger logSink,
- @NonNull AuthenticationStatsCollector statsCollector,
+ @Nullable AuthenticationStatsCollector statsCollector,
SensorManager sensorManager) {
mStatsModality = statsModality;
mStatsAction = statsAction;
@@ -206,7 +207,9 @@ public class BiometricLogger {
return;
}
- mAuthenticationStatsCollector.authenticate(targetUserId, authenticated);
+ if (mAuthenticationStatsCollector != null) {
+ mAuthenticationStatsCollector.authenticate(targetUserId, authenticated);
+ }
int authState = FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__UNKNOWN;
if (!authenticated) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 6ac163121d8c..78c95ad4576b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -283,7 +283,11 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions>
}
try {
- listener.onAuthenticationFailed(getSensorId());
+ if (listener != null) {
+ listener.onAuthenticationFailed(getSensorId());
+ } else {
+ Slog.e(TAG, "Received failed auth, but client was not listening");
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify listener", e);
mCallback.onClientFinished(this, false);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index fb64bcc3abc1..22110037890f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -62,7 +62,8 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
+ String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
mFaceService.prepareForAuthentication(requireConfirmation, token, operationId,
sensorReceiver, new FaceAuthenticateOptions.Builder()
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 28f0a4dadbd5..cc3118cc3433 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -49,6 +49,7 @@ import android.util.proto.ProtoOutputStream;
import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
import com.android.server.biometrics.AuthenticationStatsCollector;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
@@ -56,7 +57,6 @@ import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricNotificationImpl;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
@@ -114,8 +114,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
private final BiometricContext mBiometricContext;
@NonNull
private final AuthSessionCoordinator mAuthSessionCoordinator;
- @NonNull
- private final AuthenticationStatsCollector mAuthenticationStatsCollector;
+ @Nullable
+ private AuthenticationStatsCollector mAuthenticationStatsCollector;
@Nullable
private IFace mDaemon;
@@ -177,8 +177,14 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
mAuthSessionCoordinator = mBiometricContext.getAuthSessionCoordinator();
mDaemon = daemon;
- mAuthenticationStatsCollector = new AuthenticationStatsCollector(mContext,
- BiometricsProtoEnums.MODALITY_FACE, new BiometricNotificationImpl());
+ AuthenticationStatsBroadcastReceiver mBroadcastReceiver =
+ new AuthenticationStatsBroadcastReceiver(
+ mContext,
+ BiometricsProtoEnums.MODALITY_FACE,
+ (AuthenticationStatsCollector collector) -> {
+ Slog.d(getTag(), "Initializing AuthenticationStatsCollector");
+ mAuthenticationStatsCollector = collector;
+ });
for (SensorProps prop : props) {
final int sensorId = prop.commonProps.sensorId;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 808626120c1e..1499317478aa 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -52,6 +52,7 @@ import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
import com.android.server.biometrics.AuthenticationStatsCollector;
import com.android.server.biometrics.SensorServiceStateProto;
import com.android.server.biometrics.SensorStateProto;
@@ -62,7 +63,6 @@ import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricNotificationImpl;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
@@ -125,7 +125,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
@Nullable private IBiometricsFace mDaemon;
@NonNull private final HalResultController mHalResultController;
@NonNull private final BiometricContext mBiometricContext;
- @NonNull private final AuthenticationStatsCollector mAuthenticationStatsCollector;
+ @Nullable private AuthenticationStatsCollector mAuthenticationStatsCollector;
// for requests that do not use biometric prompt
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
private int mCurrentUserId = UserHandle.USER_NULL;
@@ -366,8 +366,14 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
mCurrentUserId = UserHandle.USER_NULL;
});
- mAuthenticationStatsCollector = new AuthenticationStatsCollector(mContext,
- BiometricsProtoEnums.MODALITY_FACE, new BiometricNotificationImpl());
+ AuthenticationStatsBroadcastReceiver mBroadcastReceiver =
+ new AuthenticationStatsBroadcastReceiver(
+ mContext,
+ BiometricsProtoEnums.MODALITY_FACE,
+ (AuthenticationStatsCollector collector) -> {
+ Slog.d(TAG, "Initializing AuthenticationStatsCollector");
+ mAuthenticationStatsCollector = collector;
+ });
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index d47a57ad6742..b6fa0c126cd6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -62,7 +62,8 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
+ String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
mFingerprintService.prepareForAuthentication(token, operationId, sensorReceiver,
new FingerprintAuthenticateOptions.Builder()
@@ -70,7 +71,7 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
.setUserId(userId)
.setOpPackageName(opPackageName)
.build(),
- requestId, cookie, allowBackgroundAuthentication);
+ requestId, cookie, allowBackgroundAuthentication, isForLegacyFingerprintManager);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 7cc6940f4b9d..5ce0c8b384ef 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -464,7 +464,8 @@ public class FingerprintService extends SystemService {
public void prepareForAuthentication(IBinder token, long operationId,
IBiometricSensorReceiver sensorReceiver,
@NonNull FingerprintAuthenticateOptions options,
- long requestId, int cookie, boolean allowBackgroundAuthentication) {
+ long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager) {
super.prepareForAuthentication_enforcePermission();
final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
@@ -473,10 +474,13 @@ public class FingerprintService extends SystemService {
return;
}
+ final int statsClient =
+ isForLegacyFingerprintManager ? BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER
+ : BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT;
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(token, operationId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
- restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ restricted, statsClient,
allowBackgroundAuthentication);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 5f4b89439fd0..f74b45cbdb0e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -57,6 +57,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
import com.android.server.biometrics.AuthenticationStatsCollector;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
@@ -64,7 +65,6 @@ import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricNotificationImpl;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
@@ -124,7 +124,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private ISidefpsController mSidefpsController;
private AuthSessionCoordinator mAuthSessionCoordinator;
- @NonNull private final AuthenticationStatsCollector mAuthenticationStatsCollector;
+ @Nullable private AuthenticationStatsCollector mAuthenticationStatsCollector;
private final class BiometricTaskStackListener extends TaskStackListener {
@Override
@@ -184,8 +184,14 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
mAuthSessionCoordinator = mBiometricContext.getAuthSessionCoordinator();
mDaemon = daemon;
- mAuthenticationStatsCollector = new AuthenticationStatsCollector(mContext,
- BiometricsProtoEnums.MODALITY_FINGERPRINT, new BiometricNotificationImpl());
+ AuthenticationStatsBroadcastReceiver mBroadcastReceiver =
+ new AuthenticationStatsBroadcastReceiver(
+ mContext,
+ BiometricsProtoEnums.MODALITY_FINGERPRINT,
+ (AuthenticationStatsCollector collector) -> {
+ Slog.d(getTag(), "Initializing AuthenticationStatsCollector");
+ mAuthenticationStatsCollector = collector;
+ });
final List<SensorLocationInternal> workaroundLocations = getWorkaroundSensorProps(context);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index d0b71fcf2dbb..a655f3601a07 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -52,6 +52,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.AuthenticationStatsBroadcastReceiver;
import com.android.server.biometrics.AuthenticationStatsCollector;
import com.android.server.biometrics.SensorServiceStateProto;
import com.android.server.biometrics.SensorStateProto;
@@ -66,7 +67,6 @@ import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.BiometricNotificationImpl;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
@@ -125,7 +125,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private ISidefpsController mSidefpsController;
@NonNull private final BiometricContext mBiometricContext;
- @NonNull private final AuthenticationStatsCollector mAuthenticationStatsCollector;
+ @Nullable private AuthenticationStatsCollector mAuthenticationStatsCollector;
// for requests that do not use biometric prompt
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
private int mCurrentUserId = UserHandle.USER_NULL;
@@ -354,8 +354,14 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
mCurrentUserId = UserHandle.USER_NULL;
});
- mAuthenticationStatsCollector = new AuthenticationStatsCollector(mContext,
- BiometricsProtoEnums.MODALITY_FINGERPRINT, new BiometricNotificationImpl());
+ AuthenticationStatsBroadcastReceiver mBroadcastReceiver =
+ new AuthenticationStatsBroadcastReceiver(
+ mContext,
+ BiometricsProtoEnums.MODALITY_FINGERPRINT,
+ (AuthenticationStatsCollector collector) -> {
+ Slog.d(TAG, "Initializing AuthenticationStatsCollector");
+ mAuthenticationStatsCollector = collector;
+ });
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
index 5c0c3626037a..01d1e378a735 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
@@ -59,7 +59,8 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long sessionId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
+ String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
index d4232ab60eec..6bed42b54bd9 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
@@ -323,10 +323,15 @@ final class ConversionUtils {
static ProgramIdentifier identifierToHalProgramIdentifier(ProgramSelector.Identifier id) {
ProgramIdentifier hwId = new ProgramIdentifier();
hwId.type = id.getType();
- if (hwId.type == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT) {
+ if (id.getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT) {
hwId.type = IdentifierType.DAB_SID_EXT;
}
- hwId.value = id.getValue();
+ long value = id.getValue();
+ if (id.getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT) {
+ hwId.value = (value & 0xFFFF) | ((value >>> 16) << 32);
+ } else {
+ hwId.value = value;
+ }
return hwId;
}
@@ -584,6 +589,9 @@ final class ConversionUtils {
|| isNewIdentifierInU(info.getPhysicallyTunedTo())) {
return false;
}
+ if (info.getRelatedContent() == null) {
+ return true;
+ }
Iterator<ProgramSelector.Identifier> relatedContentIt = info.getRelatedContent().iterator();
while (relatedContentIt.hasNext()) {
if (isNewIdentifierInU(relatedContentIt.next())) {
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 4bfc09075448..21273e0f2785 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -17,10 +17,11 @@
package com.android.server.display;
import android.hardware.display.BrightnessInfo;
+import android.os.Handler;
import android.os.IBinder;
-import android.provider.DeviceConfigInterface;
-import com.android.server.display.feature.DeviceConfigParameterProvider;
+import com.android.server.display.brightness.clamper.HdrClamper;
+import com.android.server.display.feature.DisplayManagerFlags;
import java.io.PrintWriter;
import java.util.function.BooleanSupplier;
@@ -31,23 +32,30 @@ class BrightnessRangeController {
private final NormalBrightnessModeController mNormalBrightnessModeController =
new NormalBrightnessModeController();
+ private final HdrClamper mHdrClamper;
+
private final Runnable mModeChangeCallback;
private final boolean mUseNbmController;
+ private final boolean mUseHdrClamper;
+
BrightnessRangeController(HighBrightnessModeController hbmController,
- Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig) {
+ Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig, Handler handler,
+ DisplayManagerFlags flags) {
this(hbmController, modeChangeCallback, displayDeviceConfig,
- new DeviceConfigParameterProvider(DeviceConfigInterface.REAL));
+ new HdrClamper(modeChangeCallback::run, new Handler(handler.getLooper())), flags);
}
BrightnessRangeController(HighBrightnessModeController hbmController,
Runnable modeChangeCallback, DisplayDeviceConfig displayDeviceConfig,
- DeviceConfigParameterProvider configParameterProvider) {
+ HdrClamper hdrClamper, DisplayManagerFlags flags) {
mHbmController = hbmController;
mModeChangeCallback = modeChangeCallback;
- mUseNbmController = configParameterProvider.isNormalBrightnessControllerFeatureEnabled();
+ mUseHdrClamper = false;
+ mUseNbmController = flags.isNbmControllerEnabled();
mNormalBrightnessModeController.resetNbmData(displayDeviceConfig.getLuxThrottlingData());
+ mHdrClamper = hdrClamper;
}
void dump(PrintWriter pw) {
@@ -55,7 +63,6 @@ class BrightnessRangeController {
pw.println(" mUseNormalBrightnessController=" + mUseNbmController);
mHbmController.dump(pw);
mNormalBrightnessModeController.dump(pw);
-
}
void onAmbientLuxChange(float ambientLux) {
@@ -63,6 +70,9 @@ class BrightnessRangeController {
() -> mNormalBrightnessModeController.onAmbientLuxChange(ambientLux),
() -> mHbmController.onAmbientLuxChange(ambientLux)
);
+ if (mUseHdrClamper) {
+ mHdrClamper.onAmbientLuxChange(ambientLux);
+ }
}
float getNormalBrightnessMax() {
@@ -118,7 +128,8 @@ class BrightnessRangeController {
}
float getHdrBrightnessValue() {
- return mHbmController.getHdrBrightnessValue();
+ float hdrBrightness = mHbmController.getHdrBrightnessValue();
+ return Math.min(hdrBrightness, mHdrClamper.getMaxBrightness());
}
float getTransitionPoint() {
@@ -138,4 +149,8 @@ class BrightnessRangeController {
hbmChangesFunc.run();
}
}
+
+ public float getHdrTransitionRate() {
+ return mHdrClamper.getTransitionRate();
+ }
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index e3dafa4a4cc0..3a6e5f93861b 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -53,6 +53,7 @@ import com.android.server.display.config.DisplayBrightnessPoint;
import com.android.server.display.config.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.HbmTiming;
+import com.android.server.display.config.HdrBrightnessData;
import com.android.server.display.config.HighBrightnessMode;
import com.android.server.display.config.IntegerArray;
import com.android.server.display.config.LuxThrottling;
@@ -232,7 +233,22 @@ import javax.xml.datatype.DatatypeConfigurationException;
* </point>
* </sdrHdrRatioMap>
* </highBrightnessMode>
- *
+ * <hdrBrightnessConfig>
+ * <brightnessMap>
+ * <point>
+ * <first>500</first>
+ * <second>0.3</second>
+ * </point>
+ * <point>
+ * <first>1200</first>
+ * <second>0.6</second>
+ * </point>
+ * </brightnessMap>
+ * <brightnessIncreaseDebounceMillis>1000</brightnessIncreaseDebounceMillis>
+ * <brightnessIncreaseDurationMillis>10000</brightnessIncreaseDurationMillis>
+ * <brightnessDecreaseDebounceMillis>13000</brightnessDecreaseDebounceMillis>
+ * <brightnessDecreaseDurationMillis>10000</brightnessDecreaseDurationMillis>
+ * </hdrBrightnessConfig>
* <luxThrottling>
* <brightnessLimitMap>
* <type>default</type>
@@ -769,6 +785,9 @@ public class DisplayDeviceConfig {
@Nullable
private HostUsiVersion mHostUsiVersion;
+ @Nullable
+ private HdrBrightnessData mHdrBrightnessData;
+
@VisibleForTesting
DisplayDeviceConfig(Context context) {
mContext = context;
@@ -1544,6 +1563,14 @@ public class DisplayDeviceConfig {
}
/**
+ * @return HDR brightness related configuration
+ */
+ @Nullable
+ public HdrBrightnessData getHdrBrightnessData() {
+ return mHdrBrightnessData;
+ }
+
+ /**
* @return Refresh rate range for specific profile id or null
*/
@Nullable
@@ -1759,7 +1786,8 @@ public class DisplayDeviceConfig {
+ "mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
mScreenOffBrightnessSensorValueToLux)
+ "\n"
- + "mUsiVersion= " + mHostUsiVersion
+ + "mUsiVersion= " + mHostUsiVersion + "\n"
+ + "mHdrBrightnessData" + mHdrBrightnessData
+ "}";
}
@@ -1823,6 +1851,7 @@ public class DisplayDeviceConfig {
loadRefreshRateSetting(config);
loadScreenOffBrightnessSensorValueToLuxFromDdc(config);
loadUsiVersion(config);
+ mHdrBrightnessData = HdrBrightnessData.loadConfig(config);
} else {
Slog.w(TAG, "DisplayDeviceConfig file is null");
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 90c7ce7d5bc8..65e199007de9 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -3267,12 +3267,12 @@ public final class DisplayManagerService extends SystemService {
displayPowerController = new DisplayPowerController2(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted);
+ () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted, mFlags);
} else {
displayPowerController = new DisplayPowerController(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted);
+ () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted, mFlags);
}
mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
return displayPowerController;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 40dbabf29807..25f3237e9b8b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -75,6 +75,7 @@ import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.Layout;
import com.android.server.display.utils.SensorUtils;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
@@ -592,7 +593,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
- boolean bootCompleted) {
+ boolean bootCompleted, DisplayManagerFlags flags) {
mInjector = injector != null ? injector : new Injector();
mClock = mInjector.getClock();
@@ -677,7 +678,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback);
mBrightnessRangeController = new BrightnessRangeController(hbmController,
- modeChangeCallback, mDisplayDeviceConfig);
+ modeChangeCallback, mDisplayDeviceConfig, mHandler, flags);
mBrightnessThrottler = createBrightnessThrottlerLocked();
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 460c351c4027..595abfd81c23 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -77,6 +77,7 @@ import com.android.server.display.brightness.clamper.BrightnessClamperController
import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.Layout;
import com.android.server.display.state.DisplayStateController;
import com.android.server.display.utils.SensorUtils;
@@ -472,7 +473,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
- boolean bootCompleted) {
+ boolean bootCompleted, DisplayManagerFlags flags) {
mInjector = injector != null ? injector : new Injector();
mClock = mInjector.getClock();
@@ -539,8 +540,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
modeChangeCallback);
mBrightnessThrottler = createBrightnessThrottlerLocked();
- mBrightnessRangeController = new BrightnessRangeController(hbmController,
- modeChangeCallback, mDisplayDeviceConfig);
+ mBrightnessRangeController = mInjector.getBrightnessRangeController(hbmController,
+ modeChangeCallback, mDisplayDeviceConfig, mHandler, flags);
mDisplayBrightnessController =
new DisplayBrightnessController(context, null,
@@ -1497,6 +1498,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// allowed range.
float animateValue = clampScreenBrightness(brightnessState);
+ // custom transition duration
+ float customTransitionRate = -1f;
+
// If there are any HDR layers on the screen, we have a special brightness value that we
// use instead. We still preserve the calculated brightness for Standard Dynamic Range
// (SDR) layers, but the main brightness value will be the one for HDR.
@@ -1511,6 +1515,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// We want to scale HDR brightness level with the SDR level, we also need to restore
// SDR brightness immediately when entering dim or low power mode.
animateValue = mBrightnessRangeController.getHdrBrightnessValue();
+ customTransitionRate = mBrightnessRangeController.getHdrTransitionRate();
}
final float currentBrightness = mPowerState.getScreenBrightness();
@@ -1523,6 +1528,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|| !isDisplayContentVisible || brightnessIsTemporary) {
animateScreenBrightness(animateValue, sdrAnimateValue,
SCREEN_ANIMATION_RATE_MINIMUM);
+ } else if (customTransitionRate > 0) {
+ animateScreenBrightness(animateValue, sdrAnimateValue,
+ customTransitionRate);
} else {
boolean isIncreasing = animateValue > currentBrightness;
final float rampSpeed;
@@ -2968,6 +2976,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
hbmChangeCallback, hbmMetadata, context);
}
+ BrightnessRangeController getBrightnessRangeController(
+ HighBrightnessModeController hbmController, Runnable modeChangeCallback,
+ DisplayDeviceConfig displayDeviceConfig, Handler handler,
+ DisplayManagerFlags flags) {
+ return new BrightnessRangeController(hbmController,
+ modeChangeCallback, displayDeviceConfig, handler, flags);
+ }
+
DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
SensorManager sensorManager, Resources resources) {
return DisplayWhiteBalanceFactory.create(handler,
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 693611263d66..d910e16de8e8 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -167,6 +167,8 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
int width, int height, int densityDpi) {
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
if (device != null) {
+ Slog.v(TAG, "Resize VirtualDisplay " + device.mName + " to " + width
+ + " " + height);
device.resizeLocked(width, height, densityDpi);
}
}
@@ -183,6 +185,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
public void setVirtualDisplaySurfaceLocked(IBinder appToken, Surface surface) {
VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
if (device != null) {
+ Slog.v(TAG, "Update surface for VirtualDisplay " + device.mName);
device.setSurfaceLocked(surface);
}
}
@@ -197,6 +200,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
if (device != null) {
+ Slog.v(TAG, "Release VirtualDisplay " + device.mName);
device.destroyLocked(true);
appToken.unlinkToDeath(device, 0);
}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
new file mode 100644
index 000000000000..079a196234a8
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.brightness.clamper;
+
+import android.os.Handler;
+import android.os.PowerManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class HdrClamper {
+
+ private final Configuration mConfiguration = new Configuration();
+
+ private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener;
+
+ private final Handler mHandler;
+
+ private final Runnable mDebouncer;
+
+ private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX;
+
+ // brightness change speed, in units per seconds,
+ private float mTransitionRate = -1f;
+
+ private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX;
+
+ private float mDesiredTransitionDuration = -1; // in seconds
+
+ public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener,
+ Handler handler) {
+ mClamperChangeListener = clamperChangeListener;
+ mHandler = handler;
+ mDebouncer = () -> {
+ mTransitionRate = Math.abs((mMaxBrightness - mDesiredMaxBrightness)
+ / mDesiredTransitionDuration);
+ mMaxBrightness = mDesiredMaxBrightness;
+ mClamperChangeListener.onChanged();
+ };
+ }
+
+ // Called in same looper: mHandler.getLooper()
+ public float getMaxBrightness() {
+ return mMaxBrightness;
+ }
+
+ // Called in same looper: mHandler.getLooper()
+ public float getTransitionRate() {
+ return mTransitionRate;
+ }
+
+
+ /**
+ * Updates brightness cap in response to ambient lux change.
+ * Called by ABC in same looper: mHandler.getLooper()
+ */
+ public void onAmbientLuxChange(float ambientLux) {
+ float expectedMaxBrightness = findBrightnessLimit(ambientLux);
+ if (mMaxBrightness == expectedMaxBrightness) {
+ mDesiredMaxBrightness = mMaxBrightness;
+ mDesiredTransitionDuration = -1;
+ mTransitionRate = -1f;
+ mHandler.removeCallbacks(mDebouncer);
+ } else if (mDesiredMaxBrightness != expectedMaxBrightness) {
+ mDesiredMaxBrightness = expectedMaxBrightness;
+ long debounceTime;
+ if (mDesiredMaxBrightness > mMaxBrightness) {
+ debounceTime = mConfiguration.mIncreaseConfig.mDebounceTimeMillis;
+ mDesiredTransitionDuration =
+ (float) mConfiguration.mIncreaseConfig.mTransitionTimeMillis / 1000;
+ } else {
+ debounceTime = mConfiguration.mDecreaseConfig.mDebounceTimeMillis;
+ mDesiredTransitionDuration =
+ (float) mConfiguration.mDecreaseConfig.mTransitionTimeMillis / 1000;
+ }
+
+ mHandler.removeCallbacks(mDebouncer);
+ mHandler.postDelayed(mDebouncer, debounceTime);
+ }
+ }
+
+ @VisibleForTesting
+ Configuration getConfiguration() {
+ return mConfiguration;
+ }
+
+ private float findBrightnessLimit(float ambientLux) {
+ float foundAmbientBoundary = Float.MAX_VALUE;
+ float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX;
+ for (Map.Entry<Float, Float> brightnessPoint :
+ mConfiguration.mMaxBrightnessLimits.entrySet()) {
+ float ambientBoundary = brightnessPoint.getKey();
+ // find ambient lux upper boundary closest to current ambient lux
+ if (ambientBoundary > ambientLux && ambientBoundary < foundAmbientBoundary) {
+ foundMaxBrightness = brightnessPoint.getValue();
+ foundAmbientBoundary = ambientBoundary;
+ }
+ }
+ return foundMaxBrightness;
+ }
+
+ @VisibleForTesting
+ static class Configuration {
+ final Map<Float, Float> mMaxBrightnessLimits = new HashMap<>();
+ final TransitionConfiguration mIncreaseConfig = new TransitionConfiguration();
+
+ final TransitionConfiguration mDecreaseConfig = new TransitionConfiguration();
+ }
+
+ @VisibleForTesting
+ static class TransitionConfiguration {
+ long mDebounceTimeMillis;
+
+ long mTransitionTimeMillis;
+ }
+}
diff --git a/services/core/java/com/android/server/display/config/HdrBrightnessData.java b/services/core/java/com/android/server/display/config/HdrBrightnessData.java
new file mode 100644
index 000000000000..06d3c5b87520
--- /dev/null
+++ b/services/core/java/com/android/server/display/config/HdrBrightnessData.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.config;
+
+import android.annotation.Nullable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Brightness config for HDR content
+ */
+public class HdrBrightnessData {
+
+ /**
+ * Lux to brightness map
+ */
+ public final Map<Float, Float> mMaxBrightnessLimits;
+
+ /**
+ * Debounce time for brightness increase
+ */
+ public final long mBrightnessIncreaseDebounceMillis;
+
+ /**
+ * Brightness increase animation duration
+ */
+ public final long mBrightnessIncreaseDurationMillis;
+
+ /**
+ * Debounce time for brightness decrease
+ */
+ public final long mBrightnessDecreaseDebounceMillis;
+
+ /**
+ * Brightness decrease animation duration
+ */
+ public final long mBrightnessDecreaseDurationMillis;
+
+ private HdrBrightnessData(Map<Float, Float> maxBrightnessLimits,
+ long brightnessIncreaseDebounceMillis, long brightnessIncreaseDurationMillis,
+ long brightnessDecreaseDebounceMillis, long brightnessDecreaseDurationMillis) {
+ mMaxBrightnessLimits = maxBrightnessLimits;
+ mBrightnessIncreaseDebounceMillis = brightnessIncreaseDebounceMillis;
+ mBrightnessIncreaseDurationMillis = brightnessIncreaseDurationMillis;
+ mBrightnessDecreaseDebounceMillis = brightnessDecreaseDebounceMillis;
+ mBrightnessDecreaseDurationMillis = brightnessDecreaseDurationMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "HdrBrightnessData {"
+ + "mMaxBrightnessLimits: " + mMaxBrightnessLimits
+ + ", mBrightnessIncreaseDebounceMillis: " + mBrightnessIncreaseDebounceMillis
+ + ", mBrightnessIncreaseDurationMillis: " + mBrightnessIncreaseDurationMillis
+ + ", mBrightnessDecreaseDebounceMillis: " + mBrightnessDecreaseDebounceMillis
+ + ", mBrightnessDecreaseDurationMillis: " + mBrightnessDecreaseDurationMillis
+ + "} ";
+ }
+
+ /**
+ * Loads HdrBrightnessData from DisplayConfiguration
+ */
+ @Nullable
+ public static HdrBrightnessData loadConfig(DisplayConfiguration config) {
+ HdrBrightnessConfig hdrConfig = config.getHdrBrightnessConfig();
+ if (hdrConfig == null) {
+ return null;
+ }
+
+ List<NonNegativeFloatToFloatPoint> points = hdrConfig.getBrightnessMap().getPoint();
+ Map<Float, Float> brightnessLimits = new HashMap<>();
+ for (NonNegativeFloatToFloatPoint point: points) {
+ brightnessLimits.put(point.getFirst().floatValue(), point.getSecond().floatValue());
+ }
+
+ return new HdrBrightnessData(brightnessLimits,
+ hdrConfig.getBrightnessIncreaseDebounceMillis().longValue(),
+ hdrConfig.getBrightnessIncreaseDurationMillis().longValue(),
+ hdrConfig.getBrightnessDecreaseDebounceMillis().longValue(),
+ hdrConfig.getBrightnessDecreaseDurationMillis().longValue());
+ }
+}
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index fddac6dcf874..aebd8a08ee3f 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -30,43 +30,68 @@ import java.util.function.Supplier;
public class DisplayManagerFlags {
private static final boolean DEBUG = false;
private static final String TAG = "DisplayManagerFlags";
- private boolean mIsConnectedDisplayManagementEnabled = false;
- private boolean mIsConnectedDisplayManagementEnabledSet = false;
- private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
- // TODO(b/299462337) Remove when the infrastructure is ready.
- if ((Build.IS_ENG || Build.IS_USERDEBUG)
- && SystemProperties.getBoolean("persist.sys." + flagName, false)) {
- return true;
- }
- try {
- return flagFunction.get();
- } catch (Throwable ex) {
- if (DEBUG) {
- Slog.i(TAG, "Flags not ready yet. Return false for " + flagName, ex);
- }
- return false;
- }
- }
+ private final FlagState mConnectedDisplayManagementFlagState = new FlagState(
+ Flags.FLAG_ENABLE_CONNECTED_DISPLAY_MANAGEMENT,
+ Flags::enableConnectedDisplayManagement);
+
+ private final FlagState mNbmControllerFlagState = new FlagState(
+ Flags.FLAG_ENABLE_NBM_CONTROLLER,
+ Flags::enableNbmController);
- // TODO(b/297159910): Simplify using READ-ONLY flags when available.
/** Returns whether connected display management is enabled or not. */
public boolean isConnectedDisplayManagementEnabled() {
- if (mIsConnectedDisplayManagementEnabledSet) {
+ return mConnectedDisplayManagementFlagState.isEnabled();
+ }
+
+ /** Returns whether hdr clamper is enabled on not*/
+ public boolean isNbmControllerEnabled() {
+ return mNbmControllerFlagState.isEnabled();
+ }
+
+ private static class FlagState {
+
+ private final String mName;
+
+ private final Supplier<Boolean> mFlagFunction;
+ private boolean mEnabledSet;
+ private boolean mEnabled;
+
+ private FlagState(String name, Supplier<Boolean> flagFunction) {
+ mName = name;
+ mFlagFunction = flagFunction;
+ }
+
+ // TODO(b/297159910): Simplify using READ-ONLY flags when available.
+ private boolean isEnabled() {
+ if (mEnabledSet) {
+ if (DEBUG) {
+ Slog.d(TAG, mName + ": mEnabled. Recall = " + mEnabled);
+ }
+ return mEnabled;
+ }
+ mEnabled = flagOrSystemProperty(mFlagFunction, mName);
if (DEBUG) {
- Slog.d(TAG, "isConnectedDisplayManagementEnabled. Recall = "
- + mIsConnectedDisplayManagementEnabled);
+ Slog.d(TAG, mName + ": mEnabled. Flag value = " + mEnabled);
}
- return mIsConnectedDisplayManagementEnabled;
+ mEnabledSet = true;
+ return mEnabled;
}
- mIsConnectedDisplayManagementEnabled =
- flagOrSystemProperty(Flags::enableConnectedDisplayManagement,
- Flags.FLAG_ENABLE_CONNECTED_DISPLAY_MANAGEMENT);
- if (DEBUG) {
- Slog.d(TAG, "isConnectedDisplayManagementEnabled. Flag value = "
- + mIsConnectedDisplayManagementEnabled);
+
+ private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
+ // TODO(b/299462337) Remove when the infrastructure is ready.
+ if ((Build.IS_ENG || Build.IS_USERDEBUG)
+ && SystemProperties.getBoolean("persist.sys." + flagName, false)) {
+ return true;
+ }
+ try {
+ return flagFunction.get();
+ } catch (Throwable ex) {
+ if (DEBUG) {
+ Slog.i(TAG, "Flags not ready yet. Return false for " + flagName, ex);
+ }
+ return false;
+ }
}
- mIsConnectedDisplayManagementEnabledSet = true;
- return mIsConnectedDisplayManagementEnabled;
}
}
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 2c3c66e2dfc9..12306b039225 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -9,3 +9,11 @@ flag {
bug: "280739508"
is_fixed_read_only: true
}
+
+flag {
+ name: "enable_nbm_controller"
+ namespace: "display_manager"
+ description: "Feature flag for Normal Brightness Mode Controller"
+ bug: "277877297"
+ is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/media/BluetoothRouteController.java b/services/core/java/com/android/server/media/BluetoothRouteController.java
index 66985e0b2533..ddeeacc76579 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteController.java
@@ -24,6 +24,8 @@ import android.content.Context;
import android.media.MediaRoute2Info;
import android.os.UserHandle;
+import com.android.media.flags.Flags;
+
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -53,15 +55,10 @@ import java.util.Objects;
return new NoOpBluetoothRouteController();
}
- MediaFeatureFlagManager flagManager = MediaFeatureFlagManager.getInstance();
- boolean isUsingLegacyController = flagManager.getBoolean(
- MediaFeatureFlagManager.FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER,
- true);
-
- if (isUsingLegacyController) {
- return new LegacyBluetoothRouteController(context, btAdapter, listener);
- } else {
+ if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
return new AudioPoliciesBluetoothRouteController(context, btAdapter, listener);
+ } else {
+ return new LegacyBluetoothRouteController(context, btAdapter, listener);
}
}
diff --git a/services/core/java/com/android/server/media/DeviceRouteController.java b/services/core/java/com/android/server/media/DeviceRouteController.java
index 3875c84e618b..e17f4a3fd42f 100644
--- a/services/core/java/com/android/server/media/DeviceRouteController.java
+++ b/services/core/java/com/android/server/media/DeviceRouteController.java
@@ -25,6 +25,8 @@ import android.media.IAudioService;
import android.media.MediaRoute2Info;
import android.os.ServiceManager;
+import com.android.media.flags.Flags;
+
/**
* Controls device routes.
*
@@ -44,18 +46,13 @@ import android.os.ServiceManager;
IAudioService audioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
- MediaFeatureFlagManager flagManager = MediaFeatureFlagManager.getInstance();
- boolean isUsingLegacyController = flagManager.getBoolean(
- MediaFeatureFlagManager.FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER,
- true);
-
- if (isUsingLegacyController) {
- return new LegacyDeviceRouteController(context,
+ if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+ return new AudioPoliciesDeviceRouteController(context,
audioManager,
audioService,
onDeviceRouteChangedListener);
} else {
- return new AudioPoliciesDeviceRouteController(context,
+ return new LegacyDeviceRouteController(context,
audioManager,
audioService,
onDeviceRouteChangedListener);
diff --git a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
index e31a7fc5d5ff..198040378dc6 100644
--- a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
@@ -508,7 +508,11 @@ class LegacyBluetoothRouteController implements BluetoothRouteController {
case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
clearActiveRoutesWithType(MediaRoute2Info.TYPE_BLUETOOTH_A2DP);
if (device != null) {
- addActiveRoute(mBluetoothRoutes.get(device.getAddress()));
+ if (DEBUG) {
+ Log.d(TAG, "Setting active a2dp devices. device=" + device);
+ }
+
+ addActiveDevices(device);
}
notifyBluetoothRoutesUpdated();
break;
diff --git a/services/core/java/com/android/server/media/MediaFeatureFlagManager.java b/services/core/java/com/android/server/media/MediaFeatureFlagManager.java
index f55550509f46..f90f64a19301 100644
--- a/services/core/java/com/android/server/media/MediaFeatureFlagManager.java
+++ b/services/core/java/com/android/server/media/MediaFeatureFlagManager.java
@@ -36,7 +36,6 @@ import java.lang.annotation.Target;
@StringDef(
prefix = "FEATURE_",
value = {
- FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER,
FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE
})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@@ -44,14 +43,6 @@ import java.lang.annotation.Target;
/* package */ @interface MediaFeatureFlag {}
/**
- * Whether to use old legacy implementation of BluetoothRouteController or new
- * 'Audio Strategies'-aware controller.
- */
- /* package */ static final @MediaFeatureFlag String
- FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER =
- "BluetoothRouteController__enable_legacy_bluetooth_routes_controller";
-
- /**
* Whether to use IMPORTANCE_FOREGROUND (i.e. 100) or IMPORTANCE_FOREGROUND_SERVICE (i.e. 125)
* as the minimum package importance for scanning.
*/
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 515c7fb09ab0..ebbe37a094a6 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -932,6 +932,7 @@ public final class MediaProjectionManagerService extends SystemService
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
+ Slog.v(TAG, "Start the token instance " + this);
// Cache result of calling into ActivityManagerService outside of the lock, to prevent
// deadlock with WindowManagerService.
final boolean hasFGS = mActivityManagerInternal.hasRunningForegroundService(
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ec071a73d74f..bada8165766c 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2047,7 +2047,6 @@ public class NotificationManagerService extends SystemService {
protected class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
SparseBooleanArray mUserInLockDownMode = new SparseBooleanArray();
- boolean mIsInLockDownMode = false;
StrongAuthTracker(Context context) {
super(context);
@@ -2827,9 +2826,6 @@ public class NotificationManagerService extends SystemService {
mAssistants.onBootPhaseAppsCanStart();
mConditionProviders.onBootPhaseAppsCanStart();
mHistoryManager.onBootPhaseAppsCanStart();
- if (expireBitmaps()) {
- NotificationBitmapJobService.scheduleJob(getContext());
- }
registerDeviceConfigChange();
migrateDefaultNAS();
maybeShowInitialReviewPermissionsNotification();
@@ -2838,6 +2834,10 @@ public class NotificationManagerService extends SystemService {
} else if (phase == SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY) {
mPreferencesHelper.updateFixedImportance(mUm.getUsers());
mPreferencesHelper.migrateNotificationPermissions(mUm.getUsers());
+ } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+ if (expireBitmaps()) {
+ NotificationBitmapJobService.scheduleJob(getContext());
+ }
}
}
@@ -6631,8 +6631,7 @@ public class NotificationManagerService extends SystemService {
}
};
- @VisibleForTesting
- static boolean isBigPictureWithBitmapOrIcon(Notification n) {
+ private static boolean isBigPictureWithBitmapOrIcon(Notification n) {
final boolean isBigPicture = n.isStyle(Notification.BigPictureStyle.class);
if (!isBigPicture) {
return false;
@@ -6650,15 +6649,12 @@ public class NotificationManagerService extends SystemService {
return false;
}
- @VisibleForTesting
- // TODO(b/298414239) Unit test via public API
- static boolean isBitmapExpired(long timePostedMs, long timeNowMs, long timeToLiveMs) {
+ private static boolean isBitmapExpired(long timePostedMs, long timeNowMs, long timeToLiveMs) {
final long timeDiff = timeNowMs - timePostedMs;
return timeDiff > timeToLiveMs;
}
- @VisibleForTesting
- void removeBitmapAndRepost(NotificationRecord r) {
+ private void removeBitmapAndRepost(NotificationRecord r) {
if (!isBigPictureWithBitmapOrIcon(r.getNotification())) {
return;
}
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index f95f7bc0d165..bd9be30b681b 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -17,7 +17,6 @@
package com.android.server.pm;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
@@ -228,7 +227,7 @@ public class AppDataHelper {
userId, flags, appId, seInfo, targetSdkVersion, usesSdk);
args.previousAppId = previousAppId;
- return batch.createAppData(args).whenComplete((ceDataInode, e) -> {
+ return batch.createAppData(args).whenComplete((createAppDataResult, e) -> {
// Note: this code block is executed with the Installer lock
// already held, since it's invoked as a side-effect of
// executeBatchLI()
@@ -237,7 +236,7 @@ public class AppDataHelper {
+ ", but trying to recover: " + e);
destroyAppDataLeafLIF(pkg, userId, flags);
try {
- ceDataInode = mInstaller.createAppData(args).ceDataInode;
+ createAppDataResult = mInstaller.createAppData(args);
logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
} catch (Installer.InstallerException e2) {
logCriticalInfo(Log.DEBUG, "Recovery failed!");
@@ -279,12 +278,19 @@ public class AppDataHelper {
}
}
+ final long ceDataInode = createAppDataResult.ceDataInode;
+ final long deDataInode = createAppDataResult.deDataInode;
+
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
- // TODO: mark this structure as dirty so we persist it!
synchronized (mPm.mLock) {
ps.setCeDataInode(ceDataInode, userId);
}
}
+ if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && deDataInode != -1) {
+ synchronized (mPm.mLock) {
+ ps.setDeDataInode(deDataInode, userId);
+ }
+ }
prepareAppDataContentsLeafLIF(pkg, ps, userId, flags);
});
@@ -609,7 +615,7 @@ public class AppDataHelper {
destroyAppDataLeafLIF(pkg, userId, flags);
}
- public void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
+ private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
final Computer snapshot = mPm.snapshotComputer();
final PackageStateInternal packageStateInternal =
snapshot.getPackageStateInternal(pkg.getPackageName());
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index ffa2af1e2f81..316c4aca1891 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -1024,7 +1024,7 @@ public class ComputerEngine implements Computer {
if ("android".equals(packageName) || "system".equals(packageName)) {
return androidApplication();
}
- if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
+ if ((flags & (MATCH_KNOWN_PACKAGES | MATCH_ARCHIVED_PACKAGES)) != 0) {
// Already generates the external package name
return generateApplicationInfoFromSettings(packageName,
flags, filterCallingUid, userId);
@@ -1518,7 +1518,6 @@ public class ComputerEngine implements Computer {
pi.sharedUserId = (sharedUser != null) ? sharedUser.getName() : null;
pi.firstInstallTime = state.getFirstInstallTimeMillis();
pi.lastUpdateTime = ps.getLastUpdateTime();
- pi.isArchived = isArchived(state);
ApplicationInfo ai = new ApplicationInfo();
ai.packageName = ps.getPackageName();
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index b5a373e35571..7d59210044d0 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -569,6 +569,7 @@ final class DeletePackageHelper {
ps.setUserState(nextUserId,
ps.getCeDataInode(nextUserId),
+ ps.getDeDataInode(nextUserId),
COMPONENT_ENABLED_STATE_DEFAULT,
false /*installed*/,
true /*stopped*/,
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 468b3a705bf1..e1e5e6db104a 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -44,6 +44,7 @@ import static android.os.incremental.IncrementalManager.isIncrementalPath;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
+
import static com.android.server.pm.DexOptHelper.useArtService;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
@@ -56,7 +57,6 @@ import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
import static com.android.server.pm.PackageManagerService.DEBUG_UPGRADE;
import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY;
-import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY;
import static com.android.server.pm.PackageManagerService.MIN_INSTALLABLE_TARGET_SDK;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.POST_INSTALL;
@@ -112,6 +112,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ArchivedPackageParcel;
import android.content.pm.DataLoaderType;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
@@ -180,7 +181,6 @@ import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.permission.Permission;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
-import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.SharedLibraryWrapper;
import com.android.server.pm.pkg.component.ComponentMutateUtils;
@@ -1144,15 +1144,18 @@ final class InstallPackageHelper {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
final ParsedPackage parsedPackage;
+ final ArchivedPackageParcel archivedPackage;
try (PackageParser2 pp = mPm.mInjector.getPreparingPackageParser()) {
if (request.getPackageLite() == null || !request.isArchived()) {
// TODO: pass packageLite from install request instead of reparsing the package
parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
+ archivedPackage = null;
} else {
// Archived install mode, no APK.
parsedPackage = pp.parsePackageFromPackageLite(request.getPackageLite(),
parseFlags);
+ archivedPackage = request.getPackageLite().getArchivedPackage();
}
} catch (PackageManagerException e) {
throw new PrepareFailure("Failed parse during installPackageLI", e);
@@ -1245,6 +1248,7 @@ final class InstallPackageHelper {
boolean systemApp = false;
boolean replace = false;
synchronized (mPm.mLock) {
+ final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
// Check if installing already existing package
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName);
@@ -1261,16 +1265,15 @@ final class InstallPackageHelper {
Slog.d(TAG, "Replacing existing renamed package: oldName="
+ oldName + " pkgName=" + pkgName);
}
- } else if (mPm.mPackages.containsKey(pkgName)) {
+ } else if (ps != null) {
// This package, under its official name, already exists
// on the device; we should replace it.
replace = true;
if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName);
}
-
- if (replace) {
+ final AndroidPackage oldPackage = mPm.mPackages.get(pkgName);
+ if (replace && oldPackage != null) {
// Prevent apps opting out from runtime permissions
- AndroidPackage oldPackage = mPm.mPackages.get(pkgName);
final int oldTargetSdk = oldPackage.getTargetSdkVersion();
final int newTargetSdk = parsedPackage.getTargetSdkVersion();
if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
@@ -1292,7 +1295,6 @@ final class InstallPackageHelper {
}
}
- PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
PackageSetting signatureCheckPs = ps;
// SDK libs can have other major versions with different package names.
@@ -1368,8 +1370,8 @@ final class InstallPackageHelper {
if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
systemApp = ps.isSystem();
- request.setOriginUsers(
- ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true));
+ request.setOriginUsers(ps.queryUsersInstalledOrHasData(
+ mPm.mUserManager.getUserIds()));
}
final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups());
@@ -1595,7 +1597,7 @@ final class InstallPackageHelper {
boolean shouldCloseFreezerBeforeReturn = true;
try {
- final PackageState oldPackageState;
+ final PackageSetting oldPackageState;
final AndroidPackage oldPackage;
String renamedPackage;
boolean sysPkg = false;
@@ -1648,7 +1650,7 @@ final class InstallPackageHelper {
}
} else {
SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails();
- SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails();
+ SigningDetails oldPkgSigningDetails = oldPackageState.getSigningDetails();
// default to original signature matching
if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails,
SigningDetails.CertCapabilities.INSTALLED_DATA)
@@ -1668,7 +1670,8 @@ final class InstallPackageHelper {
}
// don't allow a system upgrade unless the upgrade hash matches
- if (oldPackage.getRestrictUpdateHash() != null && oldPackageState.isSystem()) {
+ if (oldPackage != null && oldPackage.getRestrictUpdateHash() != null
+ && oldPackageState.isSystem()) {
final byte[] digestBytes;
try {
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
@@ -1691,23 +1694,26 @@ final class InstallPackageHelper {
parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
}
- // APK should not change its sharedUserId declarations
- final var oldSharedUid = oldPackage.getSharedUserId() != null
- ? oldPackage.getSharedUserId() : "<nothing>";
- final var newSharedUid = parsedPackage.getSharedUserId() != null
- ? parsedPackage.getSharedUserId() : "<nothing>";
- if (!oldSharedUid.equals(newSharedUid)) {
- throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
- "Package " + parsedPackage.getPackageName()
- + " shared user changed from "
- + oldSharedUid + " to " + newSharedUid);
- }
+ if (oldPackage != null) {
+ // APK should not change its sharedUserId declarations
+ final var oldSharedUid = oldPackage.getSharedUserId() != null
+ ? oldPackage.getSharedUserId() : "<nothing>";
+ final var newSharedUid = parsedPackage.getSharedUserId() != null
+ ? parsedPackage.getSharedUserId() : "<nothing>";
+ if (!oldSharedUid.equals(newSharedUid)) {
+ throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
+ "Package " + parsedPackage.getPackageName()
+ + " shared user changed from "
+ + oldSharedUid + " to " + newSharedUid);
+ }
- // APK should not re-join shared UID
- if (oldPackage.isLeavingSharedUser() && !parsedPackage.isLeavingSharedUser()) {
- throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
- "Package " + parsedPackage.getPackageName()
- + " attempting to rejoin " + newSharedUid);
+ // APK should not re-join shared UID
+ if (oldPackage.isLeavingSharedUser()
+ && !parsedPackage.isLeavingSharedUser()) {
+ throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
+ "Package " + parsedPackage.getPackageName()
+ + " attempting to rejoin " + newSharedUid);
+ }
}
// In case of rollback, remember per-user/profile install state
@@ -1740,8 +1746,8 @@ final class InstallPackageHelper {
// Update what is removed
PackageRemovedInfo removedInfo = new PackageRemovedInfo(mPm);
- removedInfo.mUid = oldPackage.getUid();
- removedInfo.mRemovedPackage = oldPackage.getPackageName();
+ removedInfo.mUid = ps.getAppId();
+ removedInfo.mRemovedPackage = ps.getPackageName();
removedInfo.mInstallerPackageName =
ps.getInstallSource().mInstallerPackageName;
removedInfo.mIsStaticSharedLib =
@@ -1760,8 +1766,8 @@ final class InstallPackageHelper {
removedInfo.mUninstallReasons.put(userId,
ps.getUninstallReason(userId));
}
- removedInfo.mIsExternal = oldPackage.isExternalStorage();
- removedInfo.mRemovedPackageVersionCode = oldPackage.getLongVersionCode();
+ removedInfo.mIsExternal = oldPackageState.isExternalStorage();
+ removedInfo.mRemovedPackageVersionCode = oldPackageState.getVersionCode();
request.setRemovedInfo(removedInfo);
sysPkg = oldPackageState.isSystem();
@@ -1801,7 +1807,7 @@ final class InstallPackageHelper {
} else { // new package install
ps = null;
disabledPs = null;
- oldPackage = null;
+ oldPackageState = null;
// Remember this for later, in case we need to rollback this install
String pkgName1 = parsedPackage.getPackageName();
@@ -1832,8 +1838,8 @@ final class InstallPackageHelper {
shouldCloseFreezerBeforeReturn = false;
request.setPrepareResult(replace, targetScanFlags, targetParseFlags,
- oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
- ps, disabledPs);
+ oldPackageState, parsedPackage, archivedPackage,
+ replace /* clearCodeCache */, sysPkg, ps, disabledPs);
} finally {
request.setFreezer(freezer);
if (shouldCloseFreezerBeforeReturn) {
@@ -2077,7 +2083,7 @@ final class InstallPackageHelper {
// Set the update and install times
PackageStateInternal deletedPkgSetting = mPm.snapshotComputer()
- .getPackageStateInternal(oldPackage.getPackageName());
+ .getPackageStateInternal(packageName);
// TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided
// by apexd to be more accurate.
installRequest.setScannedPackageSettingFirstInstallTimeFromReplaced(
@@ -2126,8 +2132,10 @@ final class InstallPackageHelper {
if (oldCodePaths == null) {
oldCodePaths = new ArraySet<>();
}
- Collections.addAll(oldCodePaths, oldPackage.getBaseApkPath());
- Collections.addAll(oldCodePaths, oldPackage.getSplitCodePaths());
+ if (oldPackage != null) {
+ Collections.addAll(oldCodePaths, oldPackage.getBaseApkPath());
+ Collections.addAll(oldCodePaths, oldPackage.getSplitCodePaths());
+ }
ps1.setOldCodePaths(oldCodePaths);
} else {
ps1.setOldCodePaths(null);
@@ -2161,6 +2169,9 @@ final class InstallPackageHelper {
}
}
if (installRequest.getReturnCode() == PackageManager.INSTALL_SUCCEEDED) {
+ mPm.createArchiveStateIfNeeded(ps,
+ installRequest.getArchivedPackage(),
+ installRequest.getNewUsers());
mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers());
mPm.updateInstantAppInstallerLocked(packageName);
}
@@ -2852,46 +2863,11 @@ final class InstallPackageHelper {
mPm.notifyInstantAppPackageInstalled(request.getPkg().getPackageName(),
request.getNewUsers());
- // Determine the set of users who are adding this package for
- // the first time vs. those who are seeing an update.
- int[] firstUserIds = EMPTY_INT_ARRAY;
- int[] firstInstantUserIds = EMPTY_INT_ARRAY;
- int[] updateUserIds = EMPTY_INT_ARRAY;
- int[] instantUserIds = EMPTY_INT_ARRAY;
- final boolean allNewUsers = request.getOriginUsers() == null
- || request.getOriginUsers().length == 0;
- for (int newUser : request.getNewUsers()) {
- final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser)
- .isInstantApp();
- if (allNewUsers) {
- if (isInstantApp) {
- firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
- } else {
- firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
- }
- continue;
- }
- boolean isNew = true;
- for (int origUser : request.getOriginUsers()) {
- if (origUser == newUser) {
- isNew = false;
- break;
- }
- }
- if (isNew) {
- if (isInstantApp) {
- firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
- } else {
- firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
- }
- } else {
- if (isInstantApp) {
- instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
- } else {
- updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
- }
- }
- }
+ request.populateBroadcastUsers();
+ final int[] firstUserIds = request.getFirstTimeBroadcastUserIds();
+ final int[] firstInstantUserIds = request.getFirstTimeBroadcastInstantUserIds();
+ final int[] updateUserIds = request.getUpdateBroadcastUserIds();
+ final int[] instantUserIds = request.getUpdateBroadcastInstantUserIds();
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_UID, request.getAppId());
@@ -2969,12 +2945,10 @@ final class InstallPackageHelper {
}
// If package installer is defined, notify package installer about new
// app installed
- if (mPm.mRequiredInstallerPackage != null) {
- mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
- extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
- mPm.mRequiredInstallerPackage, null /*finishedReceiver*/,
- firstUserIds, instantUserIds, null /* broadcastAllowList */, null);
- }
+ mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+ extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
+ mPm.mRequiredInstallerPackage, null /*finishedReceiver*/,
+ firstUserIds, instantUserIds, null /* broadcastAllowList */, null);
// Send replaced for users that don't see the package for the first time
if (update) {
@@ -3070,7 +3044,7 @@ final class InstallPackageHelper {
}
}
- if (allNewUsers && !update) {
+ if (request.isAllNewUsers() && !update) {
mPm.notifyPackageAdded(packageName, request.getAppId());
} else {
mPm.notifyPackageChanged(packageName, request.getAppId());
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index e1cfc418bfe5..ff347acdfd96 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -21,6 +21,8 @@ import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN;
import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.os.Process.INVALID_UID;
+
+import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY;
import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -28,6 +30,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.apex.ApexInfo;
import android.app.AppOpsManager;
+import android.content.pm.ArchivedPackageParcel;
import android.content.pm.DataLoaderType;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInstaller;
@@ -43,6 +46,7 @@ import android.util.ArrayMap;
import android.util.ExceptionUtils;
import android.util.Slog;
+import com.android.internal.util.ArrayUtils;
import com.android.server.art.model.DexoptResult;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.AndroidPackage;
@@ -52,6 +56,7 @@ import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
final class InstallRequest {
@@ -69,11 +74,13 @@ final class InstallRequest {
private int mParseFlags;
private boolean mReplace;
- @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
- private AndroidPackage mExistingPackage;
+ @Nullable /* The original package's name if it is being replaced, otherwise {@code null} */
+ private String mExistingPackageName;
/** parsed package to be scanned */
@Nullable
private ParsedPackage mParsedPackage;
+ @Nullable
+ private ArchivedPackageParcel mArchivedPackage;
private boolean mClearCodeCache;
private boolean mSystem;
@Nullable
@@ -132,6 +139,15 @@ final class InstallRequest {
private int mDexoptStatus;
+ @NonNull
+ private int[] mFirstTimeBroadcastUserIds = EMPTY_INT_ARRAY;
+ @NonNull
+ private int[] mFirstTimeBroadcastInstantUserIds = EMPTY_INT_ARRAY;
+ @NonNull
+ private int[] mUpdateBroadcastUserIds = EMPTY_INT_ARRAY;
+ @NonNull
+ private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY;
+
// New install
InstallRequest(InstallingSession params) {
mUserId = params.getUser().getIdentifier();
@@ -177,6 +193,7 @@ final class InstallRequest {
}
mInstallArgs = null;
mParsedPackage = parsedPackage;
+ mArchivedPackage = null;
mParseFlags = parseFlags;
mScanFlags = scanFlags;
mScanResult = scanResult;
@@ -413,11 +430,6 @@ final class InstallRequest {
}
@Nullable
- public AndroidPackage getExistingPackage() {
- return mExistingPackage;
- }
-
- @Nullable
public List<String> getAllowlistedRestrictedPermissions() {
return mInstallArgs == null ? null : mInstallArgs.mAllowlistedRestrictedPermissions;
}
@@ -441,6 +453,9 @@ final class InstallRequest {
return mParsedPackage;
}
+ @Nullable
+ public ArchivedPackageParcel getArchivedPackage() { return mArchivedPackage; }
+
@ParsingPackageUtils.ParseFlags
public int getParseFlags() {
return mParseFlags;
@@ -453,10 +468,7 @@ final class InstallRequest {
@Nullable
public String getExistingPackageName() {
- if (mExistingPackage != null) {
- return mExistingPackage.getPackageName();
- }
- return null;
+ return mExistingPackageName;
}
@Nullable
@@ -627,6 +639,25 @@ final class InstallRequest {
return mDexoptStatus;
}
+ public boolean isAllNewUsers() {
+ return mOrigUsers == null || mOrigUsers.length == 0;
+ }
+ public int[] getFirstTimeBroadcastUserIds() {
+ return mFirstTimeBroadcastUserIds;
+ }
+
+ public int[] getFirstTimeBroadcastInstantUserIds() {
+ return mFirstTimeBroadcastInstantUserIds;
+ }
+
+ public int[] getUpdateBroadcastUserIds() {
+ return mUpdateBroadcastUserIds;
+ }
+
+ public int[] getUpdateBroadcastInstantUserIds() {
+ return mUpdateBroadcastInstantUserIds;
+ }
+
public void setScanFlags(int scanFlags) {
mScanFlags = scanFlags;
}
@@ -729,14 +760,17 @@ final class InstallRequest {
}
public void setPrepareResult(boolean replace, int scanFlags,
- int parseFlags, AndroidPackage existingPackage,
- ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
+ int parseFlags, PackageState existingPackageState,
+ ParsedPackage packageToScan, ArchivedPackageParcel archivedPackage,
+ boolean clearCodeCache, boolean system,
PackageSetting originalPs, PackageSetting disabledPs) {
mReplace = replace;
mScanFlags = scanFlags;
mParseFlags = parseFlags;
- mExistingPackage = existingPackage;
+ mExistingPackageName =
+ existingPackageState != null ? existingPackageState.getPackageName() : null;
mParsedPackage = packageToScan;
+ mArchivedPackage = archivedPackage;
mClearCodeCache = clearCodeCache;
mSystem = system;
mOriginalPs = originalPs;
@@ -769,6 +803,58 @@ final class InstallRequest {
}
}
+ /**
+ * Determine the set of users who are adding this package for the first time vs. those who are
+ * seeing an update.
+ */
+ public void populateBroadcastUsers() {
+ assertScanResultExists();
+ mFirstTimeBroadcastUserIds = EMPTY_INT_ARRAY;
+ mFirstTimeBroadcastInstantUserIds = EMPTY_INT_ARRAY;
+ mUpdateBroadcastUserIds = EMPTY_INT_ARRAY;
+ mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY;
+
+ final boolean allNewUsers = isAllNewUsers();
+ if (allNewUsers) {
+ // App was not currently installed on any user
+ for (int newUser : mNewUsers) {
+ final boolean isInstantApp =
+ mScanResult.mPkgSetting.getUserStateOrDefault(newUser).isInstantApp();
+ if (isInstantApp) {
+ mFirstTimeBroadcastInstantUserIds =
+ ArrayUtils.appendInt(mFirstTimeBroadcastInstantUserIds, newUser);
+ } else {
+ mFirstTimeBroadcastUserIds =
+ ArrayUtils.appendInt(mFirstTimeBroadcastUserIds, newUser);
+ }
+ }
+ return;
+ }
+ // App was already installed on some users, but is new to some other users
+ for (int newUser : mNewUsers) {
+ boolean isFirstTimeUser = !ArrayUtils.contains(mOrigUsers, newUser);
+ final boolean isInstantApp =
+ mScanResult.mPkgSetting.getUserStateOrDefault(newUser).isInstantApp();
+ if (isFirstTimeUser) {
+ if (isInstantApp) {
+ mFirstTimeBroadcastInstantUserIds =
+ ArrayUtils.appendInt(mFirstTimeBroadcastInstantUserIds, newUser);
+ } else {
+ mFirstTimeBroadcastUserIds =
+ ArrayUtils.appendInt(mFirstTimeBroadcastUserIds, newUser);
+ }
+ } else {
+ if (isInstantApp) {
+ mUpdateBroadcastInstantUserIds =
+ ArrayUtils.appendInt(mUpdateBroadcastInstantUserIds, newUser);
+ } else {
+ mUpdateBroadcastUserIds =
+ ArrayUtils.appendInt(mUpdateBroadcastUserIds, newUser);
+ }
+ }
+ }
+ }
+
public void onPrepareStarted() {
if (mPackageMetrics != null) {
mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE);
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 6233c9bc4dad..0ebd33b9cd81 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -257,6 +257,7 @@ public class Installer extends SystemService {
private static CreateAppDataResult buildPlaceholderCreateAppDataResult() {
final CreateAppDataResult result = new CreateAppDataResult();
result.ceDataInode = -1;
+ result.deDataInode = -1;
result.exceptionCode = 0;
result.exceptionMessage = null;
return result;
@@ -361,7 +362,7 @@ public class Installer extends SystemService {
private boolean mExecuted;
private final List<CreateAppDataArgs> mArgs = new ArrayList<>();
- private final List<CompletableFuture<Long>> mFutures = new ArrayList<>();
+ private final List<CompletableFuture<CreateAppDataResult>> mFutures = new ArrayList<>();
/**
* Enqueue the given {@code installd} operation to be executed in the
@@ -371,11 +372,12 @@ public class Installer extends SystemService {
* {@link Installer} object.
*/
@NonNull
- public synchronized CompletableFuture<Long> createAppData(CreateAppDataArgs args) {
+ public synchronized CompletableFuture<CreateAppDataResult> createAppData(
+ CreateAppDataArgs args) {
if (mExecuted) {
throw new IllegalStateException();
}
- final CompletableFuture<Long> future = new CompletableFuture<>();
+ final CompletableFuture<CreateAppDataResult> future = new CompletableFuture<>();
mArgs.add(args);
mFutures.add(future);
return future;
@@ -402,9 +404,9 @@ public class Installer extends SystemService {
final CreateAppDataResult[] results = installer.createAppDataBatched(args);
for (int j = 0; j < results.length; j++) {
final CreateAppDataResult result = results[j];
- final CompletableFuture<Long> future = mFutures.get(i + j);
+ final CompletableFuture<CreateAppDataResult> future = mFutures.get(i + j);
if (result.exceptionCode == 0) {
- future.complete(result.ceDataInode);
+ future.complete(result);
} else {
future.completeExceptionally(
new InstallerException(result.exceptionMessage));
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 64cdca3b5784..551b1ae57973 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -31,12 +31,15 @@ import android.app.BroadcastOptions;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.ArchivedActivityParcel;
+import android.content.pm.ArchivedPackageParcel;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -56,6 +59,7 @@ import com.android.server.pm.pkg.ArchiveState.ArchiveActivityInfo;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageUserStateInternal;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -158,7 +162,8 @@ public class PackageArchiver {
String responsibleInstallerPackage = getResponsibleInstallerPackage(ps);
verifyInstaller(responsibleInstallerPackage);
- List<LauncherActivityInfo> mainActivities = getLauncherActivityInfos(ps, userId);
+ List<LauncherActivityInfo> mainActivities = getLauncherActivityInfos(ps.getPackageName(),
+ userId);
final CompletableFuture<ArchiveState> archiveState = new CompletableFuture<>();
mPm.mHandler.post(() -> {
try {
@@ -172,13 +177,34 @@ public class PackageArchiver {
return archiveState;
}
- private ArchiveState createArchiveStateInternal(String packageName, int userId,
+ static ArchiveState createArchiveState(@NonNull ArchivedPackageParcel archivedPackage,
+ int userId, String installerPackage) {
+ try {
+ var packageName = archivedPackage.packageName;
+ var mainActivities = archivedPackage.archivedActivities;
+ List<ArchiveActivityInfo> archiveActivityInfos = new ArrayList<>(mainActivities.length);
+ for (int i = 0, size = mainActivities.length; i < size; ++i) {
+ var mainActivity = mainActivities[i];
+ Path iconPath = storeIconForParcel(packageName, mainActivity, userId, i);
+ ArchiveActivityInfo activityInfo = new ArchiveActivityInfo(
+ mainActivity.title, iconPath, null);
+ archiveActivityInfos.add(activityInfo);
+ }
+
+ return new ArchiveState(archiveActivityInfos, installerPackage);
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to create archive state", e);
+ return null;
+ }
+ }
+
+ ArchiveState createArchiveStateInternal(String packageName, int userId,
List<LauncherActivityInfo> mainActivities, String installerPackage)
throws IOException {
- List<ArchiveActivityInfo> archiveActivityInfos = new ArrayList<>();
- for (int i = 0; i < mainActivities.size(); i++) {
+ List<ArchiveActivityInfo> archiveActivityInfos = new ArrayList<>(mainActivities.size());
+ for (int i = 0, size = mainActivities.size(); i < size; i++) {
LauncherActivityInfo mainActivity = mainActivities.get(i);
- Path iconPath = storeIcon(packageName, mainActivity, userId);
+ Path iconPath = storeIcon(packageName, mainActivity, userId, i);
ArchiveActivityInfo activityInfo = new ArchiveActivityInfo(
mainActivity.getLabel().toString(), iconPath, null);
archiveActivityInfos.add(activityInfo);
@@ -188,17 +214,30 @@ public class PackageArchiver {
}
// TODO(b/298452477) Handle monochrome icons.
+ private static Path storeIconForParcel(String packageName, ArchivedActivityParcel mainActivity,
+ @UserIdInt int userId, int index) throws IOException {
+ if (mainActivity.iconBitmap == null) {
+ return null;
+ }
+ File iconsDir = createIconsDir(userId);
+ File iconFile = new File(iconsDir, packageName + "-" + index + ".png");
+ try (FileOutputStream out = new FileOutputStream(iconFile)) {
+ out.write(mainActivity.iconBitmap);
+ out.flush();
+ }
+ return iconFile.toPath();
+ }
+
@VisibleForTesting
Path storeIcon(String packageName, LauncherActivityInfo mainActivity,
- @UserIdInt int userId)
- throws IOException {
+ @UserIdInt int userId, int index) throws IOException {
int iconResourceId = mainActivity.getActivityInfo().getIconResource();
if (iconResourceId == 0) {
// The app doesn't define an icon. No need to store anything.
return null;
}
File iconsDir = createIconsDir(userId);
- File iconFile = new File(iconsDir, packageName + "-" + mainActivity.getName() + ".png");
+ File iconFile = new File(iconsDir, packageName + "-" + index + ".png");
Bitmap icon = drawableToBitmap(mainActivity.getIcon(/* density= */ 0));
try (FileOutputStream out = new FileOutputStream(iconFile)) {
// Note: Quality is ignored for PNGs.
@@ -228,6 +267,9 @@ public class PackageArchiver {
*/
public boolean verifySupportsUnarchival(String installerPackage) {
// TODO(b/278553670) Check if installerPackage supports unarchival.
+ if (TextUtils.isEmpty(installerPackage)) {
+ return false;
+ }
return true;
}
@@ -310,16 +352,16 @@ public class PackageArchiver {
/* initialExtras= */ null);
}
- private List<LauncherActivityInfo> getLauncherActivityInfos(PackageStateInternal ps,
+ List<LauncherActivityInfo> getLauncherActivityInfos(String packageName,
int userId) throws PackageManager.NameNotFoundException {
List<LauncherActivityInfo> mainActivities =
Binder.withCleanCallingIdentity(() -> getLauncherApps().getActivityList(
- ps.getPackageName(),
+ packageName,
new UserHandle(userId)));
if (mainActivities.isEmpty()) {
throw new PackageManager.NameNotFoundException(
TextUtils.formatSimple("The app %s does not have a main activity.",
- ps.getPackageName()));
+ packageName));
}
return mainActivities;
@@ -340,7 +382,7 @@ public class PackageArchiver {
return DEFAULT_UNARCHIVE_FOREGROUND_TIMEOUT_MS;
}
- private String getResponsibleInstallerPackage(PackageStateInternal ps) {
+ static String getResponsibleInstallerPackage(PackageStateInternal ps) {
return TextUtils.isEmpty(ps.getInstallSource().mUpdateOwnerPackageName)
? ps.getInstallSource().mInstallerPackageName
: ps.getInstallSource().mUpdateOwnerPackageName;
@@ -423,7 +465,7 @@ public class PackageArchiver {
}
}
- private File createIconsDir(@UserIdInt int userId) throws IOException {
+ private static File createIconsDir(@UserIdInt int userId) throws IOException {
File iconsDir = getIconsDir(userId);
if (!iconsDir.isDirectory()) {
iconsDir.delete();
@@ -436,7 +478,7 @@ public class PackageArchiver {
return iconsDir;
}
- private File getIconsDir(int userId) {
+ private static File getIconsDir(int userId) {
return new File(Environment.getDataSystemCeDirectory(userId), ARCHIVE_ICONS_DIR);
}
@@ -462,4 +504,90 @@ public class PackageArchiver {
drawable.draw(canvas);
return bitmap;
}
+
+ private static byte[] bytesFromBitmapFile(Path path) throws IOException {
+ if (path == null) {
+ return null;
+ }
+ // Technically we could just read the bytes, but we want to be sure we store the
+ // right format.
+ return bytesFromBitmap(BitmapFactory.decodeFile(path.toString()));
+ }
+
+ private static byte[] bytesFromBitmap(Bitmap bitmap) throws IOException {
+ if (bitmap == null) {
+ return null;
+ }
+
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream(
+ bitmap.getByteCount())) {
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
+ return baos.toByteArray();
+ }
+ }
+
+ /**
+ * Creates serializable archived activities from existing ArchiveState.
+ */
+ static ArchivedActivityParcel[] createArchivedActivities(ArchiveState archiveState)
+ throws IOException {
+ var infos = archiveState.getActivityInfos();
+ if (infos == null || infos.isEmpty()) {
+ throw new IllegalArgumentException("No activities in archive state");
+ }
+
+ List<ArchivedActivityParcel> activities = new ArrayList<>(infos.size());
+ for (int i = 0, size = infos.size(); i < size; ++i) {
+ var info = infos.get(i);
+ if (info == null) {
+ continue;
+ }
+ var archivedActivity = new ArchivedActivityParcel();
+ archivedActivity.title = info.getTitle();
+ archivedActivity.iconBitmap = bytesFromBitmapFile(info.getIconBitmap());
+ archivedActivity.monochromeIconBitmap = bytesFromBitmapFile(
+ info.getMonochromeIconBitmap());
+ activities.add(archivedActivity);
+ }
+
+ if (activities.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Failed to extract title and icon of main activities");
+ }
+
+ return activities.toArray(new ArchivedActivityParcel[activities.size()]);
+ }
+
+ /**
+ * Creates serializable archived activities from launcher activities.
+ */
+ static ArchivedActivityParcel[] createArchivedActivities(List<LauncherActivityInfo> infos)
+ throws IOException {
+ if (infos == null || infos.isEmpty()) {
+ throw new IllegalArgumentException("No launcher activities");
+ }
+
+ List<ArchivedActivityParcel> activities = new ArrayList<>(infos.size());
+ for (int i = 0, size = infos.size(); i < size; ++i) {
+ var info = infos.get(i);
+ if (info == null) {
+ continue;
+ }
+ var archivedActivity = new ArchivedActivityParcel();
+ archivedActivity.title = info.getLabel().toString();
+ archivedActivity.iconBitmap =
+ info.getActivityInfo().getIconResource() == 0 ? null : bytesFromBitmap(
+ drawableToBitmap(info.getIcon(/* density= */ 0)));
+ // TODO(b/298452477) Handle monochrome icons.
+ archivedActivity.monochromeIconBitmap = null;
+ activities.add(archivedActivity);
+ }
+
+ if (activities.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Failed to extract title and icon of main activities");
+ }
+
+ return activities.toArray(new ArchivedActivityParcel[activities.size()]);
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 9e0a83cda584..512d338b0b48 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -40,6 +40,7 @@ import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_WRONLY;
+
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.util.XmlUtils.readBitmapAttribute;
import static com.android.internal.util.XmlUtils.readByteArrayAttribute;
@@ -1165,11 +1166,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new IllegalArgumentException(
"Archived installation can only use Streaming System DataLoader.");
}
- if (!TextUtils.isEmpty(params.appPackageName) && !isArchivedInstallationAllowed(
- params.appPackageName)) {
- throw new IllegalArgumentException(
- "Archived installation of this package is not allowed.");
- }
}
}
@@ -1548,6 +1544,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
var archPkg = metadata.getArchivedPackage();
+ if (archPkg == null) {
+ throw new PackageManagerException(INSTALL_FAILED_VERIFICATION_FAILURE,
+ "Metadata does not contain ArchivedPackage: " + file);
+ }
if (archPkg.packageName == null || archPkg.signingDetails == null) {
throw new PackageManagerException(INSTALL_FAILED_VERIFICATION_FAILURE,
"ArchivedPackage does not contain required info: " + file);
@@ -3395,8 +3395,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Archived installation of this package is not allowed.");
}
- if (!isInstalledByAdb(getInstallSource().mInitiatingPackageName)
- && !mPm.mInstallerService.mPackageArchiver.verifySupportsUnarchival(
+ if (!mPm.mInstallerService.mPackageArchiver.verifySupportsUnarchival(
getInstallSource().mInstallerPackageName)) {
throw new PackageManagerException(
PackageManager.INSTALL_FAILED_SESSION_INVALID,
@@ -3641,6 +3640,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock")
private void maybeStageFsveritySignatureLocked(File origFile, File targetFile,
boolean fsVerityRequired) throws PackageManagerException {
+ if (android.security.Flags.deprecateFsvSig()) {
+ return;
+ }
final File originalSignature = new File(
VerityUtils.getFsveritySignatureFilePath(origFile.getPath()));
if (originalSignature.exists()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d23dcbc5f18e..b5b6ce0805d5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -36,6 +36,7 @@ import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
+
import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME;
import static com.android.server.pm.DexOptHelper.useArtService;
@@ -116,11 +117,7 @@ import android.content.pm.UserPackage;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VersionedPackage;
import android.content.pm.overlay.OverlayPaths;
-import android.content.pm.parsing.ApkLite;
-import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.PackageLite;
-import android.content.pm.parsing.result.ParseResult;
-import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
@@ -228,6 +225,7 @@ import com.android.server.pm.permission.LegacyPermissionSettings;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.pm.pkg.ArchiveState;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageUserState;
@@ -1438,6 +1436,92 @@ public class PackageManagerService implements PackageSender, TestUtilityService
return extras;
}
+ ArchivedPackageParcel getArchivedPackageInternal(@NonNull String packageName, int userId) {
+ Objects.requireNonNull(packageName);
+ int binderUid = Binder.getCallingUid();
+
+ Computer snapshot = snapshotComputer();
+ snapshot.enforceCrossUserPermission(binderUid, userId, true, true,
+ "getArchivedPackage");
+
+ ArchivedPackageParcel archPkg = new ArchivedPackageParcel();
+ archPkg.packageName = packageName;
+
+ ArchiveState archiveState;
+ synchronized (mLock) {
+ PackageSetting ps = mSettings.getPackageLPr(packageName);
+ if (ps == null) {
+ return null;
+ }
+ var psi = ps.getUserStateOrDefault(userId);
+ archiveState = psi.getArchiveState();
+ if (archiveState == null && !psi.isInstalled()) {
+ return null;
+ }
+
+ archPkg.signingDetails = ps.getSigningDetails();
+
+ long longVersionCode = ps.getVersionCode();
+ archPkg.versionCodeMajor = (int) (longVersionCode >> 32);
+ archPkg.versionCode = (int) longVersionCode;
+
+ // TODO(b/297916136): extract target sdk version.
+ archPkg.targetSdkVersion = MIN_INSTALLABLE_TARGET_SDK;
+
+ // These get translated in flags important for user data management.
+ archPkg.defaultToDeviceProtectedStorage = String.valueOf(
+ ps.isDefaultToDeviceProtectedStorage());
+ archPkg.requestLegacyExternalStorage = String.valueOf(
+ ps.isRequestLegacyExternalStorage());
+ archPkg.userDataFragile = String.valueOf(ps.isUserDataFragile());
+ }
+
+ try {
+ if (archiveState != null) {
+ archPkg.archivedActivities = PackageArchiver.createArchivedActivities(
+ archiveState);
+ } else {
+ var mainActivities =
+ mInstallerService.mPackageArchiver.getLauncherActivityInfos(packageName,
+ userId);
+ archPkg.archivedActivities = PackageArchiver.createArchivedActivities(
+ mainActivities);
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Package does not have a main activity", e);
+ }
+
+ return archPkg;
+ }
+
+ void createArchiveStateIfNeeded(PackageSetting pkgSetting, ArchivedPackageParcel archivePackage,
+ int[] userIds) {
+ if (pkgSetting == null || archivePackage == null
+ || archivePackage.archivedActivities == null || userIds == null
+ || userIds.length == 0) {
+ return;
+ }
+
+ String responsibleInstallerPackage = PackageArchiver.getResponsibleInstallerPackage(
+ pkgSetting);
+ // TODO(b/278553670) Check if responsibleInstallerPackage supports unarchival.
+ if (TextUtils.isEmpty(responsibleInstallerPackage)) {
+ Slog.e(TAG, "Can't create archive state: responsible installer is empty");
+ return;
+ }
+ for (int userId : userIds) {
+ var archiveState = PackageArchiver.createArchiveState(archivePackage, userId,
+ responsibleInstallerPackage);
+ if (archiveState == null) {
+ continue;
+ }
+ pkgSetting
+ .modifyUserState(userId)
+ .setArchiveState(archiveState);
+ }
+ }
+
+
void scheduleWriteSettings() {
// We normally invalidate when we write settings, but in cases where we delay and
// coalesce settings writes, this strategy would have us invalidate the cache too late.
@@ -6301,35 +6385,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
@Override
- public ArchivedPackageParcel getArchivedPackage(String apkPath) {
- ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
- ParseResult<ApkLite> result = ApkLiteParseUtils.parseApkLite(input.reset(),
- new File(apkPath), ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES);
- if (result.isError()) {
- throw new IllegalArgumentException(result.getErrorMessage(), result.getException());
- }
- final ApkLite apk = result.getResult();
-
- ArchivedPackageParcel archPkg = new ArchivedPackageParcel();
- archPkg.packageName = apk.getPackageName();
- archPkg.signingDetails = apk.getSigningDetails();
-
- archPkg.versionCodeMajor = apk.getVersionCodeMajor();
- archPkg.versionCode = apk.getVersionCode();
-
- archPkg.targetSdkVersion = apk.getTargetSdkVersion();
-
- // These get translated in flags important for user data management.
- archPkg.backupAllowed = String.valueOf(apk.isBackupAllowed());
- archPkg.defaultToDeviceProtectedStorage = String.valueOf(
- apk.isDefaultToDeviceProtectedStorage());
- archPkg.requestLegacyExternalStorage = String.valueOf(
- apk.isRequestLegacyExternalStorage());
- archPkg.userDataFragile = String.valueOf(apk.isUserDataFragile());
- archPkg.clearUserDataOnFailedRestoreAllowed = String.valueOf(
- apk.isClearUserDataOnFailedRestoreAllowed());
-
- return archPkg;
+ public ArchivedPackageParcel getArchivedPackage(@NonNull String packageName, int userId) {
+ return getArchivedPackageInternal(packageName, userId);
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 1679987211a8..38f241d40d98 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -547,6 +547,9 @@ public class PackageManagerServiceUtils {
/** Returns true if standard APK Verity is enabled. */
static boolean isApkVerityEnabled() {
+ if (android.security.Flags.deprecateFsvSig()) {
+ return false;
+ }
return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R
|| SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED)
== FSVERITY_ENABLED;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 8d8208599998..1b30c4b82d82 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -26,6 +26,7 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS;
import static android.content.pm.PackageManager.RESTRICTION_HIDE_NOTIFICATIONS;
import static android.content.pm.PackageManager.RESTRICTION_NONE;
+
import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
@@ -82,9 +83,9 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
import android.os.IBinder;
import android.os.IUserManager;
+import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.os.PersistableBundle;
@@ -130,6 +131,7 @@ import dalvik.system.DexFile;
import libcore.io.IoUtils;
import libcore.io.Streams;
+import libcore.util.HexEncoding;
import java.io.BufferedReader;
import java.io.File;
@@ -248,8 +250,6 @@ class PackageManagerShellCommand extends ShellCommand {
return runStreamingInstall();
case "install-incremental":
return runIncrementalInstall();
- case "install-archived":
- return runArchivedInstall();
case "install-abandon":
case "install-destroy":
return runInstallAbandon();
@@ -277,6 +277,10 @@ class PackageManagerShellCommand extends ShellCommand {
return runUninstall();
case "clear":
return runClear();
+ case "get-archived-package-metadata":
+ return runGetArchivedPackageMetadata();
+ case "install-archived":
+ return runArchivedInstall();
case "enable":
return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
case "disable":
@@ -1808,6 +1812,56 @@ class PackageManagerShellCommand extends ShellCommand {
return doRemoveSplits(sessionId, splitNames, true /*logSuccess*/);
}
+ private int runGetArchivedPackageMetadata() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ int userId = UserHandle.USER_CURRENT;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "--user":
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ break;
+ default:
+ pw.println("Error: Unknown option: " + opt);
+ return 1;
+ }
+ }
+
+ final String packageName = getNextArg();
+ if (packageName == null) {
+ pw.println("Error: package name not specified");
+ return 1;
+ }
+ final int translatedUserId = translateUserId(userId, UserHandle.USER_NULL,
+ "runGetArchivedPackageMetadata");
+
+ try {
+ var archivedPackage = mInterface.getArchivedPackage(packageName, translatedUserId);
+ if (archivedPackage == null) {
+ pw.write("Package not found " + packageName);
+ return -1;
+ }
+
+ Parcel parcel = Parcel.obtain();
+ byte[] bytes;
+ try {
+ parcel.writeParcelable(archivedPackage, 0);
+ bytes = parcel.marshall();
+ } finally {
+ parcel.recycle();
+ }
+
+ String encoded = HexEncoding.encodeToString(bytes);
+ pw.write(encoded);
+ } catch (Exception e) {
+ getErrPrintWriter().println("Failed to get archived package, reason: " + e);
+ pw.println("Failure [failed to get archived package], reason: " + e);
+ return -1;
+ }
+ return 0;
+ }
+
private int runInstallExisting() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
int userId = UserHandle.USER_CURRENT;
@@ -4146,28 +4200,24 @@ class PackageManagerShellCommand extends ShellCommand {
throw new IllegalArgumentException("Error: Can't open file: " + inPath);
}
- File tmpFile = null;
+ final String encoded;
final ParcelFileDescriptor fd = fdWithSize.first;
+ final int size = (int) (long) fdWithSize.second;
try (InputStream inStream = new AutoCloseInputStream(fd)) {
- final long identity = Binder.clearCallingIdentity();
- try {
- File tmpStagingDir = Environment.getDataAppDirectory(null);
- tmpFile = new File(tmpStagingDir, "tmdl" + RANDOM.nextInt() + ".tmp");
-
- try (OutputStream outStream = new FileOutputStream(tmpFile)) {
- Streams.copy(inStream, outStream);
- }
-
- return mInterface.getArchivedPackage(tmpFile.getAbsolutePath());
- } finally {
- if (tmpFile != null) {
- tmpFile.delete();
- }
- Binder.restoreCallingIdentity(identity);
- }
+ byte[] bytes = new byte[size];
+ Streams.readFully(inStream, bytes);
+ encoded = new String(bytes);
} catch (IOException e) {
- throw new IllegalArgumentException("Error: Can't stage file: " + inPath, e);
+ throw new IllegalArgumentException("Error: Can't load archived package from: " + inPath,
+ e);
}
+
+ var result = Metadata.readArchivedPackageParcel(HexEncoding.decode(encoded));
+ if (result == null) {
+ throw new IllegalArgumentException(
+ "Error: Can't parse archived package from: " + inPath);
+ }
+ return result;
}
private void processArgForLocalFile(String arg, PackageInstaller.Session session,
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
index fbe5a51587fc..9e7f04351327 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
@@ -166,16 +166,7 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService {
/** @hide */
@VisibleForTesting
public static Metadata forArchived(ArchivedPackageParcel archivedPackage) {
- Parcel parcel = Parcel.obtain();
- byte[] bytes;
- try {
- parcel.writeParcelable(archivedPackage, 0);
- bytes = parcel.marshall();
- } finally {
- parcel.recycle();
- }
-
- return new Metadata(ARCHIVED, bytes, null);
+ return new Metadata(ARCHIVED, writeArchivedPackageParcel(archivedPackage), null);
}
static Metadata forDataOnlyStreaming(String fileId) {
@@ -270,11 +261,14 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService {
if (getMode() != ARCHIVED) {
throw new IllegalStateException("Not an archived package metadata.");
}
+ return readArchivedPackageParcel(this.mData);
+ }
+ static ArchivedPackageParcel readArchivedPackageParcel(byte[] bytes) {
Parcel parcel = Parcel.obtain();
ArchivedPackageParcel result;
try {
- parcel.unmarshall(this.mData, 0, this.mData.length);
+ parcel.unmarshall(bytes, 0, bytes.length);
parcel.setDataPosition(0);
result = parcel.readParcelable(ArchivedPackageParcel.class.getClassLoader());
} finally {
@@ -282,6 +276,16 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService {
}
return result;
}
+
+ static byte[] writeArchivedPackageParcel(ArchivedPackageParcel archivedPackage) {
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeParcelable(archivedPackage, 0);
+ return parcel.marshall();
+ } finally {
+ parcel.recycle();
+ }
+ }
}
private static class DataLoader implements DataLoaderService.DataLoader {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 114f80d7998f..2e6006465bd9 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -654,6 +654,16 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return (getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0;
}
+ public boolean isRequestLegacyExternalStorage() {
+ return (getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
+ != 0;
+ }
+
+ public boolean isUserDataFragile() {
+ return (getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
+ != 0;
+ }
+
public SigningDetails getSigningDetails() {
return signatures.mSigningDetails;
}
@@ -844,15 +854,42 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return res;
}
+ int[] queryUsersInstalledOrHasData(int[] users) {
+ int num = 0;
+ for (int user : users) {
+ if (getInstalled(user) || readUserState(user).dataExists()) {
+ num++;
+ }
+ }
+ int[] res = new int[num];
+ num = 0;
+ for (int user : users) {
+ if (getInstalled(user) || readUserState(user).dataExists()) {
+ res[num] = user;
+ num++;
+ }
+ }
+ return res;
+ }
+
long getCeDataInode(int userId) {
return readUserState(userId).getCeDataInode();
}
+ long getDeDataInode(int userId) {
+ return readUserState(userId).getDeDataInode();
+ }
+
void setCeDataInode(long ceDataInode, int userId) {
modifyUserState(userId).setCeDataInode(ceDataInode);
onChanged();
}
+ void setDeDataInode(long deDataInode, int userId) {
+ modifyUserState(userId).setDeDataInode(deDataInode);
+ onChanged();
+ }
+
boolean getStopped(int userId) {
return readUserState(userId).isStopped();
}
@@ -907,17 +944,18 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
onChanged();
}
- void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
- boolean notLaunched, boolean hidden, int distractionFlags,
- ArrayMap<String, SuspendParams> suspendParams, boolean instantApp,
- boolean virtualPreload, String lastDisableAppCaller,
- ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
- int installReason, int uninstallReason,
- String harmfulAppWarning, String splashScreenTheme,
- long firstInstallTime, int aspectRatio, ArchiveState archiveState) {
+ void setUserState(int userId, long ceDataInode, long deDataInode, int enabled,
+ boolean installed, boolean stopped, boolean notLaunched, boolean hidden,
+ int distractionFlags, ArrayMap<String, SuspendParams> suspendParams,
+ boolean instantApp, boolean virtualPreload, String lastDisableAppCaller,
+ ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
+ int installReason, int uninstallReason,
+ String harmfulAppWarning, String splashScreenTheme,
+ long firstInstallTime, int aspectRatio, ArchiveState archiveState) {
modifyUserState(userId)
.setSuspendParams(suspendParams)
.setCeDataInode(ceDataInode)
+ .setDeDataInode(deDataInode)
.setEnabledState(enabled)
.setInstalled(installed)
.setStopped(stopped)
@@ -940,9 +978,9 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
}
void setUserState(int userId, PackageUserStateInternal otherState) {
- setUserState(userId, otherState.getCeDataInode(), otherState.getEnabledState(),
- otherState.isInstalled(), otherState.isStopped(), otherState.isNotLaunched(),
- otherState.isHidden(), otherState.getDistractionFlags(),
+ setUserState(userId, otherState.getCeDataInode(), otherState.getDeDataInode(),
+ otherState.getEnabledState(), otherState.isInstalled(), otherState.isStopped(),
+ otherState.isNotLaunched(), otherState.isHidden(), otherState.getDistractionFlags(),
otherState.getSuspendParams() == null
? null : otherState.getSuspendParams().untrackedStorage(),
otherState.isInstantApp(), otherState.isVirtualPreload(),
@@ -1677,10 +1715,10 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
}
@DataClass.Generated(
- time = 1691185420362L,
+ time = 1694196905013L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/PackageSetting.java",
- inputSignatures = "private int mBooleans\nprivate int mSharedUserAppId\nprivate @android.annotation.Nullable java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mimeGroups\nprivate @java.lang.Deprecated @android.annotation.Nullable java.util.Set<java.lang.String> mOldCodePaths\nprivate @android.annotation.Nullable java.lang.String[] usesSdkLibraries\nprivate @android.annotation.Nullable long[] usesSdkLibrariesVersionsMajor\nprivate @android.annotation.Nullable java.lang.String[] usesStaticLibraries\nprivate @android.annotation.Nullable long[] usesStaticLibrariesVersions\nprivate @android.annotation.Nullable @java.lang.Deprecated java.lang.String legacyNativeLibraryPath\nprivate @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.Nullable java.lang.String mRealName\nprivate int mAppId\nprivate @android.annotation.Nullable com.android.server.pm.parsing.pkg.AndroidPackageInternal pkg\nprivate @android.annotation.NonNull java.io.File mPath\nprivate @android.annotation.NonNull java.lang.String mPathString\nprivate float mLoadingProgress\nprivate long mLoadingCompletedTime\nprivate @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate long mLastModifiedTime\nprivate long lastUpdateTime\nprivate long versionCode\nprivate @android.annotation.NonNull com.android.server.pm.PackageSignatures signatures\nprivate @android.annotation.NonNull com.android.server.pm.PackageKeySetData keySetData\nprivate final @android.annotation.NonNull android.util.SparseArray<com.android.server.pm.pkg.PackageUserStateImpl> mUserStates\nprivate @android.annotation.NonNull com.android.server.pm.InstallSource installSource\nprivate @android.annotation.Nullable java.lang.String volumeUuid\nprivate int categoryOverride\nprivate final @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized pkgState\nprivate @android.annotation.NonNull java.util.UUID mDomainSetId\nprivate @android.annotation.Nullable java.lang.String mAppMetadataFilePath\nprivate final @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> mSnapshot\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> makeCache()\npublic com.android.server.pm.PackageSetting snapshot()\npublic void dumpDebug(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\npublic com.android.server.pm.PackageSetting setAppId(int)\npublic com.android.server.pm.PackageSetting setCpuAbiOverride(java.lang.String)\npublic com.android.server.pm.PackageSetting setFirstInstallTimeFromReplaced(com.android.server.pm.pkg.PackageStateInternal,int[])\npublic com.android.server.pm.PackageSetting setFirstInstallTime(long,int)\npublic com.android.server.pm.PackageSetting setForceQueryableOverride(boolean)\npublic com.android.server.pm.PackageSetting setInstallerPackage(java.lang.String,int)\npublic com.android.server.pm.PackageSetting setUpdateOwnerPackage(java.lang.String)\npublic com.android.server.pm.PackageSetting setInstallSource(com.android.server.pm.InstallSource)\n com.android.server.pm.PackageSetting removeInstallerPackage(java.lang.String)\npublic com.android.server.pm.PackageSetting setIsOrphaned(boolean)\npublic com.android.server.pm.PackageSetting setKeySetData(com.android.server.pm.PackageKeySetData)\npublic com.android.server.pm.PackageSetting setLastModifiedTime(long)\npublic com.android.server.pm.PackageSetting setLastUpdateTime(long)\npublic com.android.server.pm.PackageSetting setLongVersionCode(long)\npublic boolean setMimeGroup(java.lang.String,android.util.ArraySet<java.lang.String>)\npublic com.android.server.pm.PackageSetting setPkg(com.android.server.pm.pkg.AndroidPackage)\npublic com.android.server.pm.PackageSetting setPkgStateLibraryFiles(java.util.Collection<java.lang.String>)\npublic com.android.server.pm.PackageSetting setPrimaryCpuAbi(java.lang.String)\npublic com.android.server.pm.PackageSetting setSecondaryCpuAbi(java.lang.String)\npublic com.android.server.pm.PackageSetting setSignatures(com.android.server.pm.PackageSignatures)\npublic com.android.server.pm.PackageSetting setVolumeUuid(java.lang.String)\npublic com.android.server.pm.PackageSetting setDefaultToDeviceProtectedStorage(boolean)\npublic @java.lang.Override boolean isExternalStorage()\npublic com.android.server.pm.PackageSetting setUpdateAvailable(boolean)\npublic void setSharedUserAppId(int)\npublic @java.lang.Override int getSharedUserAppId()\npublic @java.lang.Override boolean hasSharedUser()\npublic @java.lang.Override java.lang.String toString()\nprotected void copyMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic void updateFrom(com.android.server.pm.PackageSetting)\n com.android.server.pm.PackageSetting updateMimeGroups(java.util.Set<java.lang.String>)\npublic @java.lang.Deprecated @java.lang.Override com.android.server.pm.permission.LegacyPermissionState getLegacyPermissionState()\npublic com.android.server.pm.PackageSetting setInstallPermissionsFixed(boolean)\npublic boolean isPrivileged()\npublic boolean isOem()\npublic boolean isVendor()\npublic boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic boolean isSystemExt()\npublic boolean isOdm()\npublic boolean isSystem()\npublic android.content.pm.SigningDetails getSigningDetails()\npublic com.android.server.pm.PackageSetting setSigningDetails(android.content.pm.SigningDetails)\npublic void copyPackageSetting(com.android.server.pm.PackageSetting,boolean)\n @com.android.internal.annotations.VisibleForTesting com.android.server.pm.pkg.PackageUserStateImpl modifyUserState(int)\npublic com.android.server.pm.pkg.PackageUserStateImpl getOrCreateUserState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateInternal readUserState(int)\n void setEnabled(int,int,java.lang.String)\n int getEnabled(int)\n void setInstalled(boolean,int)\n boolean getInstalled(int)\n int getInstallReason(int)\n void setInstallReason(int,int)\n int getUninstallReason(int)\n void setUninstallReason(int,int)\n @android.annotation.NonNull android.content.pm.overlay.OverlayPaths getOverlayPaths(int)\n boolean setOverlayPathsForLibrary(java.lang.String,android.content.pm.overlay.OverlayPaths,int)\n boolean isAnyInstalled(int[])\n int[] queryInstalledUsers(int[],boolean)\n long getCeDataInode(int)\n void setCeDataInode(long,int)\n boolean getStopped(int)\n void setStopped(boolean,int)\n boolean getNotLaunched(int)\n void setNotLaunched(boolean,int)\n boolean getHidden(int)\n void setHidden(boolean,int)\n int getDistractionFlags(int)\n void setDistractionFlags(int,int)\npublic boolean getInstantApp(int)\n void setInstantApp(boolean,int)\n boolean getVirtualPreload(int)\n void setVirtualPreload(boolean,int)\n void setUserState(int,long,int,boolean,boolean,boolean,boolean,int,android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>,boolean,boolean,java.lang.String,android.util.ArraySet<java.lang.String>,android.util.ArraySet<java.lang.String>,int,int,java.lang.String,java.lang.String,long,int,com.android.server.pm.pkg.ArchiveState)\n void setUserState(int,com.android.server.pm.pkg.PackageUserStateInternal)\n com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponents(int)\n com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponents(int)\n void setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n void setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n void setEnabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n void setDisabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n com.android.server.pm.pkg.PackageUserStateImpl modifyUserStateComponents(int,boolean,boolean)\n void addDisabledComponent(java.lang.String,int)\n void addEnabledComponent(java.lang.String,int)\n boolean enableComponentLPw(java.lang.String,int)\n boolean disableComponentLPw(java.lang.String,int)\n boolean restoreComponentLPw(java.lang.String,int)\n int getCurrentEnabledStateLPr(java.lang.String,int)\n void removeUser(int)\npublic int[] getNotInstalledUserIds()\n void writePackageUserPermissionsProto(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\nprotected void writeUsersInfoToProto(android.util.proto.ProtoOutputStream,long)\nprivate static void writeArchiveState(android.util.proto.ProtoOutputStream,com.android.server.pm.pkg.ArchiveState)\n com.android.server.pm.PackageSetting setPath(java.io.File)\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideNonLocalizedLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer,int)\npublic void resetOverrideComponentLabelIcon(int)\npublic @android.annotation.Nullable java.lang.String getSplashScreenTheme(int)\npublic boolean isIncremental()\npublic boolean isLoading()\npublic com.android.server.pm.PackageSetting setLoadingProgress(float)\npublic com.android.server.pm.PackageSetting setLoadingCompletedTime(long)\npublic com.android.server.pm.PackageSetting setAppMetadataFilePath(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override long getVersionCode()\npublic @android.annotation.Nullable @java.lang.Override java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getMimeGroups()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String getPackageName()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.pm.pkg.AndroidPackage getAndroidPackage()\npublic @android.annotation.NonNull android.content.pm.SigningInfo getSigningInfo()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesSdkLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesSdkLibrariesVersionsMajor()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesStaticLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesStaticLibrariesVersions()\npublic @android.annotation.NonNull @java.lang.Override java.util.List<com.android.server.pm.pkg.SharedLibrary> getSharedLibraryDependencies()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryInfo(android.content.pm.SharedLibraryInfo)\npublic @android.annotation.NonNull @java.lang.Override java.util.List<java.lang.String> getUsesLibraryFiles()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryFile(java.lang.String)\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @android.annotation.NonNull @java.lang.Override long[] getLastPackageUsageTime()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isApkInUpdatedApex()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getApexModuleName()\npublic com.android.server.pm.PackageSetting setDomainSetId(java.util.UUID)\npublic com.android.server.pm.PackageSetting setCategoryOverride(int)\npublic com.android.server.pm.PackageSetting setLegacyNativeLibraryPath(java.lang.String)\npublic com.android.server.pm.PackageSetting setMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic com.android.server.pm.PackageSetting setOldCodePaths(java.util.Set<java.lang.String>)\npublic com.android.server.pm.PackageSetting setUsesSdkLibraries(java.lang.String[])\npublic com.android.server.pm.PackageSetting setUsesSdkLibrariesVersionsMajor(long[])\npublic com.android.server.pm.PackageSetting setUsesStaticLibraries(java.lang.String[])\npublic com.android.server.pm.PackageSetting setUsesStaticLibrariesVersions(long[])\npublic com.android.server.pm.PackageSetting setApexModuleName(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageStateUnserialized getTransientState()\npublic @android.annotation.NonNull android.util.SparseArray<? extends PackageUserStateInternal> getUserStates()\npublic com.android.server.pm.PackageSetting addMimeTypes(java.lang.String,java.util.Set<java.lang.String>)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserState getStateForUser(android.os.UserHandle)\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbi()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbi()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getSeInfo()\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbiLegacy()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbiLegacy()\npublic @android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy @java.lang.Override int getHiddenApiEnforcementPolicy()\npublic @java.lang.Override boolean isApex()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isDefaultToDeviceProtectedStorage()\nclass PackageSetting extends com.android.server.pm.SettingBase implements [com.android.server.pm.pkg.PackageStateInternal]\nprivate static final int INSTALL_PERMISSION_FIXED\nprivate static final int DEFAULT_TO_DEVICE_PROTECTED_STORAGE\nprivate static final int UPDATE_AVAILABLE\nprivate static final int FORCE_QUERYABLE_OVERRIDE\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genGetters=true, genConstructor=false, genSetters=false, genBuilder=false)")
+ inputSignatures = "private int mBooleans\nprivate int mSharedUserAppId\nprivate @android.annotation.Nullable java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mimeGroups\nprivate @java.lang.Deprecated @android.annotation.Nullable java.util.Set<java.lang.String> mOldCodePaths\nprivate @android.annotation.Nullable java.lang.String[] usesSdkLibraries\nprivate @android.annotation.Nullable long[] usesSdkLibrariesVersionsMajor\nprivate @android.annotation.Nullable java.lang.String[] usesStaticLibraries\nprivate @android.annotation.Nullable long[] usesStaticLibrariesVersions\nprivate @android.annotation.Nullable @java.lang.Deprecated java.lang.String legacyNativeLibraryPath\nprivate @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.Nullable java.lang.String mRealName\nprivate int mAppId\nprivate @android.annotation.Nullable com.android.server.pm.parsing.pkg.AndroidPackageInternal pkg\nprivate @android.annotation.NonNull java.io.File mPath\nprivate @android.annotation.NonNull java.lang.String mPathString\nprivate float mLoadingProgress\nprivate long mLoadingCompletedTime\nprivate @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate long mLastModifiedTime\nprivate long lastUpdateTime\nprivate long versionCode\nprivate @android.annotation.NonNull com.android.server.pm.PackageSignatures signatures\nprivate @android.annotation.NonNull com.android.server.pm.PackageKeySetData keySetData\nprivate final @android.annotation.NonNull android.util.SparseArray<com.android.server.pm.pkg.PackageUserStateImpl> mUserStates\nprivate @android.annotation.NonNull com.android.server.pm.InstallSource installSource\nprivate @android.annotation.Nullable java.lang.String volumeUuid\nprivate int categoryOverride\nprivate final @android.annotation.NonNull com.android.server.pm.pkg.PackageStateUnserialized pkgState\nprivate @android.annotation.NonNull java.util.UUID mDomainSetId\nprivate @android.annotation.Nullable java.lang.String mAppMetadataFilePath\nprivate final @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> mSnapshot\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.PackageSetting> makeCache()\npublic com.android.server.pm.PackageSetting snapshot()\npublic void dumpDebug(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\npublic com.android.server.pm.PackageSetting setAppId(int)\npublic com.android.server.pm.PackageSetting setCpuAbiOverride(java.lang.String)\npublic com.android.server.pm.PackageSetting setFirstInstallTimeFromReplaced(com.android.server.pm.pkg.PackageStateInternal,int[])\npublic com.android.server.pm.PackageSetting setFirstInstallTime(long,int)\npublic com.android.server.pm.PackageSetting setForceQueryableOverride(boolean)\npublic com.android.server.pm.PackageSetting setInstallerPackage(java.lang.String,int)\npublic com.android.server.pm.PackageSetting setUpdateOwnerPackage(java.lang.String)\npublic com.android.server.pm.PackageSetting setInstallSource(com.android.server.pm.InstallSource)\n com.android.server.pm.PackageSetting removeInstallerPackage(java.lang.String)\npublic com.android.server.pm.PackageSetting setIsOrphaned(boolean)\npublic com.android.server.pm.PackageSetting setKeySetData(com.android.server.pm.PackageKeySetData)\npublic com.android.server.pm.PackageSetting setLastModifiedTime(long)\npublic com.android.server.pm.PackageSetting setLastUpdateTime(long)\npublic com.android.server.pm.PackageSetting setLongVersionCode(long)\npublic boolean setMimeGroup(java.lang.String,android.util.ArraySet<java.lang.String>)\npublic com.android.server.pm.PackageSetting setPkg(com.android.server.pm.pkg.AndroidPackage)\npublic com.android.server.pm.PackageSetting setPkgStateLibraryFiles(java.util.Collection<java.lang.String>)\npublic com.android.server.pm.PackageSetting setPrimaryCpuAbi(java.lang.String)\npublic com.android.server.pm.PackageSetting setSecondaryCpuAbi(java.lang.String)\npublic com.android.server.pm.PackageSetting setSignatures(com.android.server.pm.PackageSignatures)\npublic com.android.server.pm.PackageSetting setVolumeUuid(java.lang.String)\npublic com.android.server.pm.PackageSetting setDefaultToDeviceProtectedStorage(boolean)\npublic @java.lang.Override boolean isExternalStorage()\npublic com.android.server.pm.PackageSetting setUpdateAvailable(boolean)\npublic void setSharedUserAppId(int)\npublic @java.lang.Override int getSharedUserAppId()\npublic @java.lang.Override boolean hasSharedUser()\npublic @java.lang.Override java.lang.String toString()\nprotected void copyMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic void updateFrom(com.android.server.pm.PackageSetting)\n com.android.server.pm.PackageSetting updateMimeGroups(java.util.Set<java.lang.String>)\npublic @java.lang.Deprecated @java.lang.Override com.android.server.pm.permission.LegacyPermissionState getLegacyPermissionState()\npublic com.android.server.pm.PackageSetting setInstallPermissionsFixed(boolean)\npublic boolean isPrivileged()\npublic boolean isOem()\npublic boolean isVendor()\npublic boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic boolean isSystemExt()\npublic boolean isOdm()\npublic boolean isSystem()\npublic android.content.pm.SigningDetails getSigningDetails()\npublic com.android.server.pm.PackageSetting setSigningDetails(android.content.pm.SigningDetails)\npublic void copyPackageSetting(com.android.server.pm.PackageSetting,boolean)\n @com.android.internal.annotations.VisibleForTesting com.android.server.pm.pkg.PackageUserStateImpl modifyUserState(int)\npublic com.android.server.pm.pkg.PackageUserStateImpl getOrCreateUserState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateInternal readUserState(int)\n void setEnabled(int,int,java.lang.String)\n int getEnabled(int)\n void setInstalled(boolean,int)\n boolean getInstalled(int)\n int getInstallReason(int)\n void setInstallReason(int,int)\n int getUninstallReason(int)\n void setUninstallReason(int,int)\n @android.annotation.NonNull android.content.pm.overlay.OverlayPaths getOverlayPaths(int)\n boolean setOverlayPathsForLibrary(java.lang.String,android.content.pm.overlay.OverlayPaths,int)\n boolean isInstalledOrHasDataOnAnyOtherUser(int[],int)\n int[] queryInstalledUsers(int[],boolean)\n long getCeDataInode(int)\n void setCeDataInode(long,int)\n void setDeDataInode(long,int)\n boolean getStopped(int)\n void setStopped(boolean,int)\n boolean getNotLaunched(int)\n void setNotLaunched(boolean,int)\n boolean getHidden(int)\n void setHidden(boolean,int)\n int getDistractionFlags(int)\n void setDistractionFlags(int,int)\npublic boolean getInstantApp(int)\n void setInstantApp(boolean,int)\n boolean getVirtualPreload(int)\n void setVirtualPreload(boolean,int)\n void setUserState(int,long,int,boolean,boolean,boolean,boolean,int,android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>,boolean,boolean,java.lang.String,android.util.ArraySet<java.lang.String>,android.util.ArraySet<java.lang.String>,int,int,java.lang.String,java.lang.String,long,int,com.android.server.pm.pkg.ArchiveState)\n void setUserState(int,com.android.server.pm.pkg.PackageUserStateInternal)\n com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponents(int)\n com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponents(int)\n void setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n void setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n void setEnabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n void setDisabledComponentsCopy(com.android.server.utils.WatchedArraySet<java.lang.String>,int)\n com.android.server.pm.pkg.PackageUserStateImpl modifyUserStateComponents(int,boolean,boolean)\n void addDisabledComponent(java.lang.String,int)\n void addEnabledComponent(java.lang.String,int)\n boolean enableComponentLPw(java.lang.String,int)\n boolean disableComponentLPw(java.lang.String,int)\n boolean restoreComponentLPw(java.lang.String,int)\n int getCurrentEnabledStateLPr(java.lang.String,int)\n void removeUser(int)\npublic int[] getNotInstalledUserIds()\n void writePackageUserPermissionsProto(android.util.proto.ProtoOutputStream,long,java.util.List<android.content.pm.UserInfo>,com.android.server.pm.permission.LegacyPermissionDataProvider)\nprotected void writeUsersInfoToProto(android.util.proto.ProtoOutputStream,long)\nprivate static void writeArchiveState(android.util.proto.ProtoOutputStream,com.android.server.pm.pkg.ArchiveState)\n com.android.server.pm.PackageSetting setPath(java.io.File)\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideNonLocalizedLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer,int)\npublic void resetOverrideComponentLabelIcon(int)\npublic @android.annotation.Nullable java.lang.String getSplashScreenTheme(int)\npublic boolean isIncremental()\npublic boolean isLoading()\npublic com.android.server.pm.PackageSetting setLoadingProgress(float)\npublic com.android.server.pm.PackageSetting setLoadingCompletedTime(long)\npublic com.android.server.pm.PackageSetting setAppMetadataFilePath(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override long getVersionCode()\npublic @android.annotation.Nullable @java.lang.Override java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getMimeGroups()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String getPackageName()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.pm.pkg.AndroidPackage getAndroidPackage()\npublic @android.annotation.NonNull android.content.pm.SigningInfo getSigningInfo()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesSdkLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesSdkLibrariesVersionsMajor()\npublic @android.annotation.NonNull @java.lang.Override java.lang.String[] getUsesStaticLibraries()\npublic @android.annotation.NonNull @java.lang.Override long[] getUsesStaticLibrariesVersions()\npublic @android.annotation.NonNull @java.lang.Override java.util.List<com.android.server.pm.pkg.SharedLibrary> getSharedLibraryDependencies()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryInfo(android.content.pm.SharedLibraryInfo)\npublic @android.annotation.NonNull @java.lang.Override java.util.List<java.lang.String> getUsesLibraryFiles()\npublic @android.annotation.NonNull com.android.server.pm.PackageSetting addUsesLibraryFile(java.lang.String)\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @android.annotation.NonNull @java.lang.Override long[] getLastPackageUsageTime()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isApkInUpdatedApex()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getApexModuleName()\npublic com.android.server.pm.PackageSetting setDomainSetId(java.util.UUID)\npublic com.android.server.pm.PackageSetting setCategoryOverride(int)\npublic com.android.server.pm.PackageSetting setLegacyNativeLibraryPath(java.lang.String)\npublic com.android.server.pm.PackageSetting setMimeGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)\npublic com.android.server.pm.PackageSetting setOldCodePaths(java.util.Set<java.lang.String>)\npublic com.android.server.pm.PackageSetting setUsesSdkLibraries(java.lang.String[])\npublic com.android.server.pm.PackageSetting setUsesSdkLibrariesVersionsMajor(long[])\npublic com.android.server.pm.PackageSetting setUsesStaticLibraries(java.lang.String[])\npublic com.android.server.pm.PackageSetting setUsesStaticLibrariesVersions(long[])\npublic com.android.server.pm.PackageSetting setApexModuleName(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageStateUnserialized getTransientState()\npublic @android.annotation.NonNull android.util.SparseArray<? extends PackageUserStateInternal> getUserStates()\npublic com.android.server.pm.PackageSetting addMimeTypes(java.lang.String,java.util.Set<java.lang.String>)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserState getStateForUser(android.os.UserHandle)\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbi()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbi()\npublic @android.annotation.Nullable @java.lang.Override java.lang.String getSeInfo()\npublic @android.annotation.Nullable java.lang.String getPrimaryCpuAbiLegacy()\npublic @android.annotation.Nullable java.lang.String getSecondaryCpuAbiLegacy()\npublic @android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy @java.lang.Override int getHiddenApiEnforcementPolicy()\npublic @java.lang.Override boolean isApex()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isDefaultToDeviceProtectedStorage()\nclass PackageSetting extends com.android.server.pm.SettingBase implements [com.android.server.pm.pkg.PackageStateInternal]\nprivate static final int INSTALL_PERMISSION_FIXED\nprivate static final int DEFAULT_TO_DEVICE_PROTECTED_STORAGE\nprivate static final int UPDATE_AVAILABLE\nprivate static final int FORCE_QUERYABLE_OVERRIDE\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genGetters=true, genConstructor=false, genSetters=false, genBuilder=false)")
@Deprecated
private void __metadata() {}
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 8dec425f074d..d989c90a0597 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -277,6 +277,7 @@ final class RemovePackageHelper {
mAppDataHelper.destroyAppDataLIF(pkg, nextUserId,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
ps.setCeDataInode(-1, nextUserId);
+ ps.setDeDataInode(-1, nextUserId);
}
mAppDataHelper.clearKeystoreData(nextUserId, ps.getAppId());
preferredActivityHelper.clearPackagePreferredActivities(ps.getPackageName(),
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 111a32d03b4c..c263978edd11 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -327,6 +327,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
private static final String ATTR_VERSION = "version";
private static final String ATTR_CE_DATA_INODE = "ceDataInode";
+ private static final String ATTR_DE_DATA_INODE = "deDataInode";
private static final String ATTR_INSTALLED = "inst";
private static final String ATTR_STOPPED = "stopped";
private static final String ATTR_NOT_LAUNCHED = "nl";
@@ -1121,7 +1122,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
+ "installed=%b)",
pkgName, installUserId, user.toFullString(), installed);
}
- pkgSetting.setUserState(user.id, 0, COMPONENT_ENABLED_STATE_DEFAULT,
+ pkgSetting.setUserState(user.id, 0, 0, COMPONENT_ENABLED_STATE_DEFAULT,
installed,
true /*stopped*/,
true /*notLaunched*/,
@@ -1798,7 +1799,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
// in the stopped state, but not at first boot. Also
// consider all applications to be installed.
for (PackageSetting pkg : mPackages.values()) {
- pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
+ pkg.setUserState(userId, pkg.getCeDataInode(userId),
+ pkg.getDeDataInode(userId), COMPONENT_ENABLED_STATE_DEFAULT,
true /*installed*/,
false /*stopped*/,
false /*notLaunched*/,
@@ -1861,6 +1863,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
final long ceDataInode =
parser.getAttributeLong(null, ATTR_CE_DATA_INODE, 0);
+ final long deDataInode =
+ parser.getAttributeLong(null, ATTR_DE_DATA_INODE, 0);
final boolean installed =
parser.getAttributeBoolean(null, ATTR_INSTALLED, true);
final boolean stopped =
@@ -1989,7 +1993,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
if (blockUninstall) {
setBlockUninstallLPw(userId, name, true);
}
- ps.setUserState(userId, ceDataInode, enabled, installed, stopped,
+ ps.setUserState(
+ userId, ceDataInode, deDataInode, enabled, installed, stopped,
notLaunched, hidden, distractionFlags, suspendParamsMap, instantApp,
virtualPreload, enabledCaller, enabledComponents,
disabledComponents, installReason, uninstallReason,
@@ -2306,6 +2311,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
serializer.attributeLong(null, ATTR_CE_DATA_INODE,
ustate.getCeDataInode());
}
+ if (ustate.getDeDataInode() != 0) {
+ serializer.attributeLong(null, ATTR_DE_DATA_INODE,
+ ustate.getDeDataInode());
+ }
if (!ustate.isInstalled()) {
serializer.attributeBoolean(null, ATTR_INSTALLED, false);
}
@@ -5172,6 +5181,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
pw.print(prefix); pw.print(" User "); pw.print(user.id); pw.print(": ");
pw.print("ceDataInode=");
pw.print(userState.getCeDataInode());
+ pw.print(" deDataInode=");
+ pw.print(userState.getDeDataInode());
pw.print(" installed=");
pw.print(userState.isInstalled());
pw.print(" hidden=");
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 4eceb7738836..cc8e62409597 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -378,7 +378,6 @@ public class PackageInfoUtils {
ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT)
| flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
| flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN);
-
if ((flags & PackageManager.FILTER_OUT_QUARANTINED_COMPONENTS) != 0
&& state.isQuarantined()) {
ai.enabled = false;
@@ -402,6 +401,14 @@ public class PackageInfoUtils {
ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
}
+ ai.isArchived = isArchived(state);
+ }
+
+ // TODO(b/288142708) Check for userState.isInstalled() here once this bug is fixed.
+ // If an app has isInstalled() == true - it should not be filtered above in any case, currently
+ // it is.
+ private static boolean isArchived(PackageUserState userState) {
+ return userState.getArchiveState() != null;
}
@Nullable
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserState.java b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
index c05b3c2be622..2a81a86d20f6 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
@@ -86,6 +86,13 @@ public interface PackageUserState {
long getCeDataInode();
/**
+ * Device encrypted /data partition inode.
+ *
+ * @hide
+ */
+ long getDeDataInode();
+
+ /**
* Fully qualified class names of components explicitly disabled.
*
* @hide
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java
index fc4b6863b9b8..2f4ad2d8fcc6 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java
@@ -77,6 +77,11 @@ class PackageUserStateDefault implements PackageUserStateInternal {
}
@Override
+ public long getDeDataInode() {
+ return 0;
+ }
+
+ @Override
public int getDistractionFlags() {
return 0;
}
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
index 0b35d8ae16ea..12795c6b6814 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
@@ -91,6 +91,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
protected WatchedArraySet<String> mEnabledComponentsWatched;
private long mCeDataInode;
+ private long mDeDataInode;
private int mDistractionFlags;
@PackageManager.EnabledState
private int mEnabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -172,6 +173,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
mSharedLibraryOverlayPaths = other.mSharedLibraryOverlayPaths == null
? null : other.mSharedLibraryOverlayPaths.snapshot();
mCeDataInode = other.mCeDataInode;
+ mDeDataInode = other.mDeDataInode;
mDistractionFlags = other.mDistractionFlags;
mEnabledState = other.mEnabledState;
mInstallReason = other.mInstallReason;
@@ -444,6 +446,12 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
return this;
}
+ public @NonNull PackageUserStateImpl setDeDataInode(long value) {
+ mDeDataInode = value;
+ onChanged();
+ return this;
+ }
+
public @NonNull PackageUserStateImpl setInstalled(boolean value) {
setBoolean(Booleans.INSTALLED, value);
onChanged();
@@ -687,7 +695,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
@Override
public boolean dataExists() {
- return getCeDataInode() > 0;
+ return getCeDataInode() > 0 || getDeDataInode() > 0;
}
@@ -721,6 +729,11 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
}
@DataClass.Generated.Member
+ public long getDeDataInode() {
+ return mDeDataInode;
+ }
+
+ @DataClass.Generated.Member
public int getDistractionFlags() {
return mDistractionFlags;
}
@@ -849,6 +862,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
&& Objects.equals(mDisabledComponentsWatched, that.mDisabledComponentsWatched)
&& Objects.equals(mEnabledComponentsWatched, that.mEnabledComponentsWatched)
&& mCeDataInode == that.mCeDataInode
+ && mDeDataInode == that.mDeDataInode
&& mDistractionFlags == that.mDistractionFlags
&& mEnabledState == that.mEnabledState
&& mInstallReason == that.mInstallReason
@@ -878,6 +892,7 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
_hash = 31 * _hash + Objects.hashCode(mDisabledComponentsWatched);
_hash = 31 * _hash + Objects.hashCode(mEnabledComponentsWatched);
_hash = 31 * _hash + Long.hashCode(mCeDataInode);
+ _hash = 31 * _hash + Long.hashCode(mDeDataInode);
_hash = 31 * _hash + mDistractionFlags;
_hash = 31 * _hash + mEnabledState;
_hash = 31 * _hash + mInstallReason;
@@ -898,10 +913,10 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt
}
@DataClass.Generated(
- time = 1691601685901L,
+ time = 1694196888631L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java",
- inputSignatures = "private int mBooleans\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mDisabledComponentsWatched\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mEnabledComponentsWatched\nprivate long mCeDataInode\nprivate int mDistractionFlags\nprivate @android.content.pm.PackageManager.EnabledState int mEnabledState\nprivate @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate @android.annotation.Nullable android.content.pm.overlay.OverlayPaths mOverlayPaths\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate @android.content.pm.PackageManager.UserMinAspectRatio int mMinAspectRatio\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams> mSuspendParams\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>> mComponentLabelIconOverrideMap\nprivate @android.annotation.CurrentTimeMillisLong long mFirstInstallTimeMillis\nprivate @android.annotation.Nullable com.android.server.utils.Watchable mWatchable\nprivate @android.annotation.Nullable com.android.server.pm.pkg.ArchiveState mArchiveState\nfinal @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> mSnapshot\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> makeCache()\nprivate void onChanged()\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserStateImpl snapshot()\npublic @android.annotation.Nullable boolean setOverlayPaths(android.content.pm.overlay.OverlayPaths)\npublic boolean setSharedLibraryOverlayPaths(java.lang.String,android.content.pm.overlay.OverlayPaths)\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponentsNoCopy()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponentsNoCopy()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getDisabledComponents()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getEnabledComponents()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer)\npublic void resetOverrideComponentLabelIcon()\npublic @android.annotation.Nullable android.util.Pair<java.lang.String,java.lang.Integer> getOverrideLabelIconForComponent(android.content.ComponentName)\npublic @java.lang.Override boolean isSuspended()\npublic com.android.server.pm.pkg.PackageUserStateImpl putSuspendParams(java.lang.String,com.android.server.pm.pkg.SuspendParams)\npublic com.android.server.pm.pkg.PackageUserStateImpl removeSuspension(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setCeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstalled(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setStopped(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setNotLaunched(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHidden(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDistractionFlags(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstantApp(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setVirtualPreload(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setUninstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHarmfulAppWarning(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setLastDisableAppCaller(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSharedLibraryOverlayPaths(android.util.ArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSplashScreenTheme(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setMinAspectRatio(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSuspendParams(android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setComponentLabelIconOverrideMap(android.util.ArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setFirstInstallTimeMillis(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setArchiveState(com.android.server.pm.pkg.ArchiveState)\npublic @android.annotation.NonNull @java.lang.Override java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> getSharedLibraryOverlayPaths()\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setWatchable(com.android.server.utils.Watchable)\nprivate boolean watchableEquals(com.android.server.utils.Watchable)\nprivate int watchableHashCode()\nprivate boolean snapshotEquals(com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl>)\nprivate int snapshotHashCode()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isVirtualPreload()\nclass PackageUserStateImpl extends com.android.server.utils.WatchableImpl implements [com.android.server.pm.pkg.PackageUserStateInternal, com.android.server.utils.Snappable]\nprivate static final int INSTALLED\nprivate static final int STOPPED\nprivate static final int NOT_LAUNCHED\nprivate static final int HIDDEN\nprivate static final int INSTANT_APP\nprivate static final int VIRTUAL_PRELOADED\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genEqualsHashCode=true)")
+ inputSignatures = "private int mBooleans\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mDisabledComponentsWatched\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mEnabledComponentsWatched\nprivate long mCeDataInode\nprivate long mDeDataInode\nprivate int mDistractionFlags\nprivate @android.content.pm.PackageManager.EnabledState int mEnabledState\nprivate @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate @android.annotation.Nullable android.content.pm.overlay.OverlayPaths mOverlayPaths\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate @android.content.pm.PackageManager.UserMinAspectRatio int mMinAspectRatio\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams> mSuspendParams\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>> mComponentLabelIconOverrideMap\nprivate @android.annotation.CurrentTimeMillisLong long mFirstInstallTimeMillis\nprivate @android.annotation.Nullable com.android.server.utils.Watchable mWatchable\nprivate @android.annotation.Nullable com.android.server.pm.pkg.ArchiveState mArchiveState\nfinal @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> mSnapshot\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> makeCache()\nprivate void onChanged()\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserStateImpl snapshot()\npublic @android.annotation.Nullable boolean setOverlayPaths(android.content.pm.overlay.OverlayPaths)\npublic boolean setSharedLibraryOverlayPaths(java.lang.String,android.content.pm.overlay.OverlayPaths)\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponentsNoCopy()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponentsNoCopy()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getDisabledComponents()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getEnabledComponents()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer)\npublic void resetOverrideComponentLabelIcon()\npublic @android.annotation.Nullable android.util.Pair<java.lang.String,java.lang.Integer> getOverrideLabelIconForComponent(android.content.ComponentName)\npublic @java.lang.Override boolean isSuspended()\npublic com.android.server.pm.pkg.PackageUserStateImpl putSuspendParams(java.lang.String,com.android.server.pm.pkg.SuspendParams)\npublic com.android.server.pm.pkg.PackageUserStateImpl removeSuspension(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setCeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstalled(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setStopped(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setNotLaunched(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHidden(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDistractionFlags(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstantApp(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setVirtualPreload(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setUninstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHarmfulAppWarning(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setLastDisableAppCaller(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSharedLibraryOverlayPaths(android.util.ArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSplashScreenTheme(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setMinAspectRatio(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSuspendParams(android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setComponentLabelIconOverrideMap(android.util.ArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setFirstInstallTimeMillis(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setArchiveState(com.android.server.pm.pkg.ArchiveState)\npublic @android.annotation.NonNull @java.lang.Override java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> getSharedLibraryOverlayPaths()\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setWatchable(com.android.server.utils.Watchable)\nprivate boolean watchableEquals(com.android.server.utils.Watchable)\nprivate int watchableHashCode()\nprivate boolean snapshotEquals(com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl>)\nprivate int snapshotHashCode()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isQuarantined()\npublic @java.lang.Override boolean dataExists()\nclass PackageUserStateImpl extends com.android.server.utils.WatchableImpl implements [com.android.server.pm.pkg.PackageUserStateInternal, com.android.server.utils.Snappable]\nprivate static final int INSTALLED\nprivate static final int STOPPED\nprivate static final int NOT_LAUNCHED\nprivate static final int HIDDEN\nprivate static final int INSTANT_APP\nprivate static final int VIRTUAL_PRELOADED\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 812e22833aba..f14941b2d9c8 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -28,6 +28,7 @@ import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_
import static android.os.Build.VERSION_CODES.DONUT;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
import static com.android.server.pm.pkg.parsing.ParsingUtils.parseKnownActivityEmbeddingCerts;
import android.annotation.AnyRes;
@@ -509,24 +510,33 @@ public class ParsingPackageUtils {
/* Set the global "on SD card" flag */
.setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0);
+ var archivedPackage = lite.getArchivedPackage();
+ if (archivedPackage == null) {
+ return input.error(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "archivePackage is missing");
+ }
+
// parseBaseAppBasicFlags
pkg
// Default true
- .setBackupAllowed(lite.isBackupAllowed())
+ .setBackupAllowed(true)
.setClearUserDataAllowed(true)
- .setClearUserDataOnFailedRestoreAllowed(
- lite.isClearUserDataOnFailedRestoreAllowed())
+ .setClearUserDataOnFailedRestoreAllowed(true)
.setAllowNativeHeapPointerTagging(true)
.setEnabled(true)
.setExtractNativeLibrariesRequested(true)
// targetSdkVersion gated
.setAllowAudioPlaybackCapture(targetSdk >= Build.VERSION_CODES.Q)
.setHardwareAccelerated(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
- .setRequestLegacyExternalStorage(lite.isRequestLegacyExternalStorage())
+ .setRequestLegacyExternalStorage(
+ XmlUtils.convertValueToBoolean(archivedPackage.requestLegacyExternalStorage,
+ targetSdk < Build.VERSION_CODES.Q))
.setCleartextTrafficAllowed(targetSdk < Build.VERSION_CODES.P)
// Default false
- .setDefaultToDeviceProtectedStorage(lite.isDefaultToDeviceProtectedStorage())
- .setUserDataFragile(lite.isUserDataFragile())
+ .setDefaultToDeviceProtectedStorage(XmlUtils.convertValueToBoolean(
+ archivedPackage.defaultToDeviceProtectedStorage, false))
+ .setUserDataFragile(
+ XmlUtils.convertValueToBoolean(archivedPackage.userDataFragile, false))
// Ints
.setCategory(ApplicationInfo.CATEGORY_UNDEFINED)
// Floats Default 0f
diff --git a/services/core/java/com/android/server/security/Android.bp b/services/core/java/com/android/server/security/Android.bp
deleted file mode 100644
index 3f644c44111a..000000000000
--- a/services/core/java/com/android/server/security/Android.bp
+++ /dev/null
@@ -1,17 +0,0 @@
-aconfig_declarations {
- name: "com.android.server.security.flags-aconfig",
- package: "com.android.server.security",
- srcs: ["*.aconfig"],
-}
-
-java_aconfig_library {
- name: "com.android.server.security.flags-aconfig-java",
- aconfig_declarations: "com.android.server.security.flags-aconfig",
-}
-
-java_aconfig_library {
- name: "com.android.server.security.flags-aconfig-java-host",
- aconfig_declarations: "com.android.server.security.flags-aconfig",
- host_supported: true,
- test: true,
-}
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index 3aed6e30cf87..a49df50c1b92 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -90,6 +90,13 @@ public class FileIntegrityService extends SystemService {
@NonNull String packageName) {
checkCallerPermission(packageName);
+ if (android.security.Flags.deprecateFsvSig()) {
+ // When deprecated, stop telling the caller that any app source certificate is
+ // trusted on the current device. This behavior is also consistent with devices
+ // without this feature support.
+ return false;
+ }
+
try {
if (!VerityUtils.isFsVeritySupported()) {
return false;
diff --git a/services/core/java/com/android/server/security/flags.aconfig b/services/core/java/com/android/server/security/flags.aconfig
deleted file mode 100644
index 0440989f3981..000000000000
--- a/services/core/java/com/android/server/security/flags.aconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-package: "com.android.server.security"
-
-flag {
- name: "deprecate_fsv_sig"
- namespace: "hardware_backed_security"
- description: "Feature flag for deprecating .fsv_sig"
- bug: "277916185"
-}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index cfc7031d01d7..00992a03634d 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -256,6 +256,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
|| event != CLOSE_WRITE // includes the MOVED_TO case
|| wallpaper.imageWallpaperPending;
+ if (isMigration) {
+ // When separate lock screen engine is supported, migration will be handled by
+ // WallpaperDestinationChangeHandler.
+ return;
+ }
+ if (!(sysWallpaperChanged || lockWallpaperChanged)) {
+ return;
+ }
+
if (DEBUG) {
Slog.v(TAG, "Wallpaper file change: evt=" + event
+ " path=" + path
@@ -270,15 +279,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
+ " needsUpdate=" + needsUpdate);
}
- if (isMigration) {
- // When separate lock screen engine is supported, migration will be handled by
- // WallpaperDestinationChangeHandler.
- return;
- }
- if (!(sysWallpaperChanged || lockWallpaperChanged)) {
- return;
- }
-
int notifyColorsWhich = 0;
synchronized (mLock) {
notifyCallbacksLocked(wallpaper);
@@ -1005,11 +1005,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
return;
}
- if (!mWallpaper.wallpaperUpdating
- && mWallpaper.userId == mCurrentUserId) {
+ if (!mWallpaper.wallpaperUpdating && mWallpaper.userId == mCurrentUserId) {
Slog.w(TAG, "Wallpaper reconnect timed out for " + mWallpaper.wallpaperComponent
+ ", reverting to built-in wallpaper!");
- clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null);
+ int which = mIsLockscreenLiveWallpaperEnabled ? mWallpaper.mWhich : FLAG_SYSTEM;
+ clearWallpaperLocked(which, mWallpaper.userId, null);
}
}
};
@@ -1189,7 +1189,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} else {
// Timeout
Slog.w(TAG, "Reverting to built-in wallpaper!");
- clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null);
+ clearWallpaperLocked(mWallpaper.mWhich, mWallpaper.userId, null);
final String flattened = wpService.flattenToString();
EventLog.writeEvent(EventLogTags.WP_WALLPAPER_CRASHED,
flattened.substring(0, Math.min(flattened.length(),
@@ -1228,7 +1228,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} else {
if (mLmkLimitRebindRetries <= 0) {
Slog.w(TAG, "Reverting to built-in wallpaper due to lmk!");
- clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null);
+ clearWallpaperLocked(
+ mWallpaper.mWhich, mWallpaper.userId, null);
mLmkLimitRebindRetries = LMK_RECONNECT_REBIND_RETRIES;
return;
}
@@ -1470,8 +1471,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
final ComponentName wpService = wallpaper.wallpaperComponent;
if (wpService != null && wpService.getPackageName().equals(packageName)) {
if (DEBUG_LIVE) {
@@ -1483,7 +1483,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
wallpaper, null)) {
Slog.w(TAG, "Wallpaper " + wpService
+ " no longer available; reverting to default");
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
+ int which = mIsLockscreenLiveWallpaperEnabled
+ ? wallpaper.mWhich : FLAG_SYSTEM;
+ clearWallpaperLocked(which, wallpaper.userId, null);
}
}
}
@@ -1496,13 +1498,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
- if (wallpaper.wallpaperComponent == null
- || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
- return;
+ for (WallpaperData wallpaper: getWallpapers()) {
+ if (wallpaper.wallpaperComponent != null
+ && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+ doPackagesChangedLocked(true, wallpaper);
}
- doPackagesChangedLocked(true, wallpaper);
}
}
}
@@ -1513,8 +1513,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
if (wallpaper.wallpaperComponent != null
&& wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
if (DEBUG_LIVE) {
@@ -1538,8 +1537,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return false;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
boolean res = doPackagesChangedLocked(doit, wallpaper);
changed |= res;
}
@@ -1553,8 +1551,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
doPackagesChangedLocked(true, wallpaper);
}
}
@@ -1562,6 +1559,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
boolean changed = false;
+ int which = mIsLockscreenLiveWallpaperEnabled ? wallpaper.mWhich : FLAG_SYSTEM;
if (wallpaper.wallpaperComponent != null) {
int change = isPackageDisappearing(wallpaper.wallpaperComponent
.getPackageName());
@@ -1571,7 +1569,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (doit) {
Slog.w(TAG, "Wallpaper uninstalled, removing: "
+ wallpaper.wallpaperComponent);
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
+ clearWallpaperLocked(which, wallpaper.userId, null);
}
}
}
@@ -1592,7 +1590,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} catch (NameNotFoundException e) {
Slog.w(TAG, "Wallpaper component gone, removing: "
+ wallpaper.wallpaperComponent);
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
+ clearWallpaperLocked(which, wallpaper.userId, null);
}
}
if (wallpaper.nextWallpaperComponent != null
@@ -1708,7 +1706,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (DEBUG) {
Slog.i(TAG, "Unable to regenerate crop; resetting");
}
- clearWallpaperLocked(FLAG_SYSTEM, UserHandle.USER_SYSTEM, null);
+ int which = isLockscreenLiveWallpaperEnabled() ? wallpaper.mWhich : FLAG_SYSTEM;
+ clearWallpaperLocked(which, UserHandle.USER_SYSTEM, null);
}
} else {
if (DEBUG) {
@@ -1988,12 +1987,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
WallpaperData wallpaper, IRemoteCallback reply, ServiceInfo serviceInfo) {
if (serviceInfo == null) {
- if (wallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM)) {
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
- clearWallpaperLocked(FLAG_LOCK, wallpaper.userId, reply);
- } else {
- clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, reply);
- }
+ clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, reply);
return;
}
Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked");
@@ -2014,7 +2008,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
@Override
public void clearWallpaper(String callingPackage, int which, int userId) {
- if (DEBUG) Slog.v(TAG, "clearWallpaper");
+ if (DEBUG) Slog.v(TAG, "clearWallpaper: " + which);
checkPermission(android.Manifest.permission.SET_WALLPAPER);
if (!isWallpaperSupported(callingPackage) || !isSetWallpaperAllowed(callingPackage)) {
return;
@@ -2025,7 +2019,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
WallpaperData data = null;
synchronized (mLock) {
if (mIsLockscreenLiveWallpaperEnabled) {
- clearWallpaperLocked(callingPackage, which, userId);
+ boolean fromForeground = isFromForegroundApp(callingPackage);
+ clearWallpaperLocked(which, userId, fromForeground, null);
} else {
clearWallpaperLocked(which, userId, null);
}
@@ -2045,7 +2040,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
- private void clearWallpaperLocked(String callingPackage, int which, int userId) {
+ private void clearWallpaperLocked(int which, int userId, boolean fromForeground,
+ IRemoteCallback reply) {
// Might need to bring it in the first time to establish our rewrite
if (!mWallpaperMap.contains(userId)) {
@@ -2084,8 +2080,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
finalWhich = which;
}
- boolean success = withCleanCallingIdentity(() -> setWallpaperComponent(
- component, callingPackage, finalWhich, userId));
+ // except for the lock case (for which we keep the system wallpaper as-is), force rebind
+ boolean force = which != FLAG_LOCK;
+ boolean success = withCleanCallingIdentity(() -> setWallpaperComponentInternal(
+ component, finalWhich, userId, force, fromForeground, reply));
if (success) return;
} catch (IllegalArgumentException e1) {
e = e1;
@@ -2097,10 +2095,23 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// wallpaper.
Slog.e(TAG, "Default wallpaper component not found!", e);
withCleanCallingIdentity(() -> clearWallpaperComponentLocked(wallpaper));
+ if (reply != null) {
+ try {
+ reply.sendResult(null);
+ } catch (RemoteException e1) {
+ Slog.w(TAG, "Failed to notify callback after wallpaper clear", e1);
+ }
+ }
}
- // TODO(b/266818039) remove this version of the method
+ // TODO(b/266818039) remove
private void clearWallpaperLocked(int which, int userId, IRemoteCallback reply) {
+
+ if (mIsLockscreenLiveWallpaperEnabled) {
+ clearWallpaperLocked(which, userId, false, reply);
+ return;
+ }
+
if (which != FLAG_SYSTEM && which != FLAG_LOCK) {
throw new IllegalArgumentException("Must specify exactly one kind of wallpaper to clear");
}
@@ -2815,6 +2826,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
: new WallpaperData[0];
}
+ // TODO(b/266818039) remove
+ private WallpaperData[] getWallpapers() {
+ WallpaperData systemWallpaper = mWallpaperMap.get(mCurrentUserId);
+ WallpaperData lockWallpaper = mLockWallpaperMap.get(mCurrentUserId);
+ boolean systemValid = systemWallpaper != null;
+ boolean lockValid = lockWallpaper != null && !isLockscreenLiveWallpaperEnabled();
+ return systemValid && lockValid ? new WallpaperData[]{systemWallpaper, lockWallpaper}
+ : systemValid ? new WallpaperData[]{systemWallpaper}
+ : lockValid ? new WallpaperData[]{lockWallpaper}
+ : new WallpaperData[0];
+ }
+
private IWallpaperEngine getEngine(int which, int userId, int displayId) {
WallpaperData wallpaperData = findWallpaperAtDisplay(userId, displayId);
if (wallpaperData == null) return null;
@@ -3272,15 +3295,16 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
boolean setWallpaperComponent(ComponentName name, String callingPackage,
@SetWallpaperFlags int which, int userId) {
if (mIsLockscreenLiveWallpaperEnabled) {
- return setWallpaperComponentInternal(name, callingPackage, which, userId);
+ boolean fromForeground = isFromForegroundApp(callingPackage);
+ return setWallpaperComponentInternal(name, which, userId, false, fromForeground, null);
} else {
setWallpaperComponentInternalLegacy(name, callingPackage, which, userId);
return true;
}
}
- private boolean setWallpaperComponentInternal(ComponentName name, String callingPackage,
- @SetWallpaperFlags int which, int userIdIn) {
+ private boolean setWallpaperComponentInternal(ComponentName name, @SetWallpaperFlags int which,
+ int userIdIn, boolean force, boolean fromForeground, IRemoteCallback reply) {
if (DEBUG) {
Slog.v(TAG, "Setting new live wallpaper: which=" + which + ", component: " + name);
}
@@ -3294,7 +3318,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
final WallpaperData newWallpaper;
synchronized (mLock) {
- Slog.v(TAG, "setWallpaperComponent name=" + name);
+ Slog.v(TAG, "setWallpaperComponent name=" + name + ", which = " + which);
final WallpaperData originalSystemWallpaper = mWallpaperMap.get(userId);
if (originalSystemWallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
@@ -3317,29 +3341,21 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
newWallpaper.imageWallpaperPending = false;
newWallpaper.mWhich = which;
newWallpaper.mSystemWasBoth = systemIsBoth;
- newWallpaper.fromForegroundApp = isFromForegroundApp(callingPackage);
+ newWallpaper.fromForegroundApp = fromForeground;
final WallpaperDestinationChangeHandler
liveSync = new WallpaperDestinationChangeHandler(
newWallpaper);
boolean same = changingToSame(name, newWallpaper);
- IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
- @Override
- public void sendResult(Bundle data) throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "publish system wallpaper changed!");
- }
- }
- };
/*
* If we have a shared system+lock wallpaper, and we reapply the same wallpaper
* to system only, force rebind: the current wallpaper will be migrated to lock
* and a new engine with the same wallpaper will be applied to system.
*/
- boolean forceRebind = same && systemIsBoth && which == FLAG_SYSTEM;
+ boolean forceRebind = force || (same && systemIsBoth && which == FLAG_SYSTEM);
bindSuccess = bindWallpaperComponentLocked(name, /* force */
- forceRebind, /* fromUser */ true, newWallpaper, callback);
+ forceRebind, /* fromUser */ true, newWallpaper, reply);
if (bindSuccess) {
if (!same) {
newWallpaper.primaryColors = null;
@@ -3409,7 +3425,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
WallpaperData wallpaper;
synchronized (mLock) {
- Slog.v(TAG, "setWallpaperComponent name=" + name + ", which=" + which);
+ Slog.v(TAG, "setWallpaperComponentLegacy name=" + name + ", which=" + which);
wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
@@ -3478,15 +3494,24 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
+ /**
+ * Determines if the given component name is the default component. Note: a null name can be
+ * used to represent the default component.
+ * @param name The component name to check.
+ * @return True if the component name matches the default wallpaper component.
+ */
+ private boolean isDefaultComponent(ComponentName name) {
+ return name == null || name.equals(mDefaultWallpaperComponent);
+ }
+
private boolean changingToSame(ComponentName componentName, WallpaperData wallpaper) {
if (wallpaper.connection != null) {
- if (wallpaper.wallpaperComponent == null) {
- if (componentName == null) {
- if (DEBUG) Slog.v(TAG, "changingToSame: still using default");
- // Still using default wallpaper.
- return true;
- }
- } else if (wallpaper.wallpaperComponent.equals(componentName)) {
+ final ComponentName wallpaperName = wallpaper.wallpaperComponent;
+ if (isDefaultComponent(componentName) && isDefaultComponent(wallpaperName)) {
+ if (DEBUG) Slog.v(TAG, "changingToSame: still using default");
+ // Still using default wallpaper.
+ return true;
+ } else if (wallpaperName != null && wallpaperName.equals(componentName)) {
// Changing to same wallpaper.
if (DEBUG) Slog.v(TAG, "same wallpaper");
return true;
@@ -3503,6 +3528,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// Has the component changed?
if (!force && changingToSame(componentName, wallpaper)) {
try {
+ if (DEBUG_LIVE) {
+ Slog.v(TAG, "Changing to the same component, ignoring");
+ }
if (reply != null) reply.sendResult(null);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to send callback", e);
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index a5b1132fe499..25c42b4858a4 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -33,9 +33,7 @@ import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
-import static com.android.server.wm.ActivityInterceptorCallback.MAINLINE_SDK_SANDBOX_ORDER_ID;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.KeyguardManager;
@@ -240,11 +238,6 @@ class ActivityStartInterceptor {
getInterceptorInfo(null /* clearOptionsAnimation */);
for (int i = 0; i < callbacks.size(); i++) {
- final int orderId = callbacks.keyAt(i);
- if (!shouldInterceptActivityLaunch(orderId, interceptorInfo)) {
- continue;
- }
-
final ActivityInterceptorCallback callback = callbacks.valueAt(i);
final ActivityInterceptResult interceptResult = callback.onInterceptActivityLaunch(
interceptorInfo);
@@ -543,11 +536,6 @@ class ActivityStartInterceptor {
ActivityInterceptorCallback.ActivityInterceptorInfo info = getInterceptorInfo(
r::clearOptionsAnimationForSiblings);
for (int i = 0; i < callbacks.size(); i++) {
- final int orderId = callbacks.keyAt(i);
- if (!shouldNotifyOnActivityLaunch(orderId, info)) {
- continue;
- }
-
final ActivityInterceptorCallback callback = callbacks.valueAt(i);
callback.onActivityLaunched(taskInfo, r.info, info);
}
@@ -565,21 +553,4 @@ class ActivityStartInterceptor {
.build();
}
- private boolean shouldInterceptActivityLaunch(
- @ActivityInterceptorCallback.OrderedId int orderId,
- @NonNull ActivityInterceptorCallback.ActivityInterceptorInfo info) {
- if (orderId == MAINLINE_SDK_SANDBOX_ORDER_ID) {
- return info.getIntent() != null && info.getIntent().isSandboxActivity(mServiceContext);
- }
- return true;
- }
-
- private boolean shouldNotifyOnActivityLaunch(
- @ActivityInterceptorCallback.OrderedId int orderId,
- @NonNull ActivityInterceptorCallback.ActivityInterceptorInfo info) {
- if (orderId == MAINLINE_SDK_SANDBOX_ORDER_ID) {
- return info.getIntent() != null && info.getIntent().isSandboxActivity(mServiceContext);
- }
- return true;
- }
}
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 0a2bbd467ab3..4b463c7e1756 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -459,7 +459,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
// insets should keep original position before the start transaction is applied.
return mTransitionOp != OP_LEGACY && (mTransitionOp == OP_APP_SWITCH
|| TransitionController.SYNC_METHOD == BLASTSyncEngine.METHOD_BLAST)
- && !mIsStartTransactionCommitted && isTargetToken(w.mToken);
+ && !mIsStartTransactionCommitted && canBeAsync(w.mToken) && isTargetToken(w.mToken);
}
/**
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 7cd07d6f3a5f..ed3108e8e3ae 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -141,60 +141,62 @@ final class ContentRecorder implements WindowContainerListener {
*/
void onConfigurationChanged(@Configuration.Orientation int lastOrientation) {
// Update surface for MediaProjection, if this DisplayContent is being used for recording.
- if (isCurrentlyRecording() && mLastRecordedBounds != null) {
- // Recording has already begun, but update recording since the display is now on.
- if (mRecordedWindowContainer == null) {
+ if (!isCurrentlyRecording() || mLastRecordedBounds == null) {
+ return;
+ }
+
+ // Recording has already begun, but update recording since the display is now on.
+ if (mRecordedWindowContainer == null) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Unexpectedly null window container; unable to update "
+ + "recording for display %d",
+ mDisplayContent.getDisplayId());
+ return;
+ }
+
+ // TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are
+ // inaccurate.
+ if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
+ final Task capturedTask = mRecordedWindowContainer.asTask();
+ if (capturedTask.inPinnedWindowingMode()) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Unexpectedly null window container; unable to update "
- + "recording for display %d",
+ "Content Recording: Display %d was already recording, but "
+ + "pause capture since the task is in PIP",
mDisplayContent.getDisplayId());
+ pauseRecording();
return;
}
+ }
- // TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are
- // inaccurate.
- if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
- final Task capturedTask = mRecordedWindowContainer.asTask();
- if (capturedTask.inPinnedWindowingMode()) {
- ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Display %d was already recording, but "
- + "pause capture since the task is in PIP",
- mDisplayContent.getDisplayId());
- pauseRecording();
- return;
- }
- }
-
- ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Display %d was already recording, so apply "
- + "transformations if necessary",
- mDisplayContent.getDisplayId());
- // Retrieve the size of the region to record, and continue with the update
- // if the bounds or orientation has changed.
- final Rect recordedContentBounds = mRecordedWindowContainer.getBounds();
- @Configuration.Orientation int recordedContentOrientation =
- mRecordedWindowContainer.getConfiguration().orientation;
- if (!mLastRecordedBounds.equals(recordedContentBounds)
- || lastOrientation != recordedContentOrientation) {
- Point surfaceSize = fetchSurfaceSizeIfPresent();
- if (surfaceSize != null) {
- ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Going ahead with updating recording for display "
- + "%d to new bounds %s and/or orientation %d.",
- mDisplayContent.getDisplayId(), recordedContentBounds,
- recordedContentOrientation);
- updateMirroredSurface(mRecordedWindowContainer.getSyncTransaction(),
- recordedContentBounds, surfaceSize);
- } else {
- // If the surface removed, do nothing. We will handle this via onDisplayChanged
- // (the display will be off if the surface is removed).
- ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Unable to update recording for display %d to new "
- + "bounds %s and/or orientation %d, since the surface is not "
- + "available.",
- mDisplayContent.getDisplayId(), recordedContentBounds,
- recordedContentOrientation);
- }
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Display %d was already recording, so apply "
+ + "transformations if necessary",
+ mDisplayContent.getDisplayId());
+ // Retrieve the size of the region to record, and continue with the update
+ // if the bounds or orientation has changed.
+ final Rect recordedContentBounds = mRecordedWindowContainer.getBounds();
+ @Configuration.Orientation int recordedContentOrientation =
+ mRecordedWindowContainer.getConfiguration().orientation;
+ if (!mLastRecordedBounds.equals(recordedContentBounds)
+ || lastOrientation != recordedContentOrientation) {
+ Point surfaceSize = fetchSurfaceSizeIfPresent();
+ if (surfaceSize != null) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Going ahead with updating recording for display "
+ + "%d to new bounds %s and/or orientation %d.",
+ mDisplayContent.getDisplayId(), recordedContentBounds,
+ recordedContentOrientation);
+ updateMirroredSurface(mRecordedWindowContainer.getSyncTransaction(),
+ recordedContentBounds, surfaceSize);
+ } else {
+ // If the surface removed, do nothing. We will handle this via onDisplayChanged
+ // (the display will be off if the surface is removed).
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Unable to update recording for display %d to new "
+ + "bounds %s and/or orientation %d, since the surface is not "
+ + "available.",
+ mDisplayContent.getDisplayId(), recordedContentBounds,
+ recordedContentOrientation);
}
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index daa73db4684d..4309e72c30d7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -6040,8 +6040,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mOffTokenAcquirer.release(mDisplayId);
}
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Display %d state is now (%d), so update recording?",
- mDisplayId, displayState);
+ "Content Recording: Display %d state was (%d), is now (%d), so update "
+ + "recording?",
+ mDisplayId, lastDisplayState, displayState);
if (lastDisplayState != displayState) {
// If state is on due to surface being added, then start recording.
// If state is off due to surface being removed, then stop recording.
@@ -6505,14 +6506,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/**
- * @return whether AOD is showing on this display
- */
- boolean isAodShowing() {
- return mRootWindowContainer.mTaskSupervisor
- .getKeyguardController().isAodShowing(mDisplayId);
- }
-
- /**
* @return whether this display maintains its own focus and touch mode.
*/
boolean hasOwnFocus() {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 395ab3a641b4..17bfeb453304 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1677,18 +1677,6 @@ public class DisplayPolicy {
}
private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
- // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered
- // hidden because it's in the process of hiding, but it's still being shown on screen.
- // In that case, we want to continue hiding the IME until the windows have completed
- // drawing. This way, we know that the IME can be safely shown since the other windows are
- // now shown.
- final boolean hideIme = win.mIsImWindow
- && (mDisplayContent.isAodShowing()
- || (mDisplayContent.isDefaultDisplay && !mWindowManagerDrawComplete));
- if (hideIme) {
- return true;
- }
-
if (!mDisplayContent.isDefaultDisplay || !isKeyguardShowing()) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 579fd14f8fab..45cf10bd3f5e 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -29,7 +29,6 @@ import android.util.Slog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.window.flags.FeatureFlags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -91,6 +90,13 @@ final class LetterboxConfiguration {
"enable_app_compat_user_aspect_ratio_fullscreen";
private static final boolean DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_FULLSCREEN = true;
+ // Whether the letterbox wallpaper style is enabled by default
+ private static final String KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER =
+ "enable_letterbox_background_wallpaper";
+
+ // TODO(b/290048978): Enable wallpaper as default letterbox background.
+ private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER = false;
+
/**
* Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
* set-fixed-orientation-letterbox-aspect-ratio or via {@link
@@ -179,9 +185,6 @@ final class LetterboxConfiguration {
@NonNull
private final LetterboxConfigurationPersister mLetterboxConfigurationPersister;
- @NonNull
- private final FeatureFlags mFeatureFlags;
-
// Aspect ratio of letterbox for fixed orientation, values <=
// MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
private float mFixedOrientationLetterboxAspectRatio;
@@ -298,8 +301,7 @@ final class LetterboxConfiguration {
// Flags dynamically updated with {@link android.provider.DeviceConfig}.
@NonNull private final SynchedDeviceConfig mDeviceConfig;
- LetterboxConfiguration(@NonNull final Context systemUiContext,
- @NonNull FeatureFlags featureFags) {
+ LetterboxConfiguration(@NonNull final Context systemUiContext) {
this(systemUiContext, new LetterboxConfigurationPersister(
() -> readLetterboxHorizontalReachabilityPositionFromConfig(
systemUiContext, /* forBookMode */ false),
@@ -308,16 +310,14 @@ final class LetterboxConfiguration {
() -> readLetterboxHorizontalReachabilityPositionFromConfig(
systemUiContext, /* forBookMode */ true),
() -> readLetterboxVerticalReachabilityPositionFromConfig(
- systemUiContext, /* forTabletopMode */ true)),
- featureFags);
+ systemUiContext, /* forTabletopMode */ true)));
}
@VisibleForTesting
LetterboxConfiguration(@NonNull final Context systemUiContext,
- @NonNull final LetterboxConfigurationPersister letterboxConfigurationPersister,
- @NonNull FeatureFlags featureFags) {
+ @NonNull final LetterboxConfigurationPersister letterboxConfigurationPersister) {
mContext = systemUiContext;
- mFeatureFlags = featureFags;
+
mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
R.dimen.config_fixedOrientationLetterboxAspectRatio);
mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
@@ -385,6 +385,8 @@ final class LetterboxConfiguration {
DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS,
mContext.getResources().getBoolean(
R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled))
+ .addDeviceConfigEntry(KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER,
+ DEFAULT_VALUE_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER, /* enabled */ true)
.addDeviceConfigEntry(KEY_ENABLE_USER_ASPECT_RATIO_FULLSCREEN,
DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_FULLSCREEN,
mContext.getResources().getBoolean(
@@ -542,7 +544,8 @@ final class LetterboxConfiguration {
}
/**
- * Resets letterbox background type value depending on the built time and runtime flags.
+ * Resets letterbox background type value depending on the
+ * {@link #KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER} built time and runtime flags.
*
* <p>If enabled, the letterbox background type value is set toZ
* {@link #LETTERBOX_BACKGROUND_WALLPAPER}. When disabled the letterbox background type value
@@ -552,11 +555,12 @@ final class LetterboxConfiguration {
mLetterboxBackgroundTypeOverride = LETTERBOX_BACKGROUND_OVERRIDE_UNSET;
}
- // Returns LETTERBOX_BACKGROUND_WALLPAPER if the flag is enabled or the value in
- // com.android.internal.R.integer.config_letterboxBackgroundType if the flag is disabled.
+ // Returns KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER if the DeviceConfig flag is enabled
+ // or the value in com.android.internal.R.integer.config_letterboxBackgroundType if the flag
+ // is disabled.
@LetterboxBackgroundType
private int getDefaultLetterboxBackgroundType() {
- return mFeatureFlags.letterboxBackgroundWallpaperFlag()
+ return mDeviceConfig.getFlagValue(KEY_ENABLE_LETTERBOX_BACKGROUND_WALLPAPER)
? LETTERBOX_BACKGROUND_WALLPAPER : mLetterboxBackgroundType;
}
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index a27cc3ad9973..ea722b61be6f 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -184,14 +184,31 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
void dispose() {
+ boolean wasVisible = false;
for (int i = mOrganizedTaskFragments.size() - 1; i >= 0; i--) {
+ final TaskFragment taskFragment = mOrganizedTaskFragments.get(i);
+ if (taskFragment.isVisibleRequested()) {
+ wasVisible = true;
+ }
// Cleanup the TaskFragmentOrganizer from all TaskFragments it organized before
// removing the windows to prevent it from adding any additional TaskFragment
// pending event.
- final TaskFragment taskFragment = mOrganizedTaskFragments.get(i);
taskFragment.onTaskFragmentOrganizerRemoved();
}
+ final TransitionController transitionController = mAtmService.getTransitionController();
+ if (wasVisible && transitionController.isShellTransitionsEnabled()
+ && !transitionController.isCollecting()) {
+ final Task task = mOrganizedTaskFragments.get(0).getTask();
+ final boolean containsNonEmbeddedActivity =
+ task != null && task.getActivity(a -> !a.isEmbedded()) != null;
+ transitionController.requestStartTransition(
+ transitionController.createTransition(WindowManager.TRANSIT_CLOSE),
+ // The task will be removed if all its activities are embedded, then the
+ // task is the trigger.
+ containsNonEmbeddedActivity ? null : task,
+ null /* remoteTransition */, null /* displayChange */);
+ }
// Defer to avoid unnecessary layout when there are multiple TaskFragments removal.
mAtmService.deferWindowLayout();
try {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e720446d7bad..77e1f5bdb171 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -97,6 +97,7 @@ import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_MULTIPLIER;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
import static android.window.WindowProviderService.isWindowProviderService;
+
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
@@ -333,7 +334,6 @@ import com.android.server.policy.WindowManagerPolicy;
import com.android.server.policy.WindowManagerPolicy.ScreenOffListener;
import com.android.server.power.ShutdownThread;
import com.android.server.utils.PriorityDump;
-import com.android.window.flags.FeatureFlagsImpl;
import dalvik.annotation.optimization.NeverCompile;
@@ -1175,8 +1175,7 @@ public class WindowManagerService extends IWindowManager.Stub
mLetterboxConfiguration = new LetterboxConfiguration(
// Using SysUI context to have access to Material colors extracted from Wallpaper.
- ActivityThread.currentActivityThread().getSystemUiContext(),
- new FeatureFlagsImpl());
+ ActivityThread.currentActivityThread().getSystemUiContext());
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
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 d22e02e9dae6..4203e89ec618 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -50,6 +50,13 @@
maxOccurs="1"/>
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
maxOccurs="1"/>
+
+ <xs:element name="hdrBrightnessConfig" type="hdrBrightnessConfig"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="nullable"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+
<xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1"/>
<xs:element type="autoBrightness" name="autoBrightness" minOccurs="0"
maxOccurs="1"/>
@@ -238,6 +245,31 @@
</xs:all>
</xs:complexType>
+ <!-- brightness config for HDR content -->
+ <xs:complexType name="hdrBrightnessConfig">
+ <!-- lux level from light sensor to screen brightness recommended max value map. -->
+ <xs:element name="brightnessMap" type="nonNegativeFloatToFloatMap">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- Debounce for brightness increase in millis -->
+ <xs:element name="brightnessIncreaseDebounceMillis" type="xs:nonNegativeInteger">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- Debounce for brightness decrease in millis -->
+ <xs:element name="brightnessDecreaseDebounceMillis" type="xs:nonNegativeInteger">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- Animation time for brightness increase in millis -->
+ <xs:element name="brightnessIncreaseDurationMillis" type="xs:nonNegativeInteger">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- Animation time for brightness decrease in millis -->
+ <xs:element name="brightnessDecreaseDurationMillis" type="xs:nonNegativeInteger">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:complexType>
+
<!-- Maps to PowerManager.THERMAL_STATUS_* values. -->
<xs:simpleType name="thermalStatus">
<xs:restriction base="xs:string">
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 6364c1feb659..ebd9b1c23a50 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -101,6 +101,7 @@ package com.android.server.display.config {
method @Nullable public final com.android.server.display.config.DensityMapping getDensityMapping();
method @NonNull public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholds();
method public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholdsIdle();
+ method @Nullable public final com.android.server.display.config.HdrBrightnessConfig getHdrBrightnessConfig();
method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
method public final com.android.server.display.config.SensorDetails getLightSensor();
method public com.android.server.display.config.LuxThrottling getLuxThrottling();
@@ -130,6 +131,7 @@ package com.android.server.display.config {
method public final void setDensityMapping(@Nullable com.android.server.display.config.DensityMapping);
method public final void setDisplayBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
method public final void setDisplayBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
+ method public final void setHdrBrightnessConfig(@Nullable com.android.server.display.config.HdrBrightnessConfig);
method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
method public final void setLightSensor(com.android.server.display.config.SensorDetails);
method public void setLuxThrottling(com.android.server.display.config.LuxThrottling);
@@ -168,6 +170,20 @@ package com.android.server.display.config {
method public final void setTimeWindowSecs_all(@NonNull java.math.BigInteger);
}
+ public class HdrBrightnessConfig {
+ ctor public HdrBrightnessConfig();
+ method public final java.math.BigInteger getBrightnessDecreaseDebounceMillis();
+ method public final java.math.BigInteger getBrightnessDecreaseDurationMillis();
+ method public final java.math.BigInteger getBrightnessIncreaseDebounceMillis();
+ method public final java.math.BigInteger getBrightnessIncreaseDurationMillis();
+ method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getBrightnessMap();
+ method public final void setBrightnessDecreaseDebounceMillis(java.math.BigInteger);
+ method public final void setBrightnessDecreaseDurationMillis(java.math.BigInteger);
+ method public final void setBrightnessIncreaseDebounceMillis(java.math.BigInteger);
+ method public final void setBrightnessIncreaseDurationMillis(java.math.BigInteger);
+ method public final void setBrightnessMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap);
+ }
+
public class HighBrightnessMode {
ctor public HighBrightnessMode();
method @NonNull public final boolean getAllowInLowPowerMode_all();
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index d8c684fb8c1e..49792746fbc3 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -96,6 +96,9 @@ public final class CredentialManagerService
private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER =
"enable_credential_manager";
+ private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API =
+ "enable_credential_description_api";
+
private final Context mContext;
/** Cache of system service list per user id. */
@@ -321,7 +324,14 @@ public final class CredentialManagerService
}
public static boolean isCredentialDescriptionApiEnabled() {
- return true;
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API,
+ false);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
}
@SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
@@ -954,7 +964,7 @@ public final class CredentialManagerService
Slog.i(TAG, "registerCredentialDescription with callingPackage: " + callingPackage);
if (!isCredentialDescriptionApiEnabled()) {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("Feature not supported");
}
enforceCallingPackage(callingPackage, Binder.getCallingUid());
@@ -974,7 +984,7 @@ public final class CredentialManagerService
if (!isCredentialDescriptionApiEnabled()) {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("Feature not supported");
}
enforceCallingPackage(callingPackage, Binder.getCallingUid());
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 21b12914bc4c..d0ead141b58c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -1472,11 +1472,10 @@ final class DevicePolicyEngine {
synchronized (mLock) {
clear();
new DevicePoliciesReaderWriter().readFromFileLocked();
- reapplyAllPoliciesLocked();
}
}
- private <V> void reapplyAllPoliciesLocked() {
+ <V> void reapplyAllPoliciesLocked() {
for (PolicyKey policy : mGlobalPolicies.keySet()) {
PolicyState<?> policyState = mGlobalPolicies.get(policy);
// Policy definition and value will always be of the same type
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 50dc061c1ab2..84d1a452fa7e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3347,6 +3347,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
mOwners.systemReady();
applyManagedSubscriptionsPolicyIfRequired();
break;
+ case SystemService.PHASE_SYSTEM_SERVICES_READY:
+ synchronized (getLockObject()) {
+ mDevicePolicyEngine.reapplyAllPoliciesLocked();
+ }
+ break;
case SystemService.PHASE_ACTIVITY_MANAGER_READY:
synchronized (getLockObject()) {
migrateToProfileOnOrganizationOwnedDeviceIfCompLocked();
@@ -15836,6 +15841,83 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
/**
+ * @param restriction The restriction enforced by admin. It could be any user restriction or
+ * policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA},
+ * {@link DevicePolicyManager#POLICY_DISABLE_SCREEN_CAPTURE} and {@link
+ * DevicePolicyManager#POLICY_SUSPEND_PACKAGES}.
+ */
+ private Set<android.app.admin.EnforcingAdmin> getEnforcingAdminsForRestrictionInternal(
+ int userId, @NonNull String restriction) {
+ Objects.requireNonNull(restriction);
+ Set<android.app.admin.EnforcingAdmin> admins = new HashSet<>();
+ // For POLICY_SUSPEND_PACKAGES return PO or DO to keep the behavior same as
+ // before the bug fix for b/192245204.
+ if (DevicePolicyManager.POLICY_SUSPEND_PACKAGES.equals(
+ restriction)) {
+ ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
+ if (profileOwner != null) {
+ EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+ profileOwner, userId);
+ admins.add(admin.getParcelableAdmin());
+ return admins;
+ }
+ final Pair<Integer, ComponentName> deviceOwner =
+ mOwners.getDeviceOwnerUserIdAndComponent();
+ if (deviceOwner != null && deviceOwner.first == userId) {
+ EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+ deviceOwner.second, deviceOwner.first);
+ admins.add(admin.getParcelableAdmin());
+ return admins;
+ }
+ } else {
+ long ident = mInjector.binderClearCallingIdentity();
+ try {
+ PolicyDefinition<Boolean> policyDefinition = getPolicyDefinitionForRestriction(
+ restriction);
+ Boolean value = mDevicePolicyEngine.getResolvedPolicy(policyDefinition, userId);
+ if (value != null && value) {
+ Map<EnforcingAdmin, PolicyValue<Boolean>> globalPolicies =
+ mDevicePolicyEngine.getGlobalPoliciesSetByAdmins(policyDefinition);
+ for (EnforcingAdmin admin : globalPolicies.keySet()) {
+ if (globalPolicies.get(admin) != null
+ && Boolean.TRUE.equals(globalPolicies.get(admin).getValue())) {
+ admins.add(admin.getParcelableAdmin());
+ }
+ }
+
+ Map<EnforcingAdmin, PolicyValue<Boolean>> localPolicies =
+ mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+ policyDefinition, userId);
+ for (EnforcingAdmin admin : localPolicies.keySet()) {
+ if (localPolicies.get(admin) != null
+ && Boolean.TRUE.equals(localPolicies.get(admin).getValue())) {
+ admins.add(admin.getParcelableAdmin());
+ }
+ }
+ return admins;
+ }
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
+ }
+ return admins;
+ }
+
+ private static PolicyDefinition<Boolean> getPolicyDefinitionForRestriction(
+ @NonNull String restriction) {
+ Objects.requireNonNull(restriction);
+ if (DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) {
+ return PolicyDefinition.getPolicyDefinitionForUserRestriction(
+ UserManager.DISALLOW_CAMERA);
+ } else if (DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) {
+ return PolicyDefinition.SCREEN_CAPTURE_DISABLED;
+ } else {
+ return PolicyDefinition.getPolicyDefinitionForUserRestriction(restriction);
+ }
+ }
+
+
+ /**
* Excludes restrictions imposed by UserManager.
*/
private List<UserManager.EnforcingUser> getDevicePolicySources(
@@ -15873,6 +15955,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return getEnforcingAdminAndUserDetailsInternal(userId, restriction);
}
+ @Override
+ public List<android.app.admin.EnforcingAdmin> getEnforcingAdminsForRestriction(
+ int userId, String restriction) {
+ Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()));
+ return new ArrayList<>(getEnforcingAdminsForRestrictionInternal(userId, restriction));
+ }
+
/**
* @param restriction The restriction enforced by admin. It could be any user restriction or
* policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA} and
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
index 5243d14af1ab..006642235615 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
@@ -228,7 +228,8 @@ final class EnforcingAdmin {
return new android.app.admin.EnforcingAdmin(
mPackageName,
authority,
- UserHandle.of(mUserId));
+ UserHandle.of(mUserId),
+ mComponentName);
}
/**
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
index dc2fbfc6414d..2889c749f679 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -24,9 +24,7 @@ import static android.content.pm.SuspendDialogInfo.BUTTON_ACTION_MORE_DETAILS;
import static android.content.pm.SuspendDialogInfo.BUTTON_ACTION_UNSUSPEND;
import static android.content.pm.parsing.FrameworkParsingPackageUtils.parsePublicKey;
import static android.content.res.Resources.ID_NULL;
-
import static com.android.server.pm.PackageManagerService.WRITE_USER_PACKAGE_RESTRICTIONS;
-
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
@@ -997,7 +995,7 @@ public class PackageManagerSettingsTests {
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
UUID.randomUUID());
- origPkgSetting01.setUserState(0, 100, 1, true, false, false, false, 0, null, false,
+ origPkgSetting01.setUserState(0, 100, 100, 1, true, false, false, false, 0, null, false,
false, "lastDisabledCaller", new ArraySet<>(new String[]{"enabledComponent1"}),
new ArraySet<>(new String[]{"disabledComponent1"}), 0, 0, "harmfulAppWarning",
"splashScreenTheme", 1000L, PackageManager.USER_MIN_ASPECT_RATIO_UNSET, null);
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
index 3ef3a89da94d..3ab25479686d 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyTest.kt
@@ -16,12 +16,14 @@
package com.android.server.permission.test
+import android.Manifest
import android.content.pm.PackageManager
import android.content.pm.PermissionGroupInfo
import android.content.pm.PermissionInfo
+import android.content.pm.SigningDetails
+import android.os.Build
import android.os.Bundle
import android.util.ArrayMap
-import android.util.ArraySet
import android.util.SparseArray
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.modules.utils.testing.ExtendedMockitoRule
@@ -33,12 +35,15 @@ import com.android.server.permission.access.immutable.* // ktlint-disable no-wil
import com.android.server.permission.access.permission.AppIdPermissionPolicy
import com.android.server.permission.access.permission.Permission
import com.android.server.permission.access.permission.PermissionFlags
+import com.android.server.permission.access.util.hasBits
import com.android.server.pm.parsing.PackageInfoUtils
+import com.android.server.pm.permission.PermissionAllowlist
import com.android.server.pm.pkg.AndroidPackage
import com.android.server.pm.pkg.PackageState
import com.android.server.pm.pkg.PackageUserState
import com.android.server.pm.pkg.component.ParsedPermission
import com.android.server.pm.pkg.component.ParsedPermissionGroup
+import com.android.server.testutils.any
import com.android.server.testutils.mock
import com.android.server.testutils.whenever
import com.google.common.truth.Truth.assertWithMessage
@@ -46,6 +51,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyLong
/**
* Mocking unit test for AppIdPermissionPolicy.
@@ -55,11 +61,16 @@ class AppIdPermissionPolicyTest {
private lateinit var oldState: MutableAccessState
private lateinit var newState: MutableAccessState
- private lateinit var androidPackage0: AndroidPackage
- private lateinit var androidPackage1: AndroidPackage
-
- private lateinit var packageState0: PackageState
- private lateinit var packageState1: PackageState
+ private val defaultPermissionGroup = mockParsedPermissionGroup(
+ PERMISSION_GROUP_NAME_0,
+ PACKAGE_NAME_0
+ )
+ private val defaultPermissionTree = mockParsedPermission(
+ PERMISSION_TREE_NAME,
+ PACKAGE_NAME_0,
+ isTree = true
+ )
+ private val defaultPermission = mockParsedPermission(PERMISSION_NAME_0, PACKAGE_NAME_0)
private val appIdPermissionPolicy = AppIdPermissionPolicy()
@@ -70,160 +81,124 @@ class AppIdPermissionPolicyTest {
.build()
@Before
- fun init() {
+ fun setUp() {
oldState = MutableAccessState()
createUserState(USER_ID_0)
- createUserState(USER_ID_1)
oldState.mutateExternalState().setPackageStates(ArrayMap())
-
- androidPackage0 = mockAndroidPackage(
- PACKAGE_NAME_0,
- PERMISSION_GROUP_NAME_0,
- PERMISSION_NAME_0
- )
- androidPackage1 = mockAndroidPackage(
- PACKAGE_NAME_1,
- PERMISSION_GROUP_NAME_1,
- PERMISSION_NAME_1
- )
-
- packageState0 = mockPackageState(APP_ID_0, androidPackage0)
- packageState1 = mockPackageState(APP_ID_1, androidPackage1)
+ oldState.mutateExternalState().setDisabledSystemPackageStates(ArrayMap())
+ mockPackageInfoUtilsGeneratePermissionInfo()
+ mockPackageInfoUtilsGeneratePermissionGroupInfo()
}
- private fun mockAndroidPackage(
- packageName: String,
- permissionGroupName: String,
- permissionName: String,
- ): AndroidPackage {
- val parsedPermissionGroup = mock<ParsedPermissionGroup> {
- whenever(name).thenReturn(permissionGroupName)
- whenever(metaData).thenReturn(Bundle())
- }
+ private fun createUserState(userId: Int) {
+ oldState.mutateExternalState().mutateUserIds().add(userId)
+ oldState.mutateUserStatesNoWrite().put(userId, MutableUserState())
+ }
- @Suppress("DEPRECATION")
- val permissionGroupInfo = PermissionGroupInfo().apply {
- name = permissionGroupName
- this.packageName = packageName
- }
+ private fun mockPackageInfoUtilsGeneratePermissionInfo() {
wheneverStatic {
- PackageInfoUtils.generatePermissionGroupInfo(
- parsedPermissionGroup,
- PackageManager.GET_META_DATA.toLong()
- )
- }.thenReturn(permissionGroupInfo)
-
- val parsedPermission = mock<ParsedPermission> {
- whenever(name).thenReturn(permissionName)
- whenever(isTree).thenReturn(false)
- whenever(metaData).thenReturn(Bundle())
+ PackageInfoUtils.generatePermissionInfo(any(ParsedPermission::class.java), anyLong())
+ }.thenAnswer { invocation ->
+ val parsedPermission = invocation.getArgument<ParsedPermission>(0)
+ val generateFlags = invocation.getArgument<Long>(1)
+ PermissionInfo(parsedPermission.backgroundPermission).apply {
+ name = parsedPermission.name
+ packageName = parsedPermission.packageName
+ metaData = if (generateFlags.toInt().hasBits(PackageManager.GET_META_DATA)) {
+ parsedPermission.metaData
+ } else {
+ null
+ }
+ @Suppress("DEPRECATION")
+ protectionLevel = parsedPermission.protectionLevel
+ group = parsedPermission.group
+ flags = parsedPermission.flags
+ }
}
+ }
- @Suppress("DEPRECATION")
- val permissionInfo = PermissionInfo().apply {
- name = permissionName
- this.packageName = packageName
- }
+ private fun mockPackageInfoUtilsGeneratePermissionGroupInfo() {
wheneverStatic {
- PackageInfoUtils.generatePermissionInfo(
- parsedPermission,
- PackageManager.GET_META_DATA.toLong()
+ PackageInfoUtils.generatePermissionGroupInfo(
+ any(ParsedPermissionGroup::class.java),
+ anyLong()
)
- }.thenReturn(permissionInfo)
-
- val requestedPermissions = ArraySet<String>()
- return mock {
- whenever(this.packageName).thenReturn(packageName)
- whenever(this.requestedPermissions).thenReturn(requestedPermissions)
- whenever(permissionGroups).thenReturn(listOf(parsedPermissionGroup))
- whenever(permissions).thenReturn(listOf(parsedPermission))
- whenever(signingDetails).thenReturn(mock {})
- }
- }
-
- private fun mockPackageState(
- appId: Int,
- androidPackage: AndroidPackage,
- ): PackageState {
- val packageName = androidPackage.packageName
- oldState.mutateExternalState().mutateAppIdPackageNames().mutateOrPut(appId) {
- MutableIndexedListSet()
- }.add(packageName)
-
- val userStates = SparseArray<PackageUserState>().apply {
- put(USER_ID_0, mock { whenever(isInstantApp).thenReturn(false) })
- }
- val mockPackageState: PackageState = mock {
- whenever(this.packageName).thenReturn(packageName)
- whenever(this.appId).thenReturn(appId)
- whenever(this.androidPackage).thenReturn(androidPackage)
- whenever(isSystem).thenReturn(false)
- whenever(this.userStates).thenReturn(userStates)
- }
- oldState.mutateExternalState().setPackageStates(
- oldState.mutateExternalState().packageStates.toMutableMap().apply {
- put(packageName, mockPackageState)
+ }.thenAnswer { invocation ->
+ val parsedPermissionGroup = invocation.getArgument<ParsedPermissionGroup>(0)
+ val generateFlags = invocation.getArgument<Long>(1)
+ @Suppress("DEPRECATION")
+ PermissionGroupInfo().apply {
+ name = parsedPermissionGroup.name
+ packageName = parsedPermissionGroup.packageName
+ metaData = if (generateFlags.toInt().hasBits(PackageManager.GET_META_DATA)) {
+ parsedPermissionGroup.metaData
+ } else {
+ null
+ }
+ flags = parsedPermissionGroup.flags
}
- )
- return mockPackageState
- }
-
- private fun createUserState(userId: Int) {
- oldState.mutateUserStatesNoWrite().put(userId, MutableUserState())
+ }
}
@Test
fun testResetRuntimePermissions_runtimeGranted_getsRevoked() {
val oldFlags = PermissionFlags.RUNTIME_GRANTED
val expectedNewFlags = 0
- testResetRuntimePermissions(oldFlags, expectedNewFlags) {}
+ testResetRuntimePermissions(oldFlags, expectedNewFlags)
}
@Test
fun testResetRuntimePermissions_roleGranted_getsGranted() {
val oldFlags = PermissionFlags.ROLE
val expectedNewFlags = PermissionFlags.ROLE or PermissionFlags.RUNTIME_GRANTED
- testResetRuntimePermissions(oldFlags, expectedNewFlags) {}
+ testResetRuntimePermissions(oldFlags, expectedNewFlags)
}
@Test
fun testResetRuntimePermissions_nullAndroidPackage_remainsUnchanged() {
val oldFlags = PermissionFlags.RUNTIME_GRANTED
val expectedNewFlags = PermissionFlags.RUNTIME_GRANTED
- testResetRuntimePermissions(oldFlags, expectedNewFlags) {
- whenever(packageState0.androidPackage).thenReturn(null)
- }
+ testResetRuntimePermissions(oldFlags, expectedNewFlags, isAndroidPackageMissing = true)
}
- private inline fun testResetRuntimePermissions(
+ private fun testResetRuntimePermissions(
oldFlags: Int,
expectedNewFlags: Int,
- additionalSetup: () -> Unit
+ isAndroidPackageMissing: Boolean = false
) {
- createSystemStatePermission(
- APP_ID_0,
- PACKAGE_NAME_0,
+ val parsedPermission = mockParsedPermission(
PERMISSION_NAME_0,
- PermissionInfo.PROTECTION_DANGEROUS
+ PACKAGE_NAME_0,
+ protectionLevel = PermissionInfo.PROTECTION_DANGEROUS,
)
- androidPackage0.requestedPermissions.add(PERMISSION_NAME_0)
- oldState.mutateUserState(USER_ID_0)!!.mutateAppIdPermissionFlags().mutateOrPut(APP_ID_0) {
- MutableIndexedMap()
- }.put(PERMISSION_NAME_0, oldFlags)
-
- additionalSetup()
+ val permissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(parsedPermission))
+ )
+ val requestingPackageState = if (isAndroidPackageMissing) {
+ mockPackageState(APP_ID_1, PACKAGE_NAME_1)
+ } else {
+ mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
+ )
+ }
+ setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags)
+ addPackageState(permissionOwnerPackageState)
+ addPackageState(requestingPackageState)
+ addPermission(parsedPermission)
mutateState {
with(appIdPermissionPolicy) {
- resetRuntimePermissions(PACKAGE_NAME_0, USER_ID_0)
+ resetRuntimePermissions(PACKAGE_NAME_1, USER_ID_0)
}
}
- val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0)
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
assertWithMessage(
"After resetting runtime permissions, permission flags did not match" +
- " expected values: expectedNewFlags is $expectedNewFlags," +
- " actualFlags is $actualFlags, while the oldFlags is $oldFlags"
+ " expected values: expectedNewFlags is $expectedNewFlags," +
+ " actualFlags is $actualFlags, while the oldFlags is $oldFlags"
)
.that(actualFlags)
.isEqualTo(expectedNewFlags)
@@ -231,285 +206,1499 @@ class AppIdPermissionPolicyTest {
@Test
fun testOnPackageAdded_permissionsOfMissingSystemApp_getsAdopted() {
- testOnPackageAdded {
- adoptPermissionTestSetup()
- whenever(packageState1.androidPackage).thenReturn(null)
- }
+ testAdoptPermissions(hasMissingPackage = true, isSystem = true)
- val permission0 = newState.systemState.permissions[PERMISSION_NAME_0]
assertWithMessage(
"After onPackageAdded() is called for a null adopt permission package," +
- " the permission package name: ${permission0!!.packageName} did not match" +
- " the expected package name: $PACKAGE_NAME_0"
+ " the permission package name: ${getPermission(PERMISSION_NAME_0)?.packageName}" +
+ " did not match the expected package name: $PACKAGE_NAME_0"
)
- .that(permission0.packageName)
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_0)
}
@Test
fun testOnPackageAdded_permissionsOfExistingSystemApp_notAdopted() {
- testOnPackageAdded {
- adoptPermissionTestSetup()
- }
+ testAdoptPermissions(isSystem = true)
- val permission0 = newState.systemState.permissions[PERMISSION_NAME_0]
assertWithMessage(
"After onPackageAdded() is called for a non-null adopt permission" +
- " package, the permission package name: ${permission0!!.packageName} should" +
- " not match the package name: $PACKAGE_NAME_0"
+ " package, the permission package name:" +
+ " ${getPermission(PERMISSION_NAME_0)?.packageName} should not match the" +
+ " package name: $PACKAGE_NAME_0"
)
- .that(permission0.packageName)
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
.isNotEqualTo(PACKAGE_NAME_0)
}
@Test
fun testOnPackageAdded_permissionsOfNonSystemApp_notAdopted() {
- testOnPackageAdded {
- adoptPermissionTestSetup()
- whenever(packageState1.isSystem).thenReturn(false)
- }
+ testAdoptPermissions(hasMissingPackage = true)
- val permission0 = newState.systemState.permissions[PERMISSION_NAME_0]
assertWithMessage(
"After onPackageAdded() is called for a non-system adopt permission" +
- " package, the permission package name: ${permission0!!.packageName} should" +
- " not match the package name: $PACKAGE_NAME_0"
+ " package, the permission package name:" +
+ " ${getPermission(PERMISSION_NAME_0)?.packageName} should not match the" +
+ " package name: $PACKAGE_NAME_0"
)
- .that(permission0.packageName)
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
.isNotEqualTo(PACKAGE_NAME_0)
}
- private fun adoptPermissionTestSetup() {
- createSystemStatePermission(
- APP_ID_1,
- PACKAGE_NAME_1,
- PERMISSION_NAME_0,
- PermissionInfo.PROTECTION_SIGNATURE
- )
- whenever(androidPackage0.adoptPermissions).thenReturn(listOf(PACKAGE_NAME_1))
- whenever(packageState1.isSystem).thenReturn(true)
+ private fun testAdoptPermissions(
+ hasMissingPackage: Boolean = false,
+ isSystem: Boolean = false
+ ) {
+ val parsedPermission = mockParsedPermission(PERMISSION_NAME_0, PACKAGE_NAME_1)
+ val packageToAdoptPermission = if (hasMissingPackage) {
+ mockPackageState(APP_ID_1, PACKAGE_NAME_1, isSystem = isSystem)
+ } else {
+ mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(
+ PACKAGE_NAME_1,
+ permissions = listOf(parsedPermission)
+ ),
+ isSystem = isSystem
+ )
+ }
+ addPackageState(packageToAdoptPermission)
+ addPermission(parsedPermission)
+
+ mutateState {
+ val installedPackage = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ permissions = listOf(defaultPermission),
+ adoptPermissions = listOf(PACKAGE_NAME_1)
+ )
+ )
+ addPackageState(installedPackage, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(installedPackage)
+ }
+ }
}
@Test
fun testOnPackageAdded_newPermissionGroup_getsDeclared() {
- testOnPackageAdded {}
+ mutateState {
+ val packageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ addPackageState(packageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(packageState)
+ }
+ }
assertWithMessage(
"After onPackageAdded() is called when there is no existing" +
- " permission groups, the new permission group $PERMISSION_GROUP_NAME_0 is not added"
+ " permission groups, the new permission group $PERMISSION_GROUP_NAME_0 is not added"
)
- .that(newState.systemState.permissionGroups[PERMISSION_GROUP_NAME_0]?.name)
+ .that(getPermissionGroup(PERMISSION_GROUP_NAME_0)?.name)
.isEqualTo(PERMISSION_GROUP_NAME_0)
}
@Test
fun testOnPackageAdded_systemAppTakingOverPermissionGroupDefinition_getsTakenOver() {
- testOnPackageAdded {
- whenever(packageState0.isSystem).thenReturn(true)
- createSystemStatePermissionGroup(PACKAGE_NAME_1, PERMISSION_GROUP_NAME_0)
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions(newPermissionOwnerIsSystem = true)
assertWithMessage(
"After onPackageAdded() is called when $PERMISSION_GROUP_NAME_0 already" +
- " exists in the system, the system app $PACKAGE_NAME_0 didn't takeover the ownership" +
- " of this permission group"
+ " exists in the system, the system app $PACKAGE_NAME_0 didn't takeover the" +
+ " ownership of this permission group"
)
- .that(newState.systemState.permissionGroups[PERMISSION_GROUP_NAME_0]?.packageName)
+ .that(getPermissionGroup(PERMISSION_GROUP_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_0)
}
@Test
fun testOnPackageAdded_instantApps_remainsUnchanged() {
- testOnPackageAdded {
- (packageState0.userStates as SparseArray<PackageUserState>).apply {
- put(0, mock { whenever(isInstantApp).thenReturn(true) })
- }
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions(
+ newPermissionOwnerIsInstant = true,
+ permissionGroupAlreadyExists = false
+ )
assertWithMessage(
"After onPackageAdded() is called for an instant app," +
- " the new permission group $PERMISSION_GROUP_NAME_0 should not be added"
+ " the new permission group $PERMISSION_GROUP_NAME_0 should not be added"
)
- .that(newState.systemState.permissionGroups[PERMISSION_GROUP_NAME_0])
+ .that(getPermissionGroup(PERMISSION_GROUP_NAME_0))
.isNull()
}
@Test
fun testOnPackageAdded_nonSystemAppTakingOverPermissionGroupDefinition_remainsUnchanged() {
- testOnPackageAdded {
- createSystemStatePermissionGroup(PACKAGE_NAME_1, PERMISSION_GROUP_NAME_0)
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions()
assertWithMessage(
"After onPackageAdded() is called when $PERMISSION_GROUP_NAME_0 already" +
- " exists in the system, non-system app $PACKAGE_NAME_0 shouldn't takeover ownership" +
- " of this permission group"
+ " exists in the system, non-system app $PACKAGE_NAME_0 shouldn't takeover" +
+ " ownership of this permission group"
)
- .that(newState.systemState.permissionGroups[PERMISSION_GROUP_NAME_0]?.packageName)
+ .that(getPermissionGroup(PERMISSION_GROUP_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_1)
}
@Test
fun testOnPackageAdded_takingOverPermissionGroupDeclaredBySystemApp_remainsUnchanged() {
- testOnPackageAdded {
- whenever(packageState1.isSystem).thenReturn(true)
- createSystemStatePermissionGroup(PACKAGE_NAME_1, PERMISSION_GROUP_NAME_0)
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions(oldPermissionOwnerIsSystem = true)
assertWithMessage(
"After onPackageAdded() is called when $PERMISSION_GROUP_NAME_0 already" +
- " exists in the system and is owned by a system app, app $PACKAGE_NAME_0 shouldn't" +
- " takeover ownership of this permission group"
+ " exists in the system and is owned by a system app, app $PACKAGE_NAME_0" +
+ " shouldn't takeover ownership of this permission group"
)
- .that(newState.systemState.permissionGroups[PERMISSION_GROUP_NAME_0]?.packageName)
+ .that(getPermissionGroup(PERMISSION_GROUP_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_1)
}
@Test
fun testOnPackageAdded_newPermission_getsDeclared() {
- testOnPackageAdded {}
+ mutateState {
+ val packageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ addPackageState(packageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(packageState)
+ }
+ }
assertWithMessage(
"After onPackageAdded() is called when there is no existing" +
- " permissions, the new permission $PERMISSION_NAME_0 is not added"
+ " permissions, the new permission $PERMISSION_NAME_0 is not added"
)
- .that(newState.systemState.permissions[PERMISSION_NAME_0]?.name)
+ .that(getPermission(PERMISSION_NAME_0)?.name)
.isEqualTo(PERMISSION_NAME_0)
}
@Test
fun testOnPackageAdded_configPermission_getsTakenOver() {
- testOnPackageAdded {
- whenever(packageState0.isSystem).thenReturn(true)
- createSystemStatePermission(
- APP_ID_0,
- PACKAGE_NAME_1,
- PERMISSION_NAME_0,
- PermissionInfo.PROTECTION_DANGEROUS,
- Permission.TYPE_CONFIG,
- false
- )
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions(
+ oldPermissionOwnerIsSystem = true,
+ newPermissionOwnerIsSystem = true,
+ type = Permission.TYPE_CONFIG,
+ isReconciled = false
+ )
assertWithMessage(
"After onPackageAdded() is called for a config permission with" +
- " no owner, the ownership is not taken over by a system app $PACKAGE_NAME_0"
+ " no owner, the ownership is not taken over by a system app $PACKAGE_NAME_0"
)
- .that(newState.systemState.permissions[PERMISSION_NAME_0]?.packageName)
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_0)
}
@Test
fun testOnPackageAdded_systemAppTakingOverPermissionDefinition_getsTakenOver() {
- testOnPackageAdded {
- whenever(packageState0.isSystem).thenReturn(true)
- createSystemStatePermission(
- APP_ID_1,
- PACKAGE_NAME_1,
- PERMISSION_NAME_0,
- PermissionInfo.PROTECTION_DANGEROUS
- )
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions(newPermissionOwnerIsSystem = true)
assertWithMessage(
"After onPackageAdded() is called when $PERMISSION_NAME_0 already" +
- " exists in the system, the system app $PACKAGE_NAME_0 didn't takeover the ownership" +
- " of this permission"
+ " exists in the system, the system app $PACKAGE_NAME_0 didn't takeover ownership" +
+ " of this permission"
)
- .that(newState.systemState.permissions[PERMISSION_NAME_0]?.packageName)
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_0)
}
@Test
fun testOnPackageAdded_nonSystemAppTakingOverPermissionDefinition_remainsUnchanged() {
- testOnPackageAdded {
- createSystemStatePermission(
- APP_ID_1,
- PACKAGE_NAME_1,
- PERMISSION_NAME_0,
- PermissionInfo.PROTECTION_DANGEROUS
- )
- }
+ testTakingOverPermissionAndPermissionGroupDefinitions()
assertWithMessage(
"After onPackageAdded() is called when $PERMISSION_NAME_0 already" +
- " exists in the system, the non-system app $PACKAGE_NAME_0 shouldn't takeover" +
- " ownership of this permission"
+ " exists in the system, the non-system app $PACKAGE_NAME_0 shouldn't takeover" +
+ " ownership of this permission"
)
- .that(newState.systemState.permissions[PERMISSION_NAME_0]?.packageName)
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
.isEqualTo(PACKAGE_NAME_1)
}
@Test
fun testOnPackageAdded_takingOverPermissionDeclaredBySystemApp_remainsUnchanged() {
- testOnPackageAdded {
- whenever(packageState1.isSystem).thenReturn(true)
- createSystemStatePermission(
- APP_ID_1,
- PACKAGE_NAME_1,
+ testTakingOverPermissionAndPermissionGroupDefinitions(oldPermissionOwnerIsSystem = true)
+
+ assertWithMessage(
+ "After onPackageAdded() is called when $PERMISSION_NAME_0 already" +
+ " exists in system and is owned by a system app, the $PACKAGE_NAME_0 shouldn't" +
+ " takeover ownership of this permission"
+ )
+ .that(getPermission(PERMISSION_NAME_0)?.packageName)
+ .isEqualTo(PACKAGE_NAME_1)
+ }
+
+ private fun testTakingOverPermissionAndPermissionGroupDefinitions(
+ oldPermissionOwnerIsSystem: Boolean = false,
+ newPermissionOwnerIsSystem: Boolean = false,
+ newPermissionOwnerIsInstant: Boolean = false,
+ permissionGroupAlreadyExists: Boolean = true,
+ permissionAlreadyExists: Boolean = true,
+ type: Int = Permission.TYPE_MANIFEST,
+ isReconciled: Boolean = true,
+ ) {
+ val oldPermissionOwnerPackageState = mockPackageState(
+ APP_ID_1,
+ PACKAGE_NAME_1,
+ isSystem = oldPermissionOwnerIsSystem
+ )
+ addPackageState(oldPermissionOwnerPackageState)
+ if (permissionGroupAlreadyExists) {
+ addPermissionGroup(mockParsedPermissionGroup(PERMISSION_GROUP_NAME_0, PACKAGE_NAME_1))
+ }
+ if (permissionAlreadyExists) {
+ addPermission(
+ mockParsedPermission(PERMISSION_NAME_0, PACKAGE_NAME_1),
+ type = type,
+ isReconciled = isReconciled
+ )
+ }
+
+ mutateState {
+ val newPermissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockSimpleAndroidPackage(),
+ isSystem = newPermissionOwnerIsSystem,
+ isInstantApp = newPermissionOwnerIsInstant
+ )
+ addPackageState(newPermissionOwnerPackageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(newPermissionOwnerPackageState)
+ }
+ }
+ }
+
+ @Test
+ fun testOnPackageAdded_permissionGroupChanged_getsRevoked() {
+ testPermissionChanged(
+ oldPermissionGroup = PERMISSION_GROUP_NAME_1,
+ newPermissionGroup = PERMISSION_GROUP_NAME_0
+ )
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that has a permission group change" +
+ " for a permission it defines, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_protectionLevelChanged_getsRevoked() {
+ testPermissionChanged(newProtectionLevel = PermissionInfo.PROTECTION_INTERNAL)
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that has a protection level change" +
+ " for a permission it defines, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ private fun testPermissionChanged(
+ oldPermissionGroup: String? = null,
+ newPermissionGroup: String? = null,
+ newProtectionLevel: Int = PermissionInfo.PROTECTION_DANGEROUS
+ ) {
+ val oldPermission = mockParsedPermission(
+ PERMISSION_NAME_0,
+ PACKAGE_NAME_0,
+ group = oldPermissionGroup,
+ protectionLevel = PermissionInfo.PROTECTION_DANGEROUS
+ )
+ val oldPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(oldPermission))
+ )
+ addPackageState(oldPackageState)
+ addPermission(oldPermission)
+ setPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0, PermissionFlags.RUNTIME_GRANTED)
+
+ mutateState {
+ val newPermission = mockParsedPermission(
PERMISSION_NAME_0,
- PermissionInfo.PROTECTION_DANGEROUS
+ PACKAGE_NAME_0,
+ group = newPermissionGroup,
+ protectionLevel = newProtectionLevel
+ )
+ val newPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(newPermission))
)
+ addPackageState(newPackageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(newPackageState)
+ }
}
+ }
+
+ @Test
+ fun testOnPackageAdded_permissionTreeNoLongerDeclared_getsDefinitionRemoved() {
+ testPermissionDeclaration {}
assertWithMessage(
- "After onPackageAdded() is called when $PERMISSION_NAME_0 already" +
- " exists in system and is owned by a system app, the app $PACKAGE_NAME_0 shouldn't" +
- " takeover ownership of this permission"
+ "After onPackageAdded() is called for a package that no longer defines a permission" +
+ " tree, the permission tree: $PERMISSION_NAME_0 in system state should be removed"
)
- .that(newState.systemState.permissions[PERMISSION_NAME_0]?.packageName)
- .isEqualTo(PACKAGE_NAME_1)
+ .that(getPermissionTree(PERMISSION_NAME_0))
+ .isNull()
+ }
+
+ @Test
+ fun testOnPackageAdded_permissionTreeByDisabledSystemPackage_remainsUnchanged() {
+ testPermissionDeclaration {
+ val disabledSystemPackageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ addDisabledSystemPackageState(disabledSystemPackageState)
+ }
+
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that no longer defines" +
+ " a permission tree while this permission tree is still defined by" +
+ " a disabled system package, the permission tree: $PERMISSION_NAME_0 in" +
+ " system state should not be removed"
+ )
+ .that(getPermissionTree(PERMISSION_TREE_NAME))
+ .isNotNull()
+ }
+
+ @Test
+ fun testOnPackageAdded_permissionNoLongerDeclared_getsDefinitionRemoved() {
+ testPermissionDeclaration {}
+
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that no longer defines a permission," +
+ " the permission: $PERMISSION_NAME_0 in system state should be removed"
+ )
+ .that(getPermission(PERMISSION_NAME_0))
+ .isNull()
+ }
+
+ @Test
+ fun testOnPackageAdded_permissionByDisabledSystemPackage_remainsUnchanged() {
+ testPermissionDeclaration {
+ val disabledSystemPackageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ addDisabledSystemPackageState(disabledSystemPackageState)
+ }
+
+ assertWithMessage(
+ "After onPackageAdded() is called for a disabled system package and it's updated apk" +
+ " no longer defines a permission, the permission: $PERMISSION_NAME_0 in" +
+ " system state should not be removed"
+ )
+ .that(getPermission(PERMISSION_NAME_0))
+ .isNotNull()
+ }
+
+ private fun testPermissionDeclaration(additionalSetup: () -> Unit) {
+ val oldPackageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ addPackageState(oldPackageState)
+ addPermission(defaultPermissionTree)
+ addPermission(defaultPermission)
+
+ additionalSetup()
+
+ mutateState {
+ val newPackageState = mockPackageState(APP_ID_0, mockAndroidPackage(PACKAGE_NAME_0))
+ addPackageState(newPackageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(newPackageState)
+ }
+ }
+ }
+
+ @Test
+ fun testOnPackageAdded_permissionsNoLongerRequested_getsFlagsRevoked() {
+ val parsedPermission = mockParsedPermission(
+ PERMISSION_NAME_0,
+ PACKAGE_NAME_0,
+ protectionLevel = PermissionInfo.PROTECTION_DANGEROUS
+ )
+ val oldPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ permissions = listOf(parsedPermission),
+ requestedPermissions = setOf(PERMISSION_NAME_0)
+ )
+ )
+ addPackageState(oldPackageState)
+ addPermission(parsedPermission)
+ setPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0, PermissionFlags.RUNTIME_GRANTED)
+
+ mutateState {
+ val newPackageState = mockPackageState(APP_ID_0, mockSimpleAndroidPackage())
+ addPackageState(newPackageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(newPackageState)
+ }
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that no longer requests a permission" +
+ " the actual permission flags $actualFlags should match the" +
+ " expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_storageAndMediaPermissionsDowngradingPastQ_getsRuntimeRevoked() {
+ testRevokePermissionsOnPackageUpdate(
+ PermissionFlags.RUNTIME_GRANTED,
+ newTargetSdkVersion = Build.VERSION_CODES.P
+ )
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_READ_EXTERNAL_STORAGE)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that's downgrading past Q" +
+ " the actual permission flags $actualFlags should match the" +
+ " expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_storageAndMediaPermissionsNotDowngradingPastQ_remainsUnchanged() {
+ val oldFlags = PermissionFlags.RUNTIME_GRANTED
+ testRevokePermissionsOnPackageUpdate(
+ oldFlags,
+ oldTargetSdkVersion = Build.VERSION_CODES.P,
+ newTargetSdkVersion = Build.VERSION_CODES.P
+ )
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_READ_EXTERNAL_STORAGE)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that's not downgrading past Q" +
+ " the actual permission flags $actualFlags should match the" +
+ " expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
}
- private inline fun testOnPackageAdded(mockBehaviorOverride: () -> Unit) {
- mockBehaviorOverride()
+ @Test
+ fun testOnPackageAdded_policyFixedDowngradingPastQ_remainsUnchanged() {
+ val oldFlags = PermissionFlags.RUNTIME_GRANTED and PermissionFlags.POLICY_FIXED
+ testRevokePermissionsOnPackageUpdate(oldFlags, newTargetSdkVersion = Build.VERSION_CODES.P)
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_READ_EXTERNAL_STORAGE)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that's downgrading past Q" +
+ " the actual permission flags with PermissionFlags.POLICY_FIXED $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_newlyRequestingLegacyExternalStorage_getsRuntimeRevoked() {
+ testRevokePermissionsOnPackageUpdate(
+ PermissionFlags.RUNTIME_GRANTED,
+ oldTargetSdkVersion = Build.VERSION_CODES.P,
+ newTargetSdkVersion = Build.VERSION_CODES.P,
+ oldIsRequestLegacyExternalStorage = false
+ )
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_READ_EXTERNAL_STORAGE)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package with" +
+ " newlyRequestingLegacyExternalStorage, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_missingOldPackage_remainsUnchanged() {
+ val oldFlags = PermissionFlags.RUNTIME_GRANTED
+ testRevokePermissionsOnPackageUpdate(
+ oldFlags,
+ newTargetSdkVersion = Build.VERSION_CODES.P,
+ isOldPackageMissing = true
+ )
+
+ val actualFlags = getPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_READ_EXTERNAL_STORAGE)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that's downgrading past Q" +
+ " and doesn't have the oldPackage, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ private fun testRevokePermissionsOnPackageUpdate(
+ oldFlags: Int,
+ oldTargetSdkVersion: Int = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ newTargetSdkVersion: Int = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ oldIsRequestLegacyExternalStorage: Boolean = true,
+ newIsRequestLegacyExternalStorage: Boolean = true,
+ isOldPackageMissing: Boolean = false
+ ) {
+ val parsedPermission = mockParsedPermission(
+ PERMISSION_READ_EXTERNAL_STORAGE,
+ PACKAGE_NAME_0,
+ protectionLevel = PermissionInfo.PROTECTION_DANGEROUS
+ )
+ val oldPackageState = if (isOldPackageMissing) {
+ mockPackageState(APP_ID_0, PACKAGE_NAME_0)
+ } else {
+ mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ targetSdkVersion = oldTargetSdkVersion,
+ isRequestLegacyExternalStorage = oldIsRequestLegacyExternalStorage,
+ requestedPermissions = setOf(PERMISSION_READ_EXTERNAL_STORAGE),
+ permissions = listOf(parsedPermission)
+ )
+ )
+ }
+ addPackageState(oldPackageState)
+ addPermission(parsedPermission)
+ setPermissionFlags(APP_ID_0, USER_ID_0, PERMISSION_READ_EXTERNAL_STORAGE, oldFlags)
mutateState {
+ val newPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ targetSdkVersion = newTargetSdkVersion,
+ isRequestLegacyExternalStorage = newIsRequestLegacyExternalStorage,
+ requestedPermissions = setOf(PERMISSION_READ_EXTERNAL_STORAGE),
+ permissions = listOf(parsedPermission)
+ )
+ )
+ addPackageState(newPackageState, newState)
with(appIdPermissionPolicy) {
- onPackageAdded(packageState0)
+ onPackageAdded(newPackageState)
}
}
}
+ @Test
+ fun testOnPackageAdded_normalPermissionAlreadyGranted_remainsUnchanged() {
+ val oldFlags = PermissionFlags.INSTALL_GRANTED or PermissionFlags.INSTALL_REVOKED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_NORMAL) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a normal permission" +
+ " with an existing INSTALL_GRANTED flag, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_normalPermissionNotInstallRevoked_getsGranted() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_NORMAL,
+ isNewInstall = true
+ ) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.INSTALL_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a normal permission" +
+ " with no existing flags, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_normalPermissionRequestedByInstalledPackage_getsGranted() {
+ val oldFlags = PermissionFlags.INSTALL_REVOKED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_NORMAL) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.INSTALL_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a normal permission" +
+ " with the INSTALL_REVOKED flag, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags since it's a new install"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ /**
+ * We setup a permission protection level change from SIGNATURE to NORMAL in order to make
+ * the permission a "changed permission" in order to test evaluatePermissionState() called by
+ * evaluatePermissionStateForAllPackages(). This makes the requestingPackageState not the
+ * installedPackageState so that we can test whether requesting by system package will give us
+ * the expected permission flags.
+ *
+ * Besides, this also helps us test evaluatePermissionStateForAllPackages(). Since both
+ * evaluatePermissionStateForAllPackages() and evaluateAllPermissionStatesForPackage() call
+ * evaluatePermissionState() in their implementations, we use these tests as the only tests
+ * that test evaluatePermissionStateForAllPackages()
+ */
+ @Test
+ fun testOnPackageAdded_normalPermissionRequestedBySystemPackage_getsGranted() {
+ testEvaluateNormalPermissionStateWithPermissionChanges(requestingPackageIsSystem = true)
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.INSTALL_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a system package that requests a normal" +
+ " permission with INSTALL_REVOKED flag, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_normalCompatibilityPermission_getsGranted() {
+ testEvaluateNormalPermissionStateWithPermissionChanges(
+ permissionName = PERMISSION_POST_NOTIFICATIONS,
+ requestingPackageTargetSdkVersion = Build.VERSION_CODES.S
+ )
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_POST_NOTIFICATIONS)
+ val expectedNewFlags = PermissionFlags.INSTALL_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a normal compatibility" +
+ " permission with INSTALL_REVOKED flag, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_normalPermissionPreviouslyRevoked_getsInstallRevoked() {
+ testEvaluateNormalPermissionStateWithPermissionChanges()
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.INSTALL_REVOKED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a normal" +
+ " permission with INSTALL_REVOKED flag, the actual permission flags $actualFlags" +
+ " should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ private fun testEvaluateNormalPermissionStateWithPermissionChanges(
+ permissionName: String = PERMISSION_NAME_0,
+ requestingPackageTargetSdkVersion: Int = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ requestingPackageIsSystem: Boolean = false
+ ) {
+ val oldParsedPermission = mockParsedPermission(
+ permissionName,
+ PACKAGE_NAME_0,
+ protectionLevel = PermissionInfo.PROTECTION_SIGNATURE
+ )
+ val oldPermissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(oldParsedPermission))
+ )
+ val requestingPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(
+ PACKAGE_NAME_1,
+ requestedPermissions = setOf(permissionName),
+ targetSdkVersion = requestingPackageTargetSdkVersion
+ ),
+ isSystem = requestingPackageIsSystem,
+ )
+ addPackageState(oldPermissionOwnerPackageState)
+ addPackageState(requestingPackageState)
+ addPermission(oldParsedPermission)
+ val oldFlags = PermissionFlags.INSTALL_REVOKED
+ setPermissionFlags(APP_ID_1, USER_ID_0, permissionName, oldFlags)
+
+ mutateState {
+ val newPermissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ permissions = listOf(mockParsedPermission(permissionName, PACKAGE_NAME_0))
+ )
+ )
+ addPackageState(newPermissionOwnerPackageState, newState)
+ with(appIdPermissionPolicy) {
+ onPackageAdded(newPermissionOwnerPackageState)
+ }
+ }
+ }
+
+ @Test
+ fun testOnPackageAdded_normalAppOpPermission_getsRoleAndUserSetFlagsPreserved() {
+ val oldFlags = PermissionFlags.ROLE or PermissionFlags.USER_SET
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_NORMAL or PermissionInfo.PROTECTION_FLAG_APPOP
+ ) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.INSTALL_GRANTED or oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a normal app op" +
+ " permission with existing ROLE and USER_SET flags, the actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_internalPermissionWasGrantedWithMissingPackage_getsProtectionGranted() {
+ val oldFlags = PermissionFlags.PROTECTION_GRANTED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_INTERNAL) {
+ val packageStateWithMissingPackage = mockPackageState(APP_ID_1, MISSING_ANDROID_PACKAGE)
+ addPackageState(packageStateWithMissingPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests an internal permission" +
+ " with missing android package and $oldFlags flag, the actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_internalAppOpPermission_getsRoleAndUserSetFlagsPreserved() {
+ val oldFlags = PermissionFlags.PROTECTION_GRANTED or PermissionFlags.ROLE or
+ PermissionFlags.USER_SET
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_INTERNAL or PermissionInfo.PROTECTION_FLAG_APPOP
+ ) {
+ val packageStateWithMissingPackage = mockPackageState(APP_ID_1, MISSING_ANDROID_PACKAGE)
+ addPackageState(packageStateWithMissingPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests an internal permission" +
+ " with missing android package and $oldFlags flag and the permission isAppOp," +
+ " the actual permission flags $actualFlags should match the expected" +
+ " flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_internalDevelopmentPermission_getsRuntimeGrantedPreserved() {
+ val oldFlags = PermissionFlags.PROTECTION_GRANTED or PermissionFlags.RUNTIME_GRANTED
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_INTERNAL or PermissionInfo.PROTECTION_FLAG_DEVELOPMENT
+ ) {
+ val packageStateWithMissingPackage = mockPackageState(APP_ID_1, MISSING_ANDROID_PACKAGE)
+ addPackageState(packageStateWithMissingPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests an internal permission" +
+ " with missing android package and $oldFlags flag and permission isDevelopment," +
+ " the actual permission flags $actualFlags should match the expected" +
+ " flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_internalRolePermission_getsRoleAndRuntimeGrantedPreserved() {
+ val oldFlags = PermissionFlags.PROTECTION_GRANTED or PermissionFlags.ROLE or
+ PermissionFlags.RUNTIME_GRANTED
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_INTERNAL or PermissionInfo.PROTECTION_FLAG_ROLE
+ ) {
+ val packageStateWithMissingPackage = mockPackageState(APP_ID_1, MISSING_ANDROID_PACKAGE)
+ addPackageState(packageStateWithMissingPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests an internal permission" +
+ " with missing android package and $oldFlags flag and the permission isRole," +
+ " the actual permission flags $actualFlags should match the expected" +
+ " flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_signaturePrivilegedPermissionNotAllowlisted_isNotGranted() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_SIGNATURE or PermissionInfo.PROTECTION_FLAG_PRIVILEGED,
+ isInstalledPackageSystem = true,
+ isInstalledPackagePrivileged = true,
+ isInstalledPackageProduct = true,
+ // To mock the return value of shouldGrantPrivilegedOrOemPermission()
+ isInstalledPackageVendor = true,
+ isNewInstall = true
+ ) {
+ val platformPackage = mockPackageState(
+ PLATFORM_APP_ID,
+ mockAndroidPackage(PLATFORM_PACKAGE_NAME)
+ )
+ setupAllowlist(PACKAGE_NAME_1, false)
+ addPackageState(platformPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a signature privileged" +
+ " permission that's not allowlisted, the actual permission" +
+ " flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_nonPrivilegedPermissionShouldGrantBySignature_getsProtectionGranted() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_SIGNATURE,
+ isInstalledPackageSystem = true,
+ isInstalledPackagePrivileged = true,
+ isInstalledPackageProduct = true,
+ isInstalledPackageSignatureMatching = true,
+ isInstalledPackageVendor = true,
+ isNewInstall = true
+ ) {
+ val platformPackage = mockPackageState(
+ PLATFORM_APP_ID,
+ mockAndroidPackage(PLATFORM_PACKAGE_NAME, isSignatureMatching = true)
+ )
+ setupAllowlist(PACKAGE_NAME_1, false)
+ addPackageState(platformPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.PROTECTION_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a signature" +
+ " non-privileged permission, the actual permission" +
+ " flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_privilegedAllowlistPermissionShouldGrantByProtectionFlags_getsGranted() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_SIGNATURE or PermissionInfo.PROTECTION_FLAG_PRIVILEGED,
+ isInstalledPackageSystem = true,
+ isInstalledPackagePrivileged = true,
+ isInstalledPackageProduct = true,
+ isNewInstall = true
+ ) {
+ val platformPackage = mockPackageState(
+ PLATFORM_APP_ID,
+ mockAndroidPackage(PLATFORM_PACKAGE_NAME)
+ )
+ setupAllowlist(PACKAGE_NAME_1, true)
+ addPackageState(platformPackage)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.PROTECTION_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a signature privileged" +
+ " permission that's allowlisted and should grant by protection flags, the actual" +
+ " permission flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ private fun setupAllowlist(
+ packageName: String,
+ allowlistState: Boolean,
+ state: MutableAccessState = oldState
+ ) {
+ state.mutateExternalState().setPrivilegedPermissionAllowlistPackages(
+ MutableIndexedListSet<String>().apply { add(packageName) }
+ )
+ val mockAllowlist = mock<PermissionAllowlist> {
+ whenever(
+ getProductPrivilegedAppAllowlistState(packageName, PERMISSION_NAME_0)
+ ).thenReturn(allowlistState)
+ }
+ state.mutateExternalState().setPermissionAllowlist(mockAllowlist)
+ }
+
+ @Test
+ fun testOnPackageAdded_nonRuntimeFlagsOnRuntimePermissions_getsCleared() {
+ val oldFlags = PermissionFlags.INSTALL_GRANTED or PermissionFlags.PREGRANT or
+ PermissionFlags.RUNTIME_GRANTED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_DANGEROUS) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.PREGRANT or PermissionFlags.RUNTIME_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " with existing $oldFlags flags, the actual permission flags $actualFlags should" +
+ " match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_newPermissionsForPreM_requiresUserReview() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ installedPackageTargetSdkVersion = Build.VERSION_CODES.LOLLIPOP,
+ isNewInstall = true
+ ) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.LEGACY_GRANTED or PermissionFlags.IMPLICIT
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " with no existing flags in pre M, actual permission flags $actualFlags should" +
+ " match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_legacyOrImplicitGrantedPermissionPreviouslyRevoked_getsAppOpRevoked() {
+ val oldFlags = PermissionFlags.USER_FIXED
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ installedPackageTargetSdkVersion = Build.VERSION_CODES.LOLLIPOP
+ ) {
+ setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.LEGACY_GRANTED or PermissionFlags.USER_FIXED or
+ PermissionFlags.APP_OP_REVOKED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " that should be LEGACY_GRANTED or IMPLICIT_GRANTED that was previously revoked," +
+ " the actual permission flags $actualFlags should" +
+ " match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_legacyGrantedPermissionsForPostM_userReviewRequirementRemoved() {
+ val oldFlags = PermissionFlags.LEGACY_GRANTED or PermissionFlags.IMPLICIT
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_DANGEROUS) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " that used to require user review, the user review requirement should be removed" +
+ " if it's upgraded to post M. The actual permission flags $actualFlags should" +
+ " match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_legacyGrantedPermissionsAlreadyReviewedForPostM_getsGranted() {
+ val oldFlags = PermissionFlags.LEGACY_GRANTED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_DANGEROUS) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.RUNTIME_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " that was already reviewed by the user, the permission should be RUNTIME_GRANTED" +
+ " if it's upgraded to post M. The actual permission flags $actualFlags should" +
+ " match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_leanbackNotificationPermissionsForPostM_getsImplicitGranted() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ permissionName = PERMISSION_POST_NOTIFICATIONS,
+ isNewInstall = true
+ ) {
+ oldState.mutateExternalState().setLeanback(true)
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_POST_NOTIFICATIONS)
+ val expectedNewFlags = PermissionFlags.IMPLICIT_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime notification" +
+ " permission when isLeanback, the actual permission flags $actualFlags should" +
+ " match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_implicitSourceFromNonRuntime_getsImplicitGranted() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ implicitPermissions = setOf(PERMISSION_NAME_0),
+ isNewInstall = true
+ ) {
+ oldState.mutateExternalState().setImplicitToSourcePermissions(
+ MutableIndexedMap<String, IndexedListSet<String>>().apply {
+ put(PERMISSION_NAME_0, MutableIndexedListSet<String>().apply {
+ add(PERMISSION_NAME_1)
+ })
+ }
+ )
+ addPermission(mockParsedPermission(PERMISSION_NAME_1, PACKAGE_NAME_0))
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.IMPLICIT_GRANTED or PermissionFlags.IMPLICIT
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime implicit" +
+ " permission that's source from a non-runtime permission, the actual permission" +
+ " flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ /**
+ * For a legacy granted or implicit permission during the app upgrade, when the permission
+ * should no longer be legacy or implicit granted, we want to remove the APP_OP_REVOKED flag
+ * so that the app can request the permission.
+ */
+ @Test
+ fun testOnPackageAdded_noLongerLegacyOrImplicitGranted_canBeRequested() {
+ val oldFlags = PermissionFlags.LEGACY_GRANTED or PermissionFlags.APP_OP_REVOKED or
+ PermissionFlags.RUNTIME_GRANTED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_DANGEROUS) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " that is no longer LEGACY_GRANTED or IMPLICIT_GRANTED, the actual permission" +
+ " flags $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_noLongerImplicitPermissions_getsRuntimeAndImplicitFlagsRemoved() {
+ val oldFlags = PermissionFlags.IMPLICIT or PermissionFlags.RUNTIME_GRANTED or
+ PermissionFlags.USER_SET or PermissionFlags.USER_FIXED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_DANGEROUS) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = 0
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " that is no longer implicit and we shouldn't retain as nearby device" +
+ " permissions, the actual permission flags $actualFlags should match the expected" +
+ " flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_noLongerImplicitNearbyPermissionsWasGranted_getsRuntimeGranted() {
+ val oldFlags = PermissionFlags.IMPLICIT_GRANTED or PermissionFlags.IMPLICIT
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ permissionName = PERMISSION_BLUETOOTH_CONNECT,
+ requestedPermissions = setOf(
+ PERMISSION_BLUETOOTH_CONNECT,
+ PERMISSION_ACCESS_BACKGROUND_LOCATION
+ )
+ ) {
+ setPermissionFlags(
+ APP_ID_1,
+ USER_ID_0,
+ PERMISSION_ACCESS_BACKGROUND_LOCATION,
+ PermissionFlags.RUNTIME_GRANTED
+ )
+ }
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_BLUETOOTH_CONNECT)
+ val expectedNewFlags = PermissionFlags.RUNTIME_GRANTED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime nearby device" +
+ " permission that was granted by implicit, the actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_noLongerImplicitSystemOrPolicyFixedWasGranted_getsRuntimeGranted() {
+ val oldFlags = PermissionFlags.IMPLICIT_GRANTED or PermissionFlags.IMPLICIT or
+ PermissionFlags.SYSTEM_FIXED
+ testEvaluatePermissionState(oldFlags, PermissionInfo.PROTECTION_DANGEROUS) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.RUNTIME_GRANTED or PermissionFlags.SYSTEM_FIXED
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime permission" +
+ " that was granted and is no longer implicit and is SYSTEM_FIXED or POLICY_FIXED," +
+ " the actual permission flags $actualFlags should match the expected" +
+ " flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_restrictedPermissionsNotExempt_getsRestrictionFlags() {
+ val oldFlags = PermissionFlags.RESTRICTION_REVOKED
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ permissionInfoFlags = PermissionInfo.FLAG_HARD_RESTRICTED
+ ) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = oldFlags
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime hard" +
+ " restricted permission that is not exempted, the actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ @Test
+ fun testOnPackageAdded_restrictedPermissionsIsExempted_clearsRestrictionFlags() {
+ val oldFlags = 0
+ testEvaluatePermissionState(
+ oldFlags,
+ PermissionInfo.PROTECTION_DANGEROUS,
+ permissionInfoFlags = PermissionInfo.FLAG_SOFT_RESTRICTED
+ ) {}
+
+ val actualFlags = getPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0)
+ val expectedNewFlags = PermissionFlags.UPGRADE_EXEMPT
+ assertWithMessage(
+ "After onPackageAdded() is called for a package that requests a runtime soft" +
+ " restricted permission that is exempted, the actual permission flags" +
+ " $actualFlags should match the expected flags $expectedNewFlags"
+ )
+ .that(actualFlags)
+ .isEqualTo(expectedNewFlags)
+ }
+
+ /**
+ * Setup simple package states for testing evaluatePermissionState().
+ * permissionOwnerPackageState is definer of permissionName with APP_ID_0.
+ * installedPackageState is the installed package that requests permissionName with APP_ID_1.
+ *
+ * @param oldFlags the existing permission flags for APP_ID_1, USER_ID_0, permissionName
+ * @param protectionLevel the protectionLevel for the permission
+ * @param permissionName the name of the permission (1) being defined (2) of the oldFlags, and
+ * (3) requested by installedPackageState
+ * @param requestedPermissions the permissions requested by installedPackageState
+ * @param implicitPermissions the implicit permissions of installedPackageState
+ * @param permissionInfoFlags the flags for the permission itself
+ * @param isInstalledPackageSystem whether installedPackageState is a system package
+ *
+ * @return installedPackageState
+ */
+ fun testEvaluatePermissionState(
+ oldFlags: Int,
+ protectionLevel: Int,
+ permissionName: String = PERMISSION_NAME_0,
+ requestedPermissions: Set<String> = setOf(permissionName),
+ implicitPermissions: Set<String> = emptySet(),
+ permissionInfoFlags: Int = 0,
+ isInstalledPackageSystem: Boolean = false,
+ isInstalledPackagePrivileged: Boolean = false,
+ isInstalledPackageProduct: Boolean = false,
+ isInstalledPackageSignatureMatching: Boolean = false,
+ isInstalledPackageVendor: Boolean = false,
+ installedPackageTargetSdkVersion: Int = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ isNewInstall: Boolean = false,
+ additionalSetup: () -> Unit
+ ) {
+ val parsedPermission = mockParsedPermission(
+ permissionName,
+ PACKAGE_NAME_0,
+ protectionLevel = protectionLevel,
+ flags = permissionInfoFlags
+ )
+ val permissionOwnerPackageState = mockPackageState(
+ APP_ID_0,
+ mockAndroidPackage(PACKAGE_NAME_0, permissions = listOf(parsedPermission))
+ )
+ val installedPackageState = mockPackageState(
+ APP_ID_1,
+ mockAndroidPackage(
+ PACKAGE_NAME_1,
+ requestedPermissions = requestedPermissions,
+ implicitPermissions = implicitPermissions,
+ targetSdkVersion = installedPackageTargetSdkVersion,
+ isSignatureMatching = isInstalledPackageSignatureMatching
+ ),
+ isSystem = isInstalledPackageSystem,
+ isPrivileged = isInstalledPackagePrivileged,
+ isProduct = isInstalledPackageProduct,
+ isVendor = isInstalledPackageVendor
+ )
+ addPackageState(permissionOwnerPackageState)
+ if (!isNewInstall) {
+ addPackageState(installedPackageState)
+ setPermissionFlags(APP_ID_1, USER_ID_0, permissionName, oldFlags)
+ }
+ addPermission(parsedPermission)
+
+ additionalSetup()
+
+ mutateState {
+ if (isNewInstall) {
+ addPackageState(installedPackageState, newState)
+ setPermissionFlags(APP_ID_1, USER_ID_0, permissionName, oldFlags, newState)
+ }
+ with(appIdPermissionPolicy) {
+ onPackageAdded(installedPackageState)
+ }
+ }
+ }
+
+ /**
+ * Mock an AndroidPackage with PACKAGE_NAME_0, PERMISSION_NAME_0 and PERMISSION_GROUP_NAME_0
+ */
+ private fun mockSimpleAndroidPackage(): AndroidPackage =
+ mockAndroidPackage(
+ PACKAGE_NAME_0,
+ permissionGroups = listOf(defaultPermissionGroup),
+ permissions = listOf(defaultPermissionTree, defaultPermission)
+ )
+
private inline fun mutateState(action: MutateStateScope.() -> Unit) {
newState = oldState.toMutable()
MutateStateScope(oldState, newState).action()
}
- private fun createSystemStatePermission(
+ private fun mockPackageState(
appId: Int,
packageName: String,
+ isSystem: Boolean = false,
+ ): PackageState =
+ mock {
+ whenever(this.appId).thenReturn(appId)
+ whenever(this.packageName).thenReturn(packageName)
+ whenever(androidPackage).thenReturn(null)
+ whenever(this.isSystem).thenReturn(isSystem)
+ }
+
+ private fun mockPackageState(
+ appId: Int,
+ androidPackage: AndroidPackage,
+ isSystem: Boolean = false,
+ isPrivileged: Boolean = false,
+ isProduct: Boolean = false,
+ isInstantApp: Boolean = false,
+ isVendor: Boolean = false
+ ): PackageState =
+ mock {
+ whenever(this.appId).thenReturn(appId)
+ whenever(this.androidPackage).thenReturn(androidPackage)
+ val packageName = androidPackage.packageName
+ whenever(this.packageName).thenReturn(packageName)
+ whenever(this.isSystem).thenReturn(isSystem)
+ whenever(this.isPrivileged).thenReturn(isPrivileged)
+ whenever(this.isProduct).thenReturn(isProduct)
+ whenever(this.isVendor).thenReturn(isVendor)
+ val userStates = SparseArray<PackageUserState>().apply {
+ put(USER_ID_0, mock { whenever(this.isInstantApp).thenReturn(isInstantApp) })
+ }
+ whenever(this.userStates).thenReturn(userStates)
+ }
+
+ private fun mockAndroidPackage(
+ packageName: String,
+ targetSdkVersion: Int = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ isRequestLegacyExternalStorage: Boolean = false,
+ adoptPermissions: List<String> = emptyList(),
+ implicitPermissions: Set<String> = emptySet(),
+ requestedPermissions: Set<String> = emptySet(),
+ permissionGroups: List<ParsedPermissionGroup> = emptyList(),
+ permissions: List<ParsedPermission> = emptyList(),
+ isSignatureMatching: Boolean = false
+ ): AndroidPackage =
+ mock {
+ whenever(this.packageName).thenReturn(packageName)
+ whenever(this.targetSdkVersion).thenReturn(targetSdkVersion)
+ whenever(this.isRequestLegacyExternalStorage).thenReturn(isRequestLegacyExternalStorage)
+ whenever(this.adoptPermissions).thenReturn(adoptPermissions)
+ whenever(this.implicitPermissions).thenReturn(implicitPermissions)
+ whenever(this.requestedPermissions).thenReturn(requestedPermissions)
+ whenever(this.permissionGroups).thenReturn(permissionGroups)
+ whenever(this.permissions).thenReturn(permissions)
+ val signingDetails = mock<SigningDetails> {
+ whenever(
+ hasCommonSignerWithCapability(any(), any())
+ ).thenReturn(isSignatureMatching)
+ whenever(hasAncestorOrSelf(any())).thenReturn(isSignatureMatching)
+ whenever(
+ checkCapability(any<SigningDetails>(), any())
+ ).thenReturn(isSignatureMatching)
+ }
+ whenever(this.signingDetails).thenReturn(signingDetails)
+ }
+
+ private fun mockParsedPermission(
permissionName: String,
- protectionLevel: Int,
+ packageName: String,
+ backgroundPermission: String? = null,
+ group: String? = null,
+ protectionLevel: Int = PermissionInfo.PROTECTION_NORMAL,
+ flags: Int = 0,
+ isTree: Boolean = false
+ ): ParsedPermission =
+ mock {
+ whenever(name).thenReturn(permissionName)
+ whenever(this.packageName).thenReturn(packageName)
+ whenever(metaData).thenReturn(Bundle())
+ whenever(this.backgroundPermission).thenReturn(backgroundPermission)
+ whenever(this.group).thenReturn(group)
+ whenever(this.protectionLevel).thenReturn(protectionLevel)
+ whenever(this.flags).thenReturn(flags)
+ whenever(this.isTree).thenReturn(isTree)
+ }
+
+ private fun mockParsedPermissionGroup(
+ permissionGroupName: String,
+ packageName: String,
+ ): ParsedPermissionGroup =
+ mock {
+ whenever(name).thenReturn(permissionGroupName)
+ whenever(this.packageName).thenReturn(packageName)
+ whenever(metaData).thenReturn(Bundle())
+ }
+
+ private fun addPackageState(packageState: PackageState, state: MutableAccessState = oldState) {
+ state.mutateExternalState().apply {
+ setPackageStates(
+ packageStates.toMutableMap().apply {
+ put(packageState.packageName, packageState)
+ }
+ )
+ mutateAppIdPackageNames().mutateOrPut(packageState.appId) { MutableIndexedListSet() }
+ .add(packageState.packageName)
+ }
+ }
+
+ private fun addDisabledSystemPackageState(
+ packageState: PackageState,
+ state: MutableAccessState = oldState
+ ) = state.mutateExternalState().apply {
+ (disabledSystemPackageStates as ArrayMap)[packageState.packageName] = packageState
+ }
+
+ private fun addPermission(
+ parsedPermission: ParsedPermission,
type: Int = Permission.TYPE_MANIFEST,
isReconciled: Boolean = true,
- isTree: Boolean = false
+ state: MutableAccessState = oldState
) {
- @Suppress("DEPRECATION")
- val permissionInfo = PermissionInfo().apply {
- name = permissionName
- this.packageName = packageName
- this.protectionLevel = protectionLevel
- }
+ val permissionInfo = PackageInfoUtils.generatePermissionInfo(
+ parsedPermission,
+ PackageManager.GET_META_DATA.toLong()
+ )!!
+ val appId = state.externalState.packageStates[permissionInfo.packageName]!!.appId
val permission = Permission(permissionInfo, isReconciled, type, appId)
- if (isTree) {
- oldState.mutateSystemState().mutatePermissionTrees().put(permissionName, permission)
+ if (parsedPermission.isTree) {
+ state.mutateSystemState().mutatePermissionTrees()[permission.name] = permission
} else {
- oldState.mutateSystemState().mutatePermissions().put(permissionName, permission)
+ state.mutateSystemState().mutatePermissions()[permission.name] = permission
}
}
- private fun createSystemStatePermissionGroup(packageName: String, permissionGroupName: String) {
- @Suppress("DEPRECATION")
- val permissionGroupInfo = PermissionGroupInfo().apply {
- name = permissionGroupName
- this.packageName = packageName
- }
- oldState.mutateSystemState().mutatePermissionGroups()[permissionGroupName] =
- permissionGroupInfo
+ private fun addPermissionGroup(
+ parsedPermissionGroup: ParsedPermissionGroup,
+ state: MutableAccessState = oldState
+ ) {
+ state.mutateSystemState().mutatePermissionGroups()[parsedPermissionGroup.name] =
+ PackageInfoUtils.generatePermissionGroupInfo(
+ parsedPermissionGroup,
+ PackageManager.GET_META_DATA.toLong()
+ )!!
}
- fun getPermissionFlags(
+ private fun getPermission(
+ permissionName: String,
+ state: MutableAccessState = newState
+ ): Permission? = state.systemState.permissions[permissionName]
+
+ private fun getPermissionTree(
+ permissionTreeName: String,
+ state: MutableAccessState = newState
+ ): Permission? = state.systemState.permissionTrees[permissionTreeName]
+
+ private fun getPermissionGroup(
+ permissionGroupName: String,
+ state: MutableAccessState = newState
+ ): PermissionGroupInfo? = state.systemState.permissionGroups[permissionGroupName]
+
+ private fun getPermissionFlags(
appId: Int,
userId: Int,
permissionName: String,
@@ -517,20 +1706,43 @@ class AppIdPermissionPolicyTest {
): Int =
state.userStates[userId]?.appIdPermissionFlags?.get(appId).getWithDefault(permissionName, 0)
+ private fun setPermissionFlags(
+ appId: Int,
+ userId: Int,
+ permissionName: String,
+ flags: Int,
+ state: MutableAccessState = oldState
+ ) =
+ state.mutateUserState(userId)!!.mutateAppIdPermissionFlags().mutateOrPut(appId) {
+ MutableIndexedMap()
+ }.put(permissionName, flags)
+
companion object {
private const val PACKAGE_NAME_0 = "packageName0"
private const val PACKAGE_NAME_1 = "packageName1"
+ private const val MISSING_ANDROID_PACKAGE = "missingAndroidPackage"
+ private const val PLATFORM_PACKAGE_NAME = "android"
private const val APP_ID_0 = 0
private const val APP_ID_1 = 1
-
- private const val PERMISSION_NAME_0 = "permissionName0"
- private const val PERMISSION_NAME_1 = "permissionName1"
+ private const val PLATFORM_APP_ID = 2
private const val PERMISSION_GROUP_NAME_0 = "permissionGroupName0"
private const val PERMISSION_GROUP_NAME_1 = "permissionGroupName1"
+ private const val PERMISSION_TREE_NAME = "permissionTree"
+
+ private const val PERMISSION_NAME_0 = "permissionName0"
+ private const val PERMISSION_NAME_1 = "permissionName1"
+ private const val PERMISSION_READ_EXTERNAL_STORAGE =
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ private const val PERMISSION_POST_NOTIFICATIONS =
+ Manifest.permission.POST_NOTIFICATIONS
+ private const val PERMISSION_BLUETOOTH_CONNECT =
+ Manifest.permission.BLUETOOTH_CONNECT
+ private const val PERMISSION_ACCESS_BACKGROUND_LOCATION =
+ Manifest.permission.ACCESS_BACKGROUND_LOCATION
+
private const val USER_ID_0 = 0
- private const val USER_ID_1 = 1
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 82d00a6fcbca..7374901763db 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -44,6 +44,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
+import com.android.server.display.config.HdrBrightnessData;
import com.android.server.display.config.ThermalStatus;
import org.junit.Before;
@@ -477,6 +478,23 @@ public final class DisplayDeviceConfigTest {
mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(), ZERO_DELTA);
}
+ @Test
+ public void testHdrBrightnessDataFromDisplayConfig() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ HdrBrightnessData data = mDisplayDeviceConfig.getHdrBrightnessData();
+
+ assertNotNull(data);
+ assertEquals(2, data.mMaxBrightnessLimits.size());
+ assertEquals(13000, data.mBrightnessDecreaseDebounceMillis);
+ assertEquals(10000, data.mBrightnessDecreaseDurationMillis);
+ assertEquals(1000, data.mBrightnessIncreaseDebounceMillis);
+ assertEquals(11000, data.mBrightnessIncreaseDurationMillis);
+
+ assertEquals(0.3f, data.mMaxBrightnessLimits.get(500f), SMALL_DELTA);
+ assertEquals(0.6f, data.mMaxBrightnessLimits.get(1200f), SMALL_DELTA);
+ }
+
private void verifyConfigValuesFromConfigResource() {
assertNull(mDisplayDeviceConfig.getName());
assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
@@ -694,6 +712,25 @@ public final class DisplayDeviceConfigTest {
+ "</proxSensor>\n";
}
+ private String getHdrBrightnessConfig() {
+ return "<hdrBrightnessConfig>\n"
+ + " <brightnessMap>\n"
+ + " <point>\n"
+ + " <first>500</first>\n"
+ + " <second>0.3</second>\n"
+ + " </point>\n"
+ + " <point>\n"
+ + " <first>1200</first>\n"
+ + " <second>0.6</second>\n"
+ + " </point>\n"
+ + " </brightnessMap>\n"
+ + " <brightnessIncreaseDebounceMillis>1000</brightnessIncreaseDebounceMillis>\n"
+ + " <brightnessIncreaseDurationMillis>11000</brightnessIncreaseDurationMillis>\n"
+ + " <brightnessDecreaseDebounceMillis>13000</brightnessDecreaseDebounceMillis>\n"
+ + " <brightnessDecreaseDurationMillis>10000</brightnessDecreaseDurationMillis>\n"
+ + "</hdrBrightnessConfig>";
+ }
+
private String getContent() {
return getContent(getValidLuxThrottling(), getValidProxSensor());
}
@@ -784,6 +821,7 @@ public final class DisplayDeviceConfigTest {
+ "</point>\n"
+ "</sdrHdrRatioMap>\n"
+ "</highBrightnessMode>\n"
+ + getHdrBrightnessConfig()
+ brightnessCapConfig
+ "<lightSensor>\n"
+ "<type>test_light_sensor</type>\n"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
index e7dc48e529eb..9722426667db 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -43,6 +43,7 @@ import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Handler;
@@ -67,7 +68,9 @@ import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
import com.android.server.display.brightness.BrightnessEvent;
+import com.android.server.display.brightness.clamper.HdrClamper;
import com.android.server.display.color.ColorDisplayService;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.Layout;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.policy.WindowManagerPolicy;
@@ -1175,6 +1178,26 @@ public final class DisplayPowerController2Test {
verify(mHolder.displayPowerState, times(1)).stop();
}
+ @Test
+ public void testRampRateForHdrContent() {
+ float clampedBrightness = 0.6f;
+ float transitionRate = 35.5f;
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+ when(mHolder.hbmController.getHighBrightnessMode()).thenReturn(
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR);
+ when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(PowerManager.BRIGHTNESS_MAX);
+ when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(clampedBrightness);
+ when(mHolder.hdrClamper.getTransitionRate()).thenReturn(transitionRate);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.animator, atLeastOnce()).animateTo(eq(clampedBrightness), anyFloat(),
+ eq(transitionRate));
+ }
+
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
@@ -1270,12 +1293,15 @@ public final class DisplayPowerController2Test {
final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
mock(ScreenOffBrightnessSensorController.class);
final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
+ final HdrClamper hdrClamper = mock(HdrClamper.class);
+ final DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
TestInjector injector = spy(new TestInjector(displayPowerState, animator,
automaticBrightnessController, wakelockController, brightnessMappingStrategy,
- hysteresisLevels, screenOffBrightnessSensorController, hbmController));
+ hysteresisLevels, screenOffBrightnessSensorController, hbmController, hdrClamper,
+ flags));
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -1289,11 +1315,11 @@ public final class DisplayPowerController2Test {
mContext, injector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, display,
mBrightnessTrackerMock, brightnessSetting, () -> {},
- hbmMetadata, /* bootCompleted= */ false);
+ hbmMetadata, /* bootCompleted= */ false, flags);
return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
animator, automaticBrightnessController, wakelockController,
- screenOffBrightnessSensorController, hbmController, hbmMetadata,
+ screenOffBrightnessSensorController, hbmController, hdrClamper, hbmMetadata,
brightnessMappingStrategy, injector);
}
@@ -1311,6 +1337,8 @@ public final class DisplayPowerController2Test {
public final WakelockController wakelockController;
public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
public final HighBrightnessModeController hbmController;
+
+ public final HdrClamper hdrClamper;
public final HighBrightnessModeMetadata hbmMetadata;
public final BrightnessMappingStrategy brightnessMappingStrategy;
public final DisplayPowerController2.Injector injector;
@@ -1322,6 +1350,7 @@ public final class DisplayPowerController2Test {
WakelockController wakelockController,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
HighBrightnessModeController hbmController,
+ HdrClamper hdrClamper,
HighBrightnessModeMetadata hbmMetadata,
BrightnessMappingStrategy brightnessMappingStrategy,
DisplayPowerController2.Injector injector) {
@@ -1334,6 +1363,7 @@ public final class DisplayPowerController2Test {
this.wakelockController = wakelockController;
this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
this.hbmController = hbmController;
+ this.hdrClamper = hdrClamper;
this.hbmMetadata = hbmMetadata;
this.brightnessMappingStrategy = brightnessMappingStrategy;
this.injector = injector;
@@ -1350,13 +1380,19 @@ public final class DisplayPowerController2Test {
private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
private final HighBrightnessModeController mHighBrightnessModeController;
+ private final HdrClamper mHdrClamper;
+
+ private final DisplayManagerFlags mFlags;
+
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
WakelockController wakelockController,
BrightnessMappingStrategy brightnessMappingStrategy,
HysteresisLevels hysteresisLevels,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
- HighBrightnessModeController highBrightnessModeController) {
+ HighBrightnessModeController highBrightnessModeController,
+ HdrClamper hdrClamper,
+ DisplayManagerFlags flags) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
@@ -1365,6 +1401,8 @@ public final class DisplayPowerController2Test {
mHysteresisLevels = hysteresisLevels;
mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
mHighBrightnessModeController = highBrightnessModeController;
+ mHdrClamper = hdrClamper;
+ mFlags = flags;
}
@Override
@@ -1471,6 +1509,15 @@ public final class DisplayPowerController2Test {
}
@Override
+ BrightnessRangeController getBrightnessRangeController(
+ HighBrightnessModeController hbmController, Runnable modeChangeCallback,
+ DisplayDeviceConfig displayDeviceConfig, Handler handler,
+ DisplayManagerFlags flags) {
+ return new BrightnessRangeController(hbmController, modeChangeCallback,
+ displayDeviceConfig, mHdrClamper, mFlags);
+ }
+
+ @Override
DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
SensorManager sensorManager, Resources resources) {
return mDisplayWhiteBalanceControllerMock;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 2640390ceecf..4a6665acf92b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -69,6 +69,7 @@ import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.color.ColorDisplayService;
+import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.Layout;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.policy.WindowManagerPolicy;
@@ -758,14 +759,16 @@ public final class DisplayPowerControllerTest {
@Test
public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() {
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
DisplayPowerRequest dpr = new DisplayPowerRequest();
dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true);
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1); // Run updatePowerState
@@ -1280,6 +1283,7 @@ public final class DisplayPowerControllerTest {
final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class);
final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
+ final DisplayManagerFlags flags = mock(DisplayManagerFlags.class);
setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
@@ -1287,7 +1291,7 @@ public final class DisplayPowerControllerTest {
mContext, injector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, display,
mBrightnessTrackerMock, brightnessSetting, () -> {},
- hbmMetadata, /* bootCompleted= */ false);
+ hbmMetadata, /* bootCompleted= */ false, flags);
return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
animator, automaticBrightnessController, screenOffBrightnessSensorController,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
new file mode 100644
index 000000000000..0ebe46ac0c88
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.brightness.clamper;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.os.PowerManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.testutils.OffsettableClock;
+import com.android.server.testutils.TestHandler;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@SmallTest
+public class HdrClamperTest {
+
+ public static final float FLOAT_TOLERANCE = 0.0001f;
+
+ @Rule
+ public MockitoRule mRule = MockitoJUnit.rule();
+
+ @Mock
+ private BrightnessClamperController.ClamperChangeListener mMockListener;
+
+ OffsettableClock mClock = new OffsettableClock.Stopped();
+
+ private final TestHandler mTestHandler = new TestHandler(null, mClock);
+
+
+ private HdrClamper mHdrClamper;
+
+
+ @Before
+ public void setUp() {
+ mHdrClamper = new HdrClamper(mMockListener, mTestHandler);
+ configureClamper();
+ }
+
+ @Test
+ public void testClamper_AmbientLuxChangesAboveLimit() {
+ mHdrClamper.onAmbientLuxChange(500);
+
+ assertFalse(mTestHandler.hasMessagesOrCallbacks());
+ assertEquals(PowerManager.BRIGHTNESS_MAX, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE);
+ }
+
+ @Test
+ public void testClamper_AmbientLuxChangesBelowLimit() {
+ mHdrClamper.onAmbientLuxChange(499);
+
+ assertTrue(mTestHandler.hasMessagesOrCallbacks());
+ TestHandler.MsgInfo msgInfo = mTestHandler.getPendingMessages().peek();
+ assertEquals(2000, msgInfo.sendTime);
+ assertEquals(PowerManager.BRIGHTNESS_MAX, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE);
+
+ mClock.fastForward(2000);
+ mTestHandler.timeAdvance();
+ assertEquals(0.6f, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE);
+ }
+
+ @Test
+ public void testClamper_AmbientLuxChangesBelowLimit_ThenFastAboveLimit() {
+ mHdrClamper.onAmbientLuxChange(499);
+ mHdrClamper.onAmbientLuxChange(500);
+
+ assertFalse(mTestHandler.hasMessagesOrCallbacks());
+ assertEquals(PowerManager.BRIGHTNESS_MAX, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE);
+ }
+
+ @Test
+ public void testClamper_AmbientLuxChangesBelowLimit_ThenSlowlyAboveLimit() {
+ mHdrClamper.onAmbientLuxChange(499);
+ mClock.fastForward(2000);
+ mTestHandler.timeAdvance();
+
+ mHdrClamper.onAmbientLuxChange(500);
+
+ assertTrue(mTestHandler.hasMessagesOrCallbacks());
+ TestHandler.MsgInfo msgInfo = mTestHandler.getPendingMessages().peek();
+ assertEquals(3000, msgInfo.sendTime); // 2000 + 1000
+
+ mClock.fastForward(1000);
+ mTestHandler.timeAdvance();
+ assertEquals(PowerManager.BRIGHTNESS_MAX, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE);
+ }
+
+ private void configureClamper() {
+ mHdrClamper.getConfiguration().mMaxBrightnessLimits.put(500f, 0.6f);
+ mHdrClamper.getConfiguration().mIncreaseConfig.mDebounceTimeMillis = 1000;
+ mHdrClamper.getConfiguration().mIncreaseConfig.mTransitionTimeMillis = 1500;
+ mHdrClamper.getConfiguration().mDecreaseConfig.mDebounceTimeMillis = 2000;
+ mHdrClamper.getConfiguration().mDecreaseConfig.mTransitionTimeMillis = 2500;
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
index d988063bdfb0..5555c1964c7b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
@@ -18,7 +18,9 @@ package com.android.server.pm;
import static android.content.Intent.FLAG_RECEIVER_FOREGROUND;
import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
+
import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -161,7 +163,7 @@ public class PackageArchiverTest {
mArchiveManager = spy(new PackageArchiver(mContext, pm));
doReturn(ICON_PATH).when(mArchiveManager).storeIcon(eq(PACKAGE),
- any(LauncherActivityInfo.class), eq(mUserId));
+ any(LauncherActivityInfo.class), eq(mUserId), anyInt());
}
@Test
@@ -249,7 +251,7 @@ public class PackageArchiverTest {
public void archiveApp_storeIconFails() throws IntentSender.SendIntentException, IOException {
IOException e = new IOException("IO");
doThrow(e).when(mArchiveManager).storeIcon(eq(PACKAGE),
- any(LauncherActivityInfo.class), eq(mUserId));
+ any(LauncherActivityInfo.class), eq(mUserId), anyInt());
mArchiveManager.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, UserHandle.CURRENT);
rule.mocks().getHandler().flush();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 7e638a869682..49f22eca5643 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -27,6 +27,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -428,6 +429,10 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testChangeMagnificationModeOnTestDisplay_capabilitiesIsAll_transitMode() {
+ // This test only makes sense for devices that support Window magnification
+ assumeTrue(mTestableContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WINDOW_MAGNIFICATION));
+
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
userState.setMagnificationCapabilitiesLocked(
diff --git a/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java b/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java
new file mode 100644
index 000000000000..9fdbdda38c75
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.platform.test.annotations.Presubmit;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+
+import android.util.Log;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:AnrTimerTest
+ */
+@SmallTest
+@Presubmit
+public class AnrTimerTest {
+
+ /**
+ * A handler that allows control over when to dispatch messages and callbacks. Because most
+ * Handler methods are final, the only thing this handler can intercept is sending messages.
+ * This handler allows unit tests to be written without a need to sleep (which leads to flaky
+ * tests).
+ *
+ * This code was cloned from {@link com.android.systemui.utils.os.FakeHandler}.
+ */
+ static class TestHandler extends Handler {
+
+ private boolean mImmediate = true;
+ private ArrayList<Message> mQueuedMessages = new ArrayList<>();
+
+ ArrayList<Long> mDelays = new ArrayList<>();
+
+ TestHandler(Looper looper, Callback callback, boolean immediate) {
+ super(looper, callback);
+ mImmediate = immediate;
+ }
+
+ TestHandler(Looper looper, Callback callback) {
+ this(looper, callback, true);
+ }
+
+ /**
+ * Override sendMessageAtTime. In immediate mode, the message is immediately dispatched.
+ * In non-immediate mode, the message is enqueued to the real handler. In both cases, the
+ * original delay is computed by comparing the target dispatch time with 'now'. This
+ * computation is prone to errors if the code experiences delays. The computed time is
+ * captured in the mDelays list.
+ */
+ @Override
+ public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+ long delay = uptimeMillis - SystemClock.uptimeMillis();
+ mDelays.add(delay);
+ if (mImmediate) {
+ mQueuedMessages.add(msg);
+ dispatchQueuedMessages();
+ } else {
+ super.sendMessageAtTime(msg, uptimeMillis);
+ }
+ return true;
+ }
+
+ void setImmediate(boolean immediate) {
+ mImmediate = immediate;
+ }
+
+ /** Dispatch any messages that have been queued on the calling thread. */
+ void dispatchQueuedMessages() {
+ ArrayList<Message> messages = new ArrayList<>(mQueuedMessages);
+ mQueuedMessages.clear();
+ for (Message msg : messages) {
+ dispatchMessage(msg);
+ }
+ }
+
+ /**
+ * Compare the captured delays with the input array. The comparison is fuzzy because the
+ * captured delay (see sendMessageAtTime) is affected by process delays.
+ */
+ void verifyDelays(long[] r) {
+ final long FUZZ = 10;
+ assertEquals(r.length, mDelays.size());
+ for (int i = 0; i < mDelays.size(); i++) {
+ long t = r[i];
+ long v = mDelays.get(i);
+ assertTrue(v >= t - FUZZ && v <= t + FUZZ);
+ }
+ }
+ }
+
+ private Handler mHandler;
+ private CountDownLatch mLatch = null;
+ private ArrayList<Message> mMessages;
+
+ // The commonly used message timeout key.
+ private static final int MSG_TIMEOUT = 1;
+
+ @Before
+ public void setUp() {
+ mHandler = new Handler(Looper.getMainLooper(), this::expirationHandler);
+ mMessages = new ArrayList<>();
+ mLatch = new CountDownLatch(1);
+ AnrTimer.resetTimerListForHermeticTest();
+ }
+
+ @After
+ public void tearDown() {
+ mHandler = null;
+ mMessages = null;
+ }
+
+ // When a timer expires, set the expiration time in the message and add it to the queue.
+ private boolean expirationHandler(Message msg) {
+ mMessages.add(Message.obtain(msg));
+ mLatch.countDown();
+ return false;
+ }
+
+ // The test argument includes a pid and uid, and a tag. The tag is used to distinguish
+ // different message instances.
+ private static class TestArg {
+ final int pid;
+ final int uid;
+ final int tag;
+
+ TestArg(int pid, int uid, int tag) {
+ this.pid = pid;
+ this.uid = uid;
+ this.tag = tag;
+ }
+ @Override
+ public String toString() {
+ return String.format("pid=%d uid=%d tag=%d", pid, uid, tag);
+ }
+ }
+
+ /**
+ * An instrumented AnrTimer.
+ */
+ private class TestAnrTimer extends AnrTimer {
+ // A local copy of 'what'. The field in AnrTimer is private.
+ final int mWhat;
+
+ TestAnrTimer(Handler h, int key, String tag) {
+ super(h, key, tag);
+ mWhat = key;
+ }
+
+ TestAnrTimer() {
+ this(mHandler, MSG_TIMEOUT, caller());
+ }
+
+ TestAnrTimer(Handler h, int key, String tag, boolean extend, TestInjector injector) {
+ super(h, key, tag, extend, injector);
+ mWhat = key;
+ }
+
+ TestAnrTimer(boolean extend, TestInjector injector) {
+ this(mHandler, MSG_TIMEOUT, caller(), extend, injector);
+ }
+
+ // Return the name of method that called the constructor, assuming that this function is
+ // called from inside the constructor. The calling method is used to name the AnrTimer
+ // instance so that logs are easier to understand.
+ private static String caller() {
+ final int n = 4;
+ StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+ if (stack.length < n+1) return "test";
+ return stack[n].getMethodName();
+ }
+
+ boolean start(TestArg arg, long millis) {
+ return start(arg, arg.pid, arg.uid, millis);
+ }
+
+ int what() {
+ return mWhat;
+ }
+ }
+
+ private static class TestTracker extends AnrTimer.CpuTracker {
+ long index = 0;
+ final int skip;
+ TestTracker(int skip) {
+ this.skip = skip;
+ }
+ long delay(int pid) {
+ return index++ * skip;
+ }
+ }
+
+ private class TestInjector extends AnrTimer.Injector {
+ final boolean mImmediate;
+ final AnrTimer.CpuTracker mTracker;
+ TestHandler mTestHandler;
+
+ TestInjector(int skip, boolean immediate) {
+ mTracker = new TestTracker(skip);
+ mImmediate = immediate;
+ }
+
+ TestInjector(int skip) {
+ this(skip, true);
+ }
+
+ @Override
+ Handler getHandler(Handler.Callback callback) {
+ if (mTestHandler == null) {
+ mTestHandler = new TestHandler(mHandler.getLooper(), callback, mImmediate);
+ }
+ return mTestHandler;
+ }
+
+ /** Fetch the allocated handle. This does not check for nulls. */
+ TestHandler getHandler() {
+ return mTestHandler;
+ }
+
+ AnrTimer.CpuTracker getTracker() {
+ return mTracker;
+ }
+ }
+
+ // Tests
+ // 1. Start a timer and wait for expiration.
+ // 2. Start a timer and cancel it. Verify no expiration.
+ // 3. Start a timer. Shortly thereafter, restart it. Verify only one expiration.
+ // 4. Start a couple of timers. Verify max active timers. Discard one and verify the active
+ // count drops by 1. Accept one and verify the active count drops by 1.
+
+
+ @Test
+ public void testSimpleTimeout() throws Exception {
+ // Create an immediate TestHandler.
+ TestInjector injector = new TestInjector(0);
+ TestAnrTimer timer = new TestAnrTimer(false, injector);
+ TestArg t = new TestArg(1, 1, 3);
+ assertTrue(timer.start(t, 10));
+ // Delivery is immediate but occurs on a different thread.
+ assertTrue(mLatch.await(100, TimeUnit.MILLISECONDS));
+ assertEquals(1, mMessages.size());
+ Message m = mMessages.get(0);
+ assertEquals(timer.what(), m.what);
+ assertEquals(t, m.obj);
+
+ // Verify that the timer is still present.
+ assertEquals(1, AnrTimer.sizeOfTimerList());
+ assertTrue(timer.accept(t));
+ assertEquals(0, AnrTimer.sizeOfTimerList());
+
+ // Verify that the timer no longer exists.
+ assertFalse(timer.accept(t));
+ }
+
+ @Test
+ public void testCancel() throws Exception {
+ // Create an non-immediate TestHandler.
+ TestInjector injector = new TestInjector(0, false);
+ TestAnrTimer timer = new TestAnrTimer(false, injector);
+
+ Handler handler = injector.getHandler();
+ assertNotNull(handler);
+ assertTrue(handler instanceof TestHandler);
+
+ // The tests that follow check for a 'what' of 0 (zero), which is the message key used
+ // by AnrTimer internally.
+ TestArg t = new TestArg(1, 1, 3);
+ assertFalse(handler.hasMessages(0));
+ assertTrue(timer.start(t, 100));
+ assertTrue(handler.hasMessages(0));
+ assertTrue(timer.cancel(t));
+ assertFalse(handler.hasMessages(0));
+
+ // Verify that no expiration messages were delivered.
+ assertEquals(0, mMessages.size());
+ assertEquals(0, AnrTimer.sizeOfTimerList());
+ }
+
+ @Test
+ public void testRestart() throws Exception {
+ // Create an non-immediate TestHandler.
+ TestInjector injector = new TestInjector(0, false);
+ TestAnrTimer timer = new TestAnrTimer(false, injector);
+
+ TestArg t = new TestArg(1, 1, 3);
+ assertTrue(timer.start(t, 2500));
+ assertTrue(timer.start(t, 1000));
+
+ // Verify that the test handler saw two timeouts.
+ injector.getHandler().verifyDelays(new long[] { 2500, 1000 });
+
+ // Verify that there is a single timer. Then cancel it.
+ assertEquals(1, AnrTimer.sizeOfTimerList());
+ assertTrue(timer.cancel(t));
+ assertEquals(0, AnrTimer.sizeOfTimerList());
+ }
+
+ @Test
+ public void testExtendNormal() throws Exception {
+ // Create an immediate TestHandler.
+ TestInjector injector = new TestInjector(5);
+ TestAnrTimer timer = new TestAnrTimer(true, injector);
+ TestArg t = new TestArg(1, 1, 3);
+ assertTrue(timer.start(t, 10));
+
+ assertTrue(mLatch.await(100, TimeUnit.MILLISECONDS));
+ assertEquals(1, mMessages.size());
+ Message m = mMessages.get(0);
+ assertEquals(timer.what(), m.what);
+ assertEquals(t, m.obj);
+
+ // Verify that the test handler saw two timeouts: one of 10ms and one of 5ms.
+ injector.getHandler().verifyDelays(new long[] { 10, 5 });
+
+ // Verify that the timer is still present. Then remove it and verify that the list is
+ // empty.
+ assertEquals(1, AnrTimer.sizeOfTimerList());
+ assertTrue(timer.accept(t));
+ assertEquals(0, AnrTimer.sizeOfTimerList());
+ }
+
+ @Test
+ public void testExtendOversize() throws Exception {
+ // Create an immediate TestHandler.
+ TestInjector injector = new TestInjector(25);
+ TestAnrTimer timer = new TestAnrTimer(true, injector);
+ TestArg t = new TestArg(1, 1, 3);
+ assertTrue(timer.start(t, 10));
+
+ assertTrue(mLatch.await(100, TimeUnit.MILLISECONDS));
+ assertEquals(1, mMessages.size());
+ Message m = mMessages.get(0);
+ assertEquals(timer.what(), m.what);
+ assertEquals(t, m.obj);
+
+ // Verify that the test handler saw two timeouts: one of 10ms and one of 10ms.
+ injector.getHandler().verifyDelays(new long[] { 10, 10 });
+
+ // Verify that the timer is still present. Then remove it and verify that the list is
+ // empty.
+ assertEquals(1, AnrTimer.sizeOfTimerList());
+ assertTrue(timer.accept(t));
+ assertEquals(0, AnrTimer.sizeOfTimerList());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 769be177ce03..0f3daec263e0 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -182,7 +182,8 @@ public class AuthSessionTest {
eq(TEST_PACKAGE),
eq(TEST_REQUEST_ID),
eq(sensor.getCookie()),
- anyBoolean() /* allowBackgroundAuthentication */);
+ anyBoolean() /* allowBackgroundAuthentication */,
+ anyBoolean() /* isForLegacyFingerprintManager */);
}
final int cookie1 = session.mPreAuthInfo.eligibleSensors.get(0).getCookie();
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsBroadcastReceiverTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsBroadcastReceiverTest.java
new file mode 100644
index 000000000000..f4e5faaf2103
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsBroadcastReceiverTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anySet;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static java.util.Collections.emptySet;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.os.UserHandle;
+
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.io.File;
+import java.util.function.Consumer;
+
+public class AuthenticationStatsBroadcastReceiverTest {
+
+ @Rule
+ public MockitoRule mockitoRule = MockitoJUnit.rule();
+
+ private AuthenticationStatsBroadcastReceiver mBroadcastReceiver;
+ private static final float FRR_THRESHOLD = 0.2f;
+ private static final int USER_ID_1 = 1;
+
+ @Mock
+ Context mContext;
+ @Mock
+ private Resources mResources;
+ @Mock
+ private SharedPreferences mSharedPreferences;
+ @Mock
+ private SharedPreferences.Editor mEditor;
+ @Mock
+ Intent mIntent;
+ @Mock
+ Consumer<AuthenticationStatsCollector> mCallback;
+
+ @Captor
+ private ArgumentCaptor<AuthenticationStatsCollector> mArgumentCaptor;
+
+ @Before
+ public void setUp() {
+
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getFraction(eq(R.fraction.config_biometricNotificationFrrThreshold),
+ anyInt(), anyInt())).thenReturn(FRR_THRESHOLD);
+ when(mContext.getSharedPreferences(any(File.class), anyInt()))
+ .thenReturn(mSharedPreferences);
+ when(mSharedPreferences.getStringSet(anyString(), anySet())).thenReturn(emptySet());
+ when(mSharedPreferences.edit()).thenReturn(mEditor);
+ when(mEditor.putFloat(anyString(), anyFloat())).thenReturn(mEditor);
+ when(mEditor.putStringSet(anyString(), anySet())).thenReturn(mEditor);
+
+ when(mIntent.getAction()).thenReturn(Intent.ACTION_USER_UNLOCKED);
+ when(mIntent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL))
+ .thenReturn(USER_ID_1);
+
+ mBroadcastReceiver = new AuthenticationStatsBroadcastReceiver(mContext,
+ BiometricsProtoEnums.MODALITY_FINGERPRINT, mCallback);
+ }
+
+ @Test
+ public void testRegisterReceiver() {
+ verify(mContext).registerReceiver(eq(mBroadcastReceiver), any());
+ }
+
+ @Test
+ public void testOnReceive_shouldInitializeAuthenticationStatsCollector() {
+ mBroadcastReceiver.onReceive(mContext, mIntent);
+
+ // Verify AuthenticationStatsCollector is initialized
+ verify(mCallback).accept(mArgumentCaptor.capture());
+ assertThat(mArgumentCaptor.getValue()).isNotNull();
+
+ // Verify receiver is unregistered after receiving the broadcast
+ verify(mContext).unregisterReceiver(mBroadcastReceiver);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java
index fa6e7f60c1b0..a11a8f53c2cb 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java
@@ -104,6 +104,7 @@ public class AuthenticationStatsCollectorTest {
when(mSharedPreferences.getStringSet(anyString(), anySet())).thenReturn(emptySet());
when(mSharedPreferences.edit()).thenReturn(mEditor);
when(mEditor.putFloat(anyString(), anyFloat())).thenReturn(mEditor);
+ when(mEditor.putStringSet(anyString(), anySet())).thenReturn(mEditor);
mAuthenticationStatsCollector = new AuthenticationStatsCollector(mContext,
0 /* modality */, mBiometricNotification);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index e79ac0986dc8..0230d77e8e14 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -598,7 +598,8 @@ public class BiometricServiceTest {
anyString() /* opPackageName */,
eq(TEST_REQUEST_ID),
cookieCaptor.capture() /* cookie */,
- anyBoolean() /* allowBackgroundAuthentication */);
+ anyBoolean() /* allowBackgroundAuthentication */,
+ anyBoolean() /* isForLegacyFingerprintManager */);
// onReadyForAuthentication, mAuthSession state OK
mBiometricService.mImpl.onReadyForAuthentication(TEST_REQUEST_ID, cookieCaptor.getValue());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
index 046b01c831b5..9e5a0479ea70 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.common.AuthenticateReason;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.common.OperationContext;
@@ -109,6 +110,8 @@ public class FaceAuthenticationClientTest {
private ICancellationSignal mCancellationSignal;
@Mock
private AuthSessionCoordinator mAuthSessionCoordinator;
+ @Mock
+ private BiometricManager mBiometricManager;
@Captor
private ArgumentCaptor<OperationContextExt> mOperationContextCaptor;
@Captor
@@ -119,6 +122,7 @@ public class FaceAuthenticationClientTest {
@Before
public void setup() {
+ mContext.addMockSystemService(BiometricManager.class, mBiometricManager);
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
i -> i.getArgument(0));
when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
@@ -212,11 +216,44 @@ public class FaceAuthenticationClientTest {
.onError(anyInt(), anyInt(), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
+ @Test
+ public void testOnAuthenticatedFalseWhenListenerIsNull() throws RemoteException {
+ final FaceAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Face("friendly", 1 /* faceId */, 2 /* deviceId */),
+ false /* authenticated */, new ArrayList<>());
+
+ verify(mCallback).onClientFinished(client, true);
+ }
+
+ @Test
+ public void testOnAuthenticatedTrueWhenListenerIsNull() throws RemoteException {
+ final FaceAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Face("friendly", 1 /* faceId */, 2 /* deviceId */),
+ true /* authenticated */, new ArrayList<>());
+
+ verify(mCallback).onClientFinished(client, true);
+ }
+
private FaceAuthenticationClient createClient() throws RemoteException {
- return createClient(2 /* version */);
+ return createClient(2 /* version */, mClientMonitorCallbackConverter,
+ false /* allowBackgroundAuthentication */);
+ }
+
+ private FaceAuthenticationClient createClientWithNullListener() throws RemoteException {
+ return createClient(2 /* version */, null /* listener */,
+ true /* allowBackgroundAuthentication */);
}
private FaceAuthenticationClient createClient(int version) throws RemoteException {
+ return createClient(version, mClientMonitorCallbackConverter,
+ false /* allowBackgroundAuthentication */);
+ }
+
+ private FaceAuthenticationClient createClient(int version,
+ ClientMonitorCallbackConverter listener,
+ boolean allowBackgroundAuthentication) throws RemoteException {
when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
@@ -229,11 +266,11 @@ public class FaceAuthenticationClientTest {
FaceAuthenticateOptions.AUTHENTICATE_REASON_ASSISTANT_VISIBLE)
.build();
return new FaceAuthenticationClient(mContext, () -> aidl, mToken,
- 2 /* requestId */, mClientMonitorCallbackConverter, OP_ID,
+ 2 /* requestId */, listener, OP_ID,
false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */,
mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
- mUsageStats, null /* mLockoutCache */, false /* allowBackgroundAuthentication */,
+ mUsageStats, null /* mLockoutCache */, allowBackgroundAuthentication,
null /* sensorPrivacyManager */, 0 /* biometricStrength */) {
@Override
protected ActivityTaskManager getActivityTaskManager() {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 46af90537c03..8a11e31014d5 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -392,7 +392,6 @@ public class FingerprintAuthenticationClientTest {
final ActivityManager.RunningTaskInfo topTask = new ActivityManager.RunningTaskInfo();
topTask.topActivity = new ComponentName("other", "thing");
when(mActivityTaskManager.getTasks(anyInt())).thenReturn(List.of(topTask));
- when(mHal.authenticateWithContext(anyLong(), any())).thenReturn(mCancellationSignal);
final FingerprintAuthenticationClient client = createClientWithoutBackgroundAuth();
client.start(mCallback);
@@ -406,21 +405,50 @@ public class FingerprintAuthenticationClientTest {
.onError(anyInt(), anyInt(), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
+ @Test
+ public void testOnAuthenticatedFalseWhenListenerIsNull() throws RemoteException {
+ final FingerprintAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */,
+ 2 /* deviceId */), false /* authenticated */, new ArrayList<>());
+
+ verify(mCallback, never()).onClientFinished(eq(client), anyBoolean());
+ }
+
+ @Test
+ public void testOnAuthenticatedTrueWhenListenerIsNull() throws RemoteException {
+ final FingerprintAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */,
+ 2 /* deviceId */), true /* authenticated */, new ArrayList<>());
+
+ verify(mCallback).onClientFinished(client, true);
+ }
+
private FingerprintAuthenticationClient createClient() throws RemoteException {
- return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
+ return createClient(100 /* version */, true /* allowBackgroundAuthentication */,
+ mClientMonitorCallbackConverter);
}
private FingerprintAuthenticationClient createClientWithoutBackgroundAuth()
throws RemoteException {
- return createClient(100 /* version */, false /* allowBackgroundAuthentication */);
+ return createClient(100 /* version */, false /* allowBackgroundAuthentication */,
+ mClientMonitorCallbackConverter);
}
private FingerprintAuthenticationClient createClient(int version) throws RemoteException {
- return createClient(version, true /* allowBackgroundAuthentication */);
+ return createClient(version, true /* allowBackgroundAuthentication */,
+ mClientMonitorCallbackConverter);
+ }
+
+ private FingerprintAuthenticationClient createClientWithNullListener() throws RemoteException {
+ return createClient(100 /* version */, true /* allowBackgroundAuthentication */,
+ null /* listener */);
}
private FingerprintAuthenticationClient createClient(int version,
- boolean allowBackgroundAuthentication) throws RemoteException {
+ boolean allowBackgroundAuthentication, ClientMonitorCallbackConverter listener)
+ throws RemoteException {
when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
@@ -430,7 +458,7 @@ public class FingerprintAuthenticationClientTest {
.setSensorId(9)
.build();
return new FingerprintAuthenticationClient(mContext, () -> aidl, mToken,
- REQUEST_ID, mClientMonitorCallbackConverter, OP_ID,
+ REQUEST_ID, listener, OP_ID,
false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */,
mBiometricLogger, mBiometricContext,
diff --git a/services/tests/servicestests/src/com/android/server/media/BluetoothRouteControllerTest.java b/services/tests/servicestests/src/com/android/server/media/BluetoothRouteControllerTest.java
new file mode 100644
index 000000000000..75d71daa208d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/media/BluetoothRouteControllerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
+
+import android.content.Context;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.common.truth.Truth;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class BluetoothRouteControllerTest {
+
+ private final BluetoothRouteController.BluetoothRoutesUpdatedListener
+ mBluetoothRoutesUpdatedListener = routes -> {
+ // Empty on purpose.
+ };
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ }
+
+ @Test
+ @RequiresFlagsDisabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
+ public void createInstance_audioPoliciesFlagIsDisabled_createsLegacyController() {
+ BluetoothRouteController deviceRouteController =
+ BluetoothRouteController.createInstance(mContext, mBluetoothRoutesUpdatedListener);
+
+ Truth.assertThat(deviceRouteController).isInstanceOf(LegacyBluetoothRouteController.class);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
+ public void createInstance_audioPoliciesFlagIsEnabled_createsAudioPoliciesController() {
+ BluetoothRouteController deviceRouteController =
+ BluetoothRouteController.createInstance(mContext, mBluetoothRoutesUpdatedListener);
+
+ Truth.assertThat(deviceRouteController)
+ .isInstanceOf(AudioPoliciesBluetoothRouteController.class);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java b/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
new file mode 100644
index 000000000000..ec4b8a804533
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
+
+import android.content.Context;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.common.truth.Truth;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class DeviceRouteControllerTest {
+
+ private final DeviceRouteController.OnDeviceRouteChangedListener mOnDeviceRouteChangedListener =
+ deviceRoute -> {
+ // Empty on purpose.
+ };
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ }
+
+ @Test
+ @RequiresFlagsDisabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
+ public void createInstance_audioPoliciesFlagIsDisabled_createsLegacyController() {
+ DeviceRouteController deviceRouteController =
+ DeviceRouteController.createInstance(mContext, mOnDeviceRouteChangedListener);
+
+ Truth.assertThat(deviceRouteController).isInstanceOf(LegacyDeviceRouteController.class);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
+ public void createInstance_audioPoliciesFlagIsEnabled_createsAudioPoliciesController() {
+ DeviceRouteController deviceRouteController =
+ DeviceRouteController.createInstance(mContext, mOnDeviceRouteChangedListener);
+
+ Truth.assertThat(deviceRouteController)
+ .isInstanceOf(AudioPoliciesDeviceRouteController.class);
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index cb0a61533dd5..4576e9be07ad 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -22,6 +22,8 @@ import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_
import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.SHOW_IMMEDIATELY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.Notification.EXTRA_ALLOW_DURING_SETUP;
+import static android.app.Notification.EXTRA_PICTURE;
+import static android.app.Notification.EXTRA_PICTURE_ICON;
import static android.app.Notification.FLAG_AUTO_CANCEL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_CAN_COLORIZE;
@@ -30,7 +32,6 @@ import static android.app.Notification.FLAG_NO_CLEAR;
import static android.app.Notification.FLAG_ONGOING_EVENT;
import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
import static android.app.Notification.FLAG_USER_INITIATED_JOB;
-import static android.app.Notification.GROUP_KEY_SILENT;
import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
@@ -89,6 +90,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
+import static com.android.server.notification.NotificationManagerService.BITMAP_EXPIRATION_TIME_MS;
import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
@@ -11285,114 +11287,142 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
}
- @Test
- public void testIsBigPictureWithBitmapOrIcon_notBigPicture_false() {
- Notification n = new Notification.Builder(mContext).build();
+ private NotificationRecord createBigPictureRecord(boolean isBigPictureStyle, boolean hasImage,
+ boolean isImageBitmap, boolean isExpired) {
+ Notification.Builder builder = new Notification.Builder(mContext);
+ Notification.BigPictureStyle style = new Notification.BigPictureStyle();
- assertThat(mService.isBigPictureWithBitmapOrIcon(n)).isFalse();
- }
+ if (isBigPictureStyle && hasImage) {
+ if (isImageBitmap) {
+ style = style.bigPicture(Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888));
+ } else {
+ style = style.bigPicture(Icon.createWithResource(mContext, R.drawable.btn_plus));
+ }
+ }
+ if (isBigPictureStyle) {
+ builder.setStyle(style);
+ }
- @Test
- public void testIsBigPictureWithBitmapOrIcon_bigPictureWithBitmap_true() {
- Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
+ Notification notification = builder.setChannelId(TEST_CHANNEL_ID).build();
- Notification n = new Notification.Builder(mContext)
- .setStyle(new Notification.BigPictureStyle().bigPicture(bitmap))
- .build();
+ long timePostedMs = System.currentTimeMillis();
+ if (isExpired) {
+ timePostedMs -= BITMAP_EXPIRATION_TIME_MS;
+ }
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ notification, UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
- assertThat(mService.isBigPictureWithBitmapOrIcon(n)).isTrue();
+ return new NotificationRecord(mContext, sbn, mTestNotificationChannel);
}
- @Test
- public void testIsBigPictureWithBitmapOrIcon_bigPictureWithIcon_true() {
- Icon icon = Icon.createWithResource(mContext, R.drawable.btn_plus);
-
- Notification n = new Notification.Builder(mContext)
- .setStyle(new Notification.BigPictureStyle().bigPicture(icon))
- .build();
-
- assertThat(mService.isBigPictureWithBitmapOrIcon(n)).isTrue();
+ private void addRecordAndRemoveBitmaps(NotificationRecord record) {
+ mService.addNotification(record);
+ mInternalService.removeBitmaps();
+ waitForIdle();
}
@Test
- public void testIsBitmapExpired_notExpired_false() {
- final boolean result = mService.isBitmapExpired(
- /* timePosted= */ 0,
- /* timeNow= */ 1,
- /* timeToLive= */ 2);
- assertThat(result).isFalse();
+ public void testRemoveBitmaps_notBigPicture_noRepost() {
+ addRecordAndRemoveBitmaps(
+ createBigPictureRecord(
+ /* isBigPictureStyle= */ false,
+ /* hasImage= */ false,
+ /* isImageBitmap= */ false,
+ /* isExpired= */ false));
+ verify(mWorkerHandler, never())
+ .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
}
@Test
- public void testIsBitmapExpired_expired_true() {
- final boolean result = mService.isBitmapExpired(
- /* timePosted= */ 0,
- /* timeNow= */ 2,
- /* timeToLive= */ 1);
- assertThat(result).isTrue();
+ public void testRemoveBitmaps_bigPictureNoImage_noRepost() {
+ addRecordAndRemoveBitmaps(
+ createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ false,
+ /* isImageBitmap= */ false,
+ /* isExpired= */ false));
+ verify(mWorkerHandler, never())
+ .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
}
@Test
- public void testRemoveBitmapAndRepost_removeBitmapFromExtras() {
- // Create big picture NotificationRecord with bitmap
- Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
-
- Notification n = new Notification.Builder(mContext, "test")
- .setStyle(new android.app.Notification.BigPictureStyle().bigPicture(bitmap))
- .build();
-
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- n, UserHandle.getUserHandleForUid(mUid), null, 0);
-
- NotificationRecord bigPictureRecord =
- new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mService.removeBitmapAndRepost(bigPictureRecord);
-
- Bitmap bitmapExtra = bigPictureRecord.getNotification().extras.getParcelable(
- Notification.EXTRA_PICTURE, Bitmap.class);
- assertThat(bitmapExtra).isNull();
+ public void testRemoveBitmaps_notExpired_noRepost() {
+ addRecordAndRemoveBitmaps(
+ createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ true,
+ /* isExpired= */ false));
+ verify(mWorkerHandler, never())
+ .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
}
@Test
- public void testRemoveBitmapAndRepost_removeIconFromExtras() {
- // Create big picture NotificationRecord with Icon
- Icon icon = Icon.createWithResource(mContext, R.drawable.btn_plus);
-
- Notification n = new Notification.Builder(mContext, "test")
- .setStyle(new android.app.Notification.BigPictureStyle().bigPicture(icon))
- .build();
-
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- n, UserHandle.getUserHandleForUid(mUid), null, 0);
-
- NotificationRecord bigPictureRecord =
- new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mService.removeBitmapAndRepost(bigPictureRecord);
-
- Icon iconExtra = bigPictureRecord.getNotification().extras.getParcelable(
- Notification.EXTRA_PICTURE_ICON, Icon.class);
- assertThat(iconExtra).isNull();
+ public void testRemoveBitmaps_bitmapExpired_repost() {
+ addRecordAndRemoveBitmaps(
+ createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ true,
+ /* isExpired= */ true));
+ verify(mWorkerHandler, times(1))
+ .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
}
@Test
- public void testRemoveBitmapAndRepost_flagOnlyAlertOnce() {
- Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
-
- Notification n = new Notification.Builder(mContext, "test")
- .setStyle(new android.app.Notification.BigPictureStyle().bigPicture(bitmap))
- .build();
+ public void testRemoveBitmaps_bitmapExpired_bitmapGone() {
+ NotificationRecord record = createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ true,
+ /* isExpired= */ true);
+ addRecordAndRemoveBitmaps(record);
+ assertThat(record.getNotification().extras.containsKey(EXTRA_PICTURE)).isFalse();
+ }
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ @Test
+ public void testRemoveBitmaps_bitmapExpired_silent() {
+ NotificationRecord record = createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ true,
+ /* isExpired= */ true);
+ addRecordAndRemoveBitmaps(record);
+ assertThat(record.getNotification().flags & FLAG_ONLY_ALERT_ONCE).isNotEqualTo(0);
+ }
- NotificationRecord bigPictureRecord =
- new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+ @Test
+ public void testRemoveBitmaps_iconExpired_repost() {
+ addRecordAndRemoveBitmaps(
+ createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ false,
+ /* isExpired= */ true));
+ verify(mWorkerHandler, times(1))
+ .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
+ }
- mService.removeBitmapAndRepost(bigPictureRecord);
+ @Test
+ public void testRemoveBitmaps_iconExpired_iconGone() {
+ NotificationRecord record = createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ false,
+ /* isExpired= */ true);
+ addRecordAndRemoveBitmaps(record);
+ assertThat(record.getNotification().extras.containsKey(EXTRA_PICTURE_ICON)).isFalse();
+ }
- assertThat(n.flags & FLAG_ONLY_ALERT_ONCE).isNotEqualTo(0);
+ @Test
+ public void testRemoveBitmaps_iconExpired_silent() {
+ NotificationRecord record = createBigPictureRecord(
+ /* isBigPictureStyle= */ true,
+ /* hasImage= */ true,
+ /* isImageBitmap= */ false,
+ /* isExpired= */ true);
+ addRecordAndRemoveBitmaps(record);
+ assertThat(record.getNotification().flags & FLAG_ONLY_ALERT_ONCE).isNotEqualTo(0);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
index 0989db4c25ac..568471d67c31 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
@@ -26,7 +25,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
-import static com.android.server.wm.ActivityInterceptorCallback.MAINLINE_SDK_SANDBOX_ORDER_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -36,7 +34,6 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -44,13 +41,11 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManagerInternal;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
@@ -76,7 +71,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
/**
@@ -509,88 +503,4 @@ public class ActivityStartInterceptorTest {
verify(callback, times(1)).onActivityLaunched(any(), any(), any());
}
-
- @Test
- public void testSandboxServiceInterceptionHappensToIntentWithSandboxActivityAction() {
- ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
- mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
-
- PackageManager packageManagerMock = mock(PackageManager.class);
- String sandboxPackageNameMock = "com.sandbox.mock";
- when(mContext.getPackageManager()).thenReturn(packageManagerMock);
- when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
-
- Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY);
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- verify(spyCallback, times(1)).onInterceptActivityLaunch(
- any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
- }
-
- @Test
- public void testSandboxServiceInterceptionHappensToIntentWithSandboxPackage() {
- ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
- mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
-
- PackageManager packageManagerMock = mock(PackageManager.class);
- String sandboxPackageNameMock = "com.sandbox.mock";
- when(mContext.getPackageManager()).thenReturn(packageManagerMock);
- when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
-
- Intent intent = new Intent().setPackage(sandboxPackageNameMock);
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- verify(spyCallback, times(1)).onInterceptActivityLaunch(
- any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
- }
-
- @Test
- public void testSandboxServiceInterceptionHappensToIntentWithComponentNameWithSandboxPackage() {
- ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
- mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
-
- PackageManager packageManagerMock = mock(PackageManager.class);
- String sandboxPackageNameMock = "com.sandbox.mock";
- when(mContext.getPackageManager()).thenReturn(packageManagerMock);
- when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
-
- Intent intent = new Intent().setComponent(new ComponentName(sandboxPackageNameMock, ""));
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- verify(spyCallback, times(1)).onInterceptActivityLaunch(
- any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
- }
-
- @Test
- public void testSandboxServiceInterceptionNotCalledWhenIntentNotRelatedToSandbox() {
- ActivityInterceptorCallback spyCallback = Mockito.spy(info -> null);
- mActivityInterceptorCallbacks.put(MAINLINE_SDK_SANDBOX_ORDER_ID, spyCallback);
-
- PackageManager packageManagerMock = mock(PackageManager.class);
- String sandboxPackageNameMock = "com.sandbox.mock";
- when(mContext.getPackageManager()).thenReturn(packageManagerMock);
- when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock);
-
- // Intent: null
- mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null);
-
- // Action: null, Package: null, ComponentName: null
- Intent intent = new Intent();
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- // Wrong Action
- intent = new Intent().setAction(Intent.ACTION_VIEW);
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- // Wrong Package
- intent = new Intent().setPackage("Random");
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- // Wrong ComponentName's package
- intent = new Intent().setComponent(new ComponentName("Random", ""));
- mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null);
-
- verify(spyCallback, never()).onInterceptActivityLaunch(
- any(ActivityInterceptorCallback.ActivityInterceptorInfo.class));
- }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 5341588c3992..72c3ebece242 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -237,26 +237,27 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
displayInfo.copyFrom(mDisplayInfo);
displayInfo.type = Display.TYPE_VIRTUAL;
DisplayContent virtualDisplay = createNewDisplay(displayInfo);
+ final KeyguardController keyguardController = mSupervisor.getKeyguardController();
// Make sure we're starting out with 2 unlocked displays
assertEquals(2, mRootWindowContainer.getChildCount());
mRootWindowContainer.forAllDisplays(displayContent -> {
assertFalse(displayContent.isKeyguardLocked());
- assertFalse(displayContent.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(displayContent.mDisplayId));
});
// Check that setLockScreenShown locks both displays
mAtm.setLockScreenShown(true, true);
mRootWindowContainer.forAllDisplays(displayContent -> {
assertTrue(displayContent.isKeyguardLocked());
- assertTrue(displayContent.isAodShowing());
+ assertTrue(keyguardController.isAodShowing(displayContent.mDisplayId));
});
// Check setLockScreenShown unlocking both displays
mAtm.setLockScreenShown(false, false);
mRootWindowContainer.forAllDisplays(displayContent -> {
assertFalse(displayContent.isKeyguardLocked());
- assertFalse(displayContent.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(displayContent.mDisplayId));
});
}
@@ -270,25 +271,26 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
displayInfo.displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
displayInfo.flags = Display.FLAG_OWN_DISPLAY_GROUP | Display.FLAG_ALWAYS_UNLOCKED;
DisplayContent newDisplay = createNewDisplay(displayInfo);
+ final KeyguardController keyguardController = mSupervisor.getKeyguardController();
// Make sure we're starting out with 2 unlocked displays
assertEquals(2, mRootWindowContainer.getChildCount());
mRootWindowContainer.forAllDisplays(displayContent -> {
assertFalse(displayContent.isKeyguardLocked());
- assertFalse(displayContent.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(displayContent.mDisplayId));
});
// setLockScreenShown should only lock the default display, not the virtual one
mAtm.setLockScreenShown(true, true);
assertTrue(mDefaultDisplay.isKeyguardLocked());
- assertTrue(mDefaultDisplay.isAodShowing());
+ assertTrue(keyguardController.isAodShowing(mDefaultDisplay.mDisplayId));
DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(
newDisplay.getDisplayId());
assertNotEquals(Display.DEFAULT_DISPLAY, virtualDisplay.getDisplayId());
assertFalse(virtualDisplay.isKeyguardLocked());
- assertFalse(virtualDisplay.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(virtualDisplay.mDisplayId));
}
/*
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
index be3f01ec7dbf..80e169d8d579 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
@@ -17,15 +17,14 @@
package com.android.server.wm;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
-import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
+
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
-import static junit.framework.Assert.assertEquals;
+
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -38,8 +37,6 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import com.android.window.flags.FakeFeatureFlagsImpl;
-
import org.junit.Before;
import org.junit.Test;
@@ -60,16 +57,12 @@ public class LetterboxConfigurationTest {
private LetterboxConfiguration mLetterboxConfiguration;
private LetterboxConfigurationPersister mLetterboxConfigurationPersister;
- private MutableFakeFeatureFlagsImpl mMutableFakeFeatureFlags;
-
-
@Before
public void setUp() throws Exception {
mContext = getInstrumentation().getTargetContext();
- mMutableFakeFeatureFlags = new MutableFakeFeatureFlagsImpl();
mLetterboxConfigurationPersister = mock(LetterboxConfigurationPersister.class);
mLetterboxConfiguration = new LetterboxConfiguration(mContext,
- mLetterboxConfigurationPersister, mMutableFakeFeatureFlags);
+ mLetterboxConfigurationPersister);
}
@Test
@@ -99,22 +92,6 @@ public class LetterboxConfigurationTest {
}
@Test
- public void test_whenFlagEnabled_wallpaperIsDefaultBackground() {
- mMutableFakeFeatureFlags.setLetterboxBackgroundWallpaperFlag(true);
- assertEquals(LETTERBOX_BACKGROUND_WALLPAPER,
- mLetterboxConfiguration.getLetterboxBackgroundType());
- assertEquals(1, mMutableFakeFeatureFlags.getInvocationCount());
- }
-
- @Test
- public void test_whenFlagDisabled_solidColorIsDefaultBackground() {
- mMutableFakeFeatureFlags.setLetterboxBackgroundWallpaperFlag(false);
- assertEquals(LETTERBOX_BACKGROUND_SOLID_COLOR,
- mLetterboxConfiguration.getLetterboxBackgroundType());
- assertEquals(1, mMutableFakeFeatureFlags.getInvocationCount());
- }
-
- @Test
public void test_whenMovedHorizontally_updatePositionAccordingly() {
// Starting from center
assertForHorizontalMove(
@@ -311,23 +288,4 @@ public class LetterboxConfigurationTest {
false /* forTabletopMode */,
LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP);
}
-
- private static class MutableFakeFeatureFlagsImpl extends FakeFeatureFlagsImpl {
- private boolean mLetterboxBackgroundWallpaperFlag;
- private int mInvocationCount;
-
- public void setLetterboxBackgroundWallpaperFlag(boolean letterboxBackgroundWallpaperFlag) {
- mLetterboxBackgroundWallpaperFlag = letterboxBackgroundWallpaperFlag;
- }
-
- @Override
- public boolean letterboxBackgroundWallpaperFlag() {
- mInvocationCount++;
- return mLetterboxBackgroundWallpaperFlag;
- }
-
- int getInvocationCount() {
- return mInvocationCount;
- }
- }
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 3d78a1dd8943..0a70a5f9b947 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -27,9 +27,9 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPH
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH;
-import android.app.AppOpsManager;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.content.ComponentName;
@@ -50,6 +50,7 @@ import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SharedMemory;
+import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.service.voice.HotwordDetectionService;
import android.service.voice.HotwordDetectionServiceFailure;
@@ -114,6 +115,9 @@ final class HotwordDetectionConnection {
private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour
private static final int MAX_ISOLATED_PROCESS_NUMBER = 10;
+ private static final boolean SYSPROP_VISUAL_QUERY_SERVICE_ENABLED =
+ SystemProperties.getBoolean("ro.hotword.visual_query_service_enabled", false);
+
/**
* Indicates the {@link HotwordDetectionService} is created.
*/
@@ -680,7 +684,8 @@ final class HotwordDetectionConnection {
mIntent = intent;
mDetectionServiceType = detectionServiceType;
int flags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0;
- if (mVisualQueryDetectionComponentName != null
+ if (SYSPROP_VISUAL_QUERY_SERVICE_ENABLED
+ && mVisualQueryDetectionComponentName != null
&& mHotwordDetectionComponentName != null) {
flags |= Context.BIND_SHARED_ISOLATED_PROCESS;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 471acc118572..6ba77da1d972 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -57,6 +57,7 @@ import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SharedMemory;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.service.voice.HotwordDetector;
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
@@ -96,6 +97,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
/** The delay time for retrying to request DirectActions. */
private static final long REQUEST_DIRECT_ACTIONS_RETRY_TIME_MS = 200;
+ private static final boolean SYSPROP_VISUAL_QUERY_SERVICE_ENABLED =
+ SystemProperties.getBoolean("ro.hotword.visual_query_service_enabled", false);
final boolean mValid;
@@ -715,7 +718,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
} else {
verifyDetectorForVisualQueryDetectionLocked(sharedMemory);
}
- if (!verifyProcessSharingLocked()) {
+ if (SYSPROP_VISUAL_QUERY_SERVICE_ENABLED && !verifyProcessSharingLocked()) {
Slog.w(TAG, "Sandboxed detection service not in shared isolated process");
throw new IllegalStateException("VisualQueryDetectionService or HotworDetectionService "
+ "not in a shared isolated process. Please make sure to set "
@@ -914,6 +917,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
if (hotwordInfo == null || visualQueryInfo == null) {
return true;
}
+ // Enforce shared isolated option is used when VisualQueryDetectionservice is enabled
return (hotwordInfo.flags & ServiceInfo.FLAG_ALLOW_SHARED_ISOLATED_PROCESS) != 0
&& (visualQueryInfo.flags & ServiceInfo.FLAG_ALLOW_SHARED_ISOLATED_PROCESS) != 0;
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index a72f7806d3ea..1f32c978fad1 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -412,6 +412,15 @@ public class TelecomManager {
"android.telecom.extra.CALL_CREATED_TIME_MILLIS";
/**
+ * Optional extra for incoming containing a long which specifies the time the
+ * call was answered by user. This value is in milliseconds.
+ * @hide
+ */
+ public static final String EXTRA_CALL_ANSWERED_TIME_MILLIS =
+ "android.telecom.extra.CALL_ANSWERED_TIME_MILLIS";
+
+
+ /**
* Optional extra for incoming and outgoing calls containing a long which specifies the Epoch
* time the call was created.
* @hide
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 5f6c14a36d46..6130af5abdfa 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -18,6 +18,7 @@ package android.telephony.satellite;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -39,6 +40,7 @@ import android.telephony.TelephonyFrameworkInitializer;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.IVoidConsumer;
+import com.android.internal.telephony.flags.Flags;
import com.android.telephony.Rlog;
import java.lang.annotation.Retention;
@@ -769,6 +771,16 @@ public final class SatelliteManager {
*/
public static final int SATELLITE_MODEM_STATE_UNAVAILABLE = 5;
/**
+ * The satellite modem is powered on but the device is not registered to a satellite cell.
+ */
+ @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ public static final int SATELLITE_MODEM_STATE_NOT_CONNECTED = 6;
+ /**
+ * The satellite modem is powered on and the device is registered to a satellite cell.
+ */
+ @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ public static final int SATELLITE_MODEM_STATE_CONNECTED = 7;
+ /**
* Satellite modem state is unknown. This generic modem state should be used only when the
* modem state cannot be mapped to other specific modem states.
*/
@@ -782,6 +794,8 @@ public final class SatelliteManager {
SATELLITE_MODEM_STATE_DATAGRAM_RETRYING,
SATELLITE_MODEM_STATE_OFF,
SATELLITE_MODEM_STATE_UNAVAILABLE,
+ SATELLITE_MODEM_STATE_NOT_CONNECTED,
+ SATELLITE_MODEM_STATE_CONNECTED,
SATELLITE_MODEM_STATE_UNKNOWN
})
@Retention(RetentionPolicy.SOURCE)
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl
index e4f94134caa1..162fe2b40104 100644
--- a/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteModemState.aidl
@@ -46,6 +46,14 @@ enum SatelliteModemState {
*/
SATELLITE_MODEM_STATE_UNAVAILABLE = 5,
/**
+ * The satellite modem is powered on but the device is not registered to a satellite cell.
+ */
+ SATELLITE_MODEM_STATE_NOT_CONNECTED = 6,
+ /**
+ * The satellite modem is powered on and the device is registered to a satellite cell.
+ */
+ SATELLITE_MODEM_STATE_CONNECTED = 7,
+ /**
* Satellite modem state is unknown. This generic modem state should be used only when the
* modem state cannot be mapped to other specific modem states.
*/
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index c09041518296..ee22d0732eac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.quickswitch
-import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.datatypes.Rect
import android.tools.common.traces.component.ComponentNameMatcher
@@ -51,6 +50,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 298544839)
class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp1 = SimpleAppHelper(instrumentation)
private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -92,7 +92,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that the transition starts with [testApp1]'s windows filling/covering exactly the
* entirety of the display.
*/
- @Presubmit
@Test
open fun startsWithApp1WindowsCoverFullScreen() {
flicker.assertWmStart {
@@ -112,7 +111,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
}
/** Checks that the transition starts with [testApp1] being the top window. */
- @Presubmit
@Test
open fun startsWithApp1WindowBeingOnTop() {
flicker.assertWmStart { this.isAppWindowOnTop(testApp1) }
@@ -122,7 +120,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp2] windows fill the entire screen (i.e. is "fullscreen") at the end of
* the transition once we have fully quick switched from [testApp1] back to the [testApp2].
*/
- @Presubmit
@Test
open fun endsWithApp2WindowsCoveringFullScreen() {
flicker.assertWmEnd { this.visibleRegion(testApp2).coversExactly(startDisplayBounds) }
@@ -132,7 +129,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp2] layers fill the entire screen (i.e. is "fullscreen") at the end of the
* transition once we have fully quick switched from [testApp1] back to the [testApp2].
*/
- @Presubmit
@Test
open fun endsWithApp2LayersCoveringFullScreen() {
flicker.assertLayersEnd {
@@ -145,7 +141,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp2] is the top window at the end of the transition once we have fully
* quick switched from [testApp1] back to the [testApp2].
*/
- @Presubmit
@Test
open fun endsWithApp2BeingOnTop() {
flicker.assertWmEnd { this.isAppWindowOnTop(testApp2) }
@@ -155,7 +150,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp2]'s window starts off invisible and becomes visible at some point before
* the end of the transition and then stays visible until the end of the transition.
*/
- @Presubmit
@Test
open fun app2WindowBecomesAndStaysVisible() {
flicker.assertWm {
@@ -171,7 +165,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp2]'s layer starts off invisible and becomes visible at some point before
* the end of the transition and then stays visible until the end of the transition.
*/
- @Presubmit
@Test
open fun app2LayerBecomesAndStaysVisible() {
flicker.assertLayers { this.isInvisible(testApp2).then().isVisible(testApp2) }
@@ -181,7 +174,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp1]'s window starts off visible and becomes invisible at some point before
* the end of the transition and then stays invisible until the end of the transition.
*/
- @Presubmit
@Test
open fun app1WindowBecomesAndStaysInvisible() {
flicker.assertWm { this.isAppWindowVisible(testApp1).then().isAppWindowInvisible(testApp1) }
@@ -191,7 +183,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Checks that [testApp1]'s layer starts off visible and becomes invisible at some point before
* the end of the transition and then stays invisible until the end of the transition.
*/
- @Presubmit
@Test
open fun app1LayerBecomesAndStaysInvisible() {
flicker.assertLayers { this.isVisible(testApp1).then().isInvisible(testApp1) }
@@ -202,7 +193,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Ensures that at any point, either [testApp2] or [testApp1]'s windows are at least partially
* visible.
*/
- @Presubmit
@Test
open fun app2WindowIsVisibleOnceApp1WindowIsInvisible() {
flicker.assertWm {
@@ -221,7 +211,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
* Ensures that at any point, either [testApp2] or [testApp1]'s windows are at least partially
* visible.
*/
- @Presubmit
@Test
open fun app2LayerIsVisibleOnceApp1LayerIsInvisible() {
flicker.assertLayers {
@@ -236,7 +225,6 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
}
/** {@inheritDoc} */
- @Presubmit
@Test
override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
@@ -245,14 +233,34 @@ class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTes
@Test
override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
- @FlakyTest(bugId = 246284708)
@Test
override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
super.visibleLayersShownMoreThanOneConsecutiveEntry()
- @FlakyTest(bugId = 250518877)
+ @Test override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ @Test override fun entireScreenCovered() = super.entireScreenCovered()
+
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ @Test
+ override fun navBarWindowIsVisibleAtStartAndEnd() = super.navBarWindowIsVisibleAtStartAndEnd()
+
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() = super.statusBarLayerPositionAtStartAndEnd()
+
+ @Test override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ @Test override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
@Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
private var startDisplayBounds = Rect.EMPTY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt
index 4941eea12129..3cae1c43285b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/service/quickswitch/scenarios/QuickSwitchBetweenTwoAppsForward.kt
@@ -30,6 +30,7 @@ import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
+import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
@Ignore("Base Test Class")
abstract class QuickSwitchBetweenTwoAppsForward(val rotation: Rotation = Rotation.ROTATION_0) {
@@ -46,7 +47,9 @@ abstract class QuickSwitchBetweenTwoAppsForward(val rotation: Rotation = Rotatio
tapl.setExpectedRotation(rotation.value)
testApp1.launchViaIntent(wmHelper)
+ ChangeDisplayOrientationRule.setRotation(rotation)
testApp2.launchViaIntent(wmHelper)
+ ChangeDisplayOrientationRule.setRotation(rotation)
tapl.launchedAppState.quickSwitchToPreviousApp()
wmHelper
.StateSyncBuilder()
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 0aaf3e8fd6c7..82bcfc2c1a8b 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -99,7 +99,7 @@ static bool isHidden(const char *root, const char *path)
String8 fullPath(root);
appendPath(fullPath, String8(path));
- FileType type = getFileType(fullPath);
+ FileType type = getFileType(fullPath.c_str());
int plen = strlen(path);
@@ -287,19 +287,19 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta
Vector<String8> subtags = AaptUtil::splitAndLowerCase(part, '+');
subtags.removeItemsAt(0);
if (subtags.size() == 1) {
- setLanguage(subtags[0]);
+ setLanguage(subtags[0].c_str());
} else if (subtags.size() == 2) {
- setLanguage(subtags[0]);
+ setLanguage(subtags[0].c_str());
// The second tag can either be a region, a variant or a script.
switch (subtags[1].size()) {
case 2:
case 3:
- setRegion(subtags[1]);
+ setRegion(subtags[1].c_str());
break;
case 4:
if (isAlpha(subtags[1])) {
- setScript(subtags[1]);
+ setScript(subtags[1].c_str());
break;
}
// This is not alphabetical, so we fall through to variant
@@ -308,7 +308,7 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta
case 6:
case 7:
case 8:
- setVariant(subtags[1]);
+ setVariant(subtags[1].c_str());
break;
default:
fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n",
@@ -317,14 +317,14 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta
}
} else if (subtags.size() == 3) {
// The language is always the first subtag.
- setLanguage(subtags[0]);
+ setLanguage(subtags[0].c_str());
// The second subtag can either be a script or a region code.
// If its size is 4, it's a script code, else it's a region code.
if (subtags[1].size() == 4) {
- setScript(subtags[1]);
+ setScript(subtags[1].c_str());
} else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
- setRegion(subtags[1]);
+ setRegion(subtags[1].c_str());
} else {
fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.c_str());
return -1;
@@ -333,15 +333,15 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta
// The third tag can either be a region code (if the second tag was
// a script), else a variant code.
if (subtags[2].size() >= 4) {
- setVariant(subtags[2]);
+ setVariant(subtags[2].c_str());
} else {
- setRegion(subtags[2]);
+ setRegion(subtags[2].c_str());
}
} else if (subtags.size() == 4) {
- setLanguage(subtags[0]);
- setScript(subtags[1]);
- setRegion(subtags[2]);
- setVariant(subtags[3]);
+ setLanguage(subtags[0].c_str());
+ setScript(subtags[1].c_str());
+ setRegion(subtags[2].c_str());
+ setVariant(subtags[3].c_str());
} else {
fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.c_str());
return -1;
@@ -351,7 +351,7 @@ int AaptLocaleValue::initFromDirName(const Vector<String8>& parts, const int sta
} else {
if ((part.length() == 2 || part.length() == 3)
&& isAlpha(part) && strcmp("car", part.c_str())) {
- setLanguage(part);
+ setLanguage(part.c_str());
if (++currentIndex == size) {
return size;
}
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 800466aa587f..43a8b52f2766 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -401,7 +401,7 @@ static void printUsesImpliedPermission(const String8& name, const String8& reaso
Vector<String8> getNfcAidCategories(AssetManager& assets, const String8& xmlPath, bool offHost,
String8 *outError = NULL)
{
- Asset* aidAsset = assets.openNonAsset(xmlPath, Asset::ACCESS_BUFFER);
+ Asset* aidAsset = assets.openNonAsset(xmlPath.c_str(), Asset::ACCESS_BUFFER);
if (aidAsset == NULL) {
if (outError != NULL) *outError = "xml resource does not exist";
return Vector<String8>();
@@ -2760,7 +2760,7 @@ int doPackage(Bundle* bundle)
appendPath(dependencyFile, "R.java.d");
}
// Make sure we have a clean dependency file to start with
- fp = fopen(dependencyFile, "w");
+ fp = fopen(dependencyFile.c_str(), "w");
fclose(fp);
}
@@ -2849,7 +2849,7 @@ int doPackage(Bundle* bundle)
if (bundle->getGenDependencies()) {
// Now that writeResourceSymbols or writeAPK has taken care of writing
// the targets to our dependency file, we'll write the prereqs
- fp = fopen(dependencyFile, "a+");
+ fp = fopen(dependencyFile.c_str(), "a+");
fprintf(fp, " : ");
bool includeRaw = (outputAPKFile != NULL);
err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 3a198fd43d48..7e4e186ec320 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -924,7 +924,7 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root)
if (bundle->getCompileSdkVersion() != 0) {
if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "compileSdkVersion",
- String8::format("%d", bundle->getCompileSdkVersion()),
+ String8::format("%d", bundle->getCompileSdkVersion()).c_str(),
errorOnFailedInsert, true)) {
return UNKNOWN_ERROR;
}
@@ -932,21 +932,21 @@ status_t massageManifest(Bundle* bundle, ResourceTable* table, sp<XMLNode> root)
if (bundle->getCompileSdkVersionCodename() != "") {
if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "compileSdkVersionCodename",
- bundle->getCompileSdkVersionCodename(), errorOnFailedInsert, true)) {
+ bundle->getCompileSdkVersionCodename().c_str(), errorOnFailedInsert, true)) {
return UNKNOWN_ERROR;
}
}
if (bundle->getPlatformBuildVersionCode() != "") {
if (!addTagAttribute(root, "", "platformBuildVersionCode",
- bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {
+ bundle->getPlatformBuildVersionCode().c_str(), errorOnFailedInsert, true)) {
return UNKNOWN_ERROR;
}
}
if (bundle->getPlatformBuildVersionName() != "") {
if (!addTagAttribute(root, "", "platformBuildVersionName",
- bundle->getPlatformBuildVersionName(), errorOnFailedInsert, true)) {
+ bundle->getPlatformBuildVersionName().c_str(), errorOnFailedInsert, true)) {
return UNKNOWN_ERROR;
}
}
@@ -1210,7 +1210,7 @@ status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& a
sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16("manifest"));
// Add the 'package' attribute which is set to the package name.
- const char* packageName = assets->getPackage();
+ const char* packageName = assets->getPackage().c_str();
const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
if (manifestPackageNameOverride != NULL) {
packageName = manifestPackageNameOverride;
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 8d0268393433..1af8d6f67bd3 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -472,13 +472,13 @@ status_t StringPool::writeStringBlock(const sp<AaptFile>& pool)
ENCODE_LENGTH(strings, sizeof(uint8_t), encSize)
- strncpy((char*)strings, encStr, encSize+1);
+ strncpy((char*)strings, encStr.c_str(), encSize + 1);
} else {
char16_t* strings = (char16_t*)dat;
ENCODE_LENGTH(strings, sizeof(char16_t), strSize)
- strcpy16_htod(strings, ent.value);
+ strcpy16_htod(strings, ent.value.c_str());
}
strPos += totalSize;
@@ -592,7 +592,7 @@ ssize_t StringPool::offsetForString(const String16& val) const
ssize_t res = indices != NULL && indices->size() > 0 ? indices->itemAt(0) : -1;
if (kIsDebug) {
printf("Offset for string %s: %zd (%s)\n", String8(val).c_str(), res,
- res >= 0 ? String8(mEntries[mEntryArray[res]].value).c_str() : String8());
+ res >= 0 ? String8(mEntries[mEntryArray[res]].value).c_str() : "");
}
return res;
}
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index a887ac947835..1a648c01f631 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -559,7 +559,7 @@ status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,
root->removeWhitespace(stripAll, cDataTags);
if (kIsDebug) {
- printf("Input XML from %s:\n", (const char*)file->getPrintableSource());
+ printf("Input XML from %s:\n", file->getPrintableSource().c_str());
root->print();
}
sp<AaptFile> rsc = new AaptFile(String8(), AaptGroupEntry(), String8());
diff --git a/tools/aapt/tests/AaptGroupEntry_test.cpp b/tools/aapt/tests/AaptGroupEntry_test.cpp
index bf5ca59a81c8..8621e9be7010 100644
--- a/tools/aapt/tests/AaptGroupEntry_test.cpp
+++ b/tools/aapt/tests/AaptGroupEntry_test.cpp
@@ -24,7 +24,7 @@ using android::String8;
static ::testing::AssertionResult TestParse(AaptGroupEntry& entry, const String8& dirName,
String8* outType) {
- if (entry.initFromDirName(dirName, outType)) {
+ if (entry.initFromDirName(dirName.c_str(), outType)) {
return ::testing::AssertionSuccess() << dirName << " was successfully parsed";
}
return ::testing::AssertionFailure() << dirName << " could not be parsed";
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index a0679a65b9fd..087f456ec084 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -50,8 +50,8 @@ class PrettyPrinter : public DominatorTree::Visitor {
private:
void VisitConfig(const DominatorTree::Node* node, const int indent) {
auto config_string = node->value()->config.toString();
- buffer_ << std::string(indent, ' ') << (config_string.empty() ? "<default>" : config_string)
- << std::endl;
+ buffer_ << std::string(indent, ' ')
+ << (config_string.empty() ? "<default>" : config_string.c_str()) << std::endl;
}
void VisitNode(const DominatorTree::Node* node, const int indent) {
diff --git a/tools/aapt2/OWNERS b/tools/aapt2/OWNERS
index 4f655e54a7c2..55bab7d8d74f 100644
--- a/tools/aapt2/OWNERS
+++ b/tools/aapt2/OWNERS
@@ -1,4 +1,4 @@
set noparent
-toddke@google.com
zyy@google.com
-patb@google.com \ No newline at end of file
+patb@google.com
+markpun@google.com
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 0fa13b81c4ea..70d875e394ff 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -165,7 +165,7 @@ static bool validateFile(const char* filename) {
case FileType::INPUT_DEVICE_CONFIGURATION: {
android::base::Result<std::unique_ptr<PropertyMap>> propertyMap =
- PropertyMap::load(String8(filename));
+ PropertyMap::load(String8(filename).c_str());
if (!propertyMap.ok()) {
error("Error parsing input device configuration file: %s.\n\n",
propertyMap.error().message().c_str());
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_landscape_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_landscape_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..6bd8595bc097
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_landscape_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_portrait_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_portrait_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..d5d6fb6c6ea4
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/dark_portrait_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_landscape_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_landscape_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..fe8dc6906108
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_landscape_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_portrait_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_portrait_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..ccd8a33ab4fd
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/phone/light_portrait_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_landscape_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_landscape_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..de84c4aa9dae
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_landscape_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_portrait_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_portrait_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..af9d7cf74ace
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/dark_portrait_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_landscape_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_landscape_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..33daab9c401d
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_landscape_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_portrait_credential_view_pin_or_password_emergency_call_button.png b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_portrait_credential_view_pin_or_password_emergency_call_button.png
new file mode 100644
index 000000000000..14a799c41757
--- /dev/null
+++ b/vendor/unbundled_google/packages/SystemUIGoogle/tests/screenshotBiometrics/assets/tablet/light_portrait_credential_view_pin_or_password_emergency_call_button.png
Binary files differ
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
index d41c0197addc..bc41829f16d2 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
@@ -23,9 +23,11 @@ import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.net.wifi.sharedconnectivity.service.ISharedConnectivityCallback;
@@ -35,6 +37,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
+import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
@@ -67,7 +70,7 @@ import java.util.concurrent.Executor;
@SystemApi
public class SharedConnectivityManager {
private static final String TAG = SharedConnectivityManager.class.getSimpleName();
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final class SharedConnectivityCallbackProxy extends
ISharedConnectivityCallback.Stub {
@@ -172,6 +175,7 @@ public class SharedConnectivityManager {
private final String mServicePackageName;
private final String mIntentAction;
private ServiceConnection mServiceConnection;
+ private UserManager mUserManager;
/**
* Creates a new instance of {@link SharedConnectivityManager}.
@@ -217,12 +221,14 @@ public class SharedConnectivityManager {
mContext = context;
mServicePackageName = servicePackageName;
mIntentAction = serviceIntentAction;
+ mUserManager = context.getSystemService(UserManager.class);
}
private void bind() {
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
+ if (DEBUG) Log.i(TAG, "onServiceConnected");
mService = ISharedConnectivityService.Stub.asInterface(service);
synchronized (mProxyDataLock) {
if (!mCallbackProxyCache.isEmpty()) {
@@ -253,9 +259,45 @@ public class SharedConnectivityManager {
}
};
- mContext.bindService(
+ boolean result = mContext.bindService(
new Intent().setPackage(mServicePackageName).setAction(mIntentAction),
mServiceConnection, Context.BIND_AUTO_CREATE);
+ if (!result) {
+ if (DEBUG) Log.i(TAG, "bindService failed");
+ mServiceConnection = null;
+ if (mUserManager != null && !mUserManager.isUserUnlocked()) { // In direct boot mode
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+ } else {
+ synchronized (mProxyDataLock) {
+ if (!mCallbackProxyCache.isEmpty()) {
+ mCallbackProxyCache.keySet().forEach(
+ callback -> callback.onRegisterCallbackFailed(
+ new IllegalStateException(
+ "Failed to bind after user unlock")));
+ mCallbackProxyCache.clear();
+ }
+ }
+ }
+ }
+ }
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ context.unregisterReceiver(mBroadcastReceiver);
+ bind();
+ }
+ };
+
+ /**
+ * @hide
+ */
+ @TestApi
+ @NonNull
+ public BroadcastReceiver getBroadcastReceiver() {
+ return mBroadcastReceiver;
}
private void registerCallbackInternal(SharedConnectivityClientCallback callback,
@@ -357,6 +399,13 @@ public class SharedConnectivityManager {
return false;
}
+ // Try to unregister the broadcast receiver to guard against memory leaks.
+ try {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ } catch (IllegalArgumentException e) {
+ // This is fine, it means the receiver was never registered or was already unregistered.
+ }
+
if (mService == null) {
boolean shouldUnbind;
synchronized (mProxyDataLock) {